How to delay a display Python Processing

Hi all, I am currently wring a code to solve a Rubik’s cube and I am at the stage of animating the turns. I have managed to do it, however it happens to quickly to see. I have tried to put a delay in but where ever I put it it seems to just put the delay and then do the animation so it still happens as quickly. The only luck I’ve had is putting the delay in the draw class but this just makes the program laggy. Any help is appreciated
Here is the code:

add_library('peasycam')
from peasy import PeasyCam

import math

def setup():
    size(800, 800, P3D)
    cam = PeasyCam(this, 100)
    cam.setMinimumDistance(50)
    cam.setMaximumDistance(500)
    background(23,117,46)
    textSize(10)
    frameRate(120)
    strokeWeight(5)
    global finished
    finished = False
    

#faces class

class Face:
    def __init__(self, index):
        self.index = index
        
    def getcolour(self):
        if self.index == 0:
            self.colour = 'white'
            self.pos_curr = [0,1,0]
            self.pos_set = [0,1,0]
            
        elif self.index == 1:
            self.colour = 'blue'
            self.pos_curr = [0,0,1]
            self.pos_set = [0,0,1]
            
        elif self.index == 2:
            self.colour = 'orange'
            self.pos_curr = [1,0,0]
            self.pos_set = [1,0,0]
            
        elif self.index == 3:
            self.colour = 'green'
            self.pos_curr = [0,0,-1]
            self.pos_set = [0,0,-1]
            
        elif self.index == 4:
            self.colour = 'red'
            self.pos_curr = [-1,0,0]
            self.pos_set = [-1,0,0]
            
        elif self.index == 5:
            self.colour = 'yellow'
            self.pos_curr = [0,-1,0]
            self.pos_set = [0,-1,0]
            
    def check(self):
        if self.pos_curr == self.pos_set:
            return True
        else:
            return False
        
        

#cube class

class Cube:
    def __init__(self, x, y, z):
        self.faces = []
        #current positions of each cube -2<x<2 
        self.x_curr = x
        self.y_curr = y
        self.z_curr = z
        
        #the solved positition of the cube
        self._xset = x
        self._yset = y
        self._zset = z
    
    def getfaces(self):
        for i in range (0,6):
            newFace = Face(i)
            newFace.getcolour()
            self.faces.append(newFace)
    
    def show(self):
        len_= 10
        r=6
        stroke(0)
        pushMatrix()
        
        translate(self.x_curr*2*r,self.y_curr*2*r,self.z_curr*2*r)
        beginShape(QUADS)
        
        #front face
        for each in self.faces:
            if each.pos_curr == [0,0,1]:
                if each.colour == 'white':
                    fill(251,255,255)
                elif each.colour == 'blue':
                    fill(77,77,255)
                elif each.colour == 'green':
                    fill(57,255,20)
                elif each.colour == 'orange':
                    fill(255,95,31)
                elif each.colour == 'yellow':
                    fill(255,237,39)
                elif each.colour == 'red':
                    fill(255,49,49)
        vertex(r, r, r)
        vertex(r, -r, r)
        vertex(-r, -r, r)
        vertex(-r, r, r)

        #bottom face
        for each in self.faces:
            if each.pos_curr == [0,-1,0]:
                if each.colour == 'white':
                    fill(251,255,255)
                elif each.colour == 'blue':
                    fill(77,77,255)
                elif each.colour == 'green':
                    fill(57,255,20)
                elif each.colour == 'orange':
                    fill(255,95,31)
                elif each.colour == 'yellow':
                    fill(255,237,39)
                elif each.colour == 'red':
                    fill(255,49,49)
        vertex(r, r, r)
        vertex(r, r, -r)
        vertex(-r, r, -r)
        vertex(-r, r, r)
        
        #right face
        for each in self.faces:
            if each.pos_curr == [1,0,0]:
                if each.colour == 'white':
                    fill(251,255,255)
                elif each.colour == 'blue':
                    fill(77,77,255)
                elif each.colour == 'green':
                    fill(57,255,20)
                elif each.colour == 'orange':
                    fill(255,95,31)
                elif each.colour == 'yellow':
                    fill(255,237,39)
                elif each.colour == 'red':
                    fill(255,49,49)
        vertex(r, r, r)
        vertex(r, r, -r)
        vertex(r, -r, -r)
        vertex(r, -r, r)
        

        #back face
        for each in self.faces:
            if each.pos_curr == [0,0,-1]:
                if each.colour == 'white':
                    fill(251,255,255)
                elif each.colour == 'blue':
                    fill(77,77,255)
                elif each.colour == 'green':
                    fill(57,255,20)
                elif each.colour == 'orange':
                    fill(255,95,31)
                elif each.colour == 'yellow':
                    fill(255,237,39)
                elif each.colour == 'red':
                    fill(255,49,49)
        vertex(r, r, -r)
        vertex(r, -r, -r)
        vertex(-r, -r, -r)
        vertex(-r, r, -r)

        #up face
        for each in self.faces:
            if each.pos_curr == [0,1,0]:
                if each.colour == 'white':
                    fill(251,255,255)
                elif each.colour == 'blue':
                    fill(77,77,255)
                elif each.colour == 'green':
                    fill(57,255,20)
                elif each.colour == 'orange':
                    fill(255,95,31)
                elif each.colour == 'yellow':
                    fill(255,237,39)
                elif each.colour == 'red':
                    fill(255,49,49)
        vertex(r, -r, r)
        vertex(r, -r, -r)
        vertex(-r, -r, -r)
        vertex(-r, -r, r)

        #left face
        for each in self.faces:
            if each.pos_curr == [-1,0,0]:
                if each.colour == 'white':
                    fill(251,255,255)
                elif each.colour == 'blue':
                    fill(77,77,255)
                elif each.colour == 'green':
                    fill(57,255,20)
                elif each.colour == 'orange':
                    fill(255,95,31)
                elif each.colour == 'yellow':
                    fill(255,237,39)
                elif each.colour == 'red':
                    fill(255,49,49)
        vertex(-r, r, r)
        vertex(-r, r, -r)
        vertex(-r, -r, -r)
        vertex(-r, -r, r)

        endShape()
        popMatrix()
        
#Moves class

class Moves:
    def __init__(self):
        self.yes=True

    def create(self):
        a=[]
        b=[]
        self.cubeList = []
        for x in range(-1,2):
            for y in range(-1,2):
                for z in range(-1,2):
                    newCube = Cube(x, y, z)
                    newCube.getfaces()
                    a.append(newCube)
                b.append(a)
                a=[]
            self.cubeList.append(b)
            b=[]
        
        
        
    def applyMatrix(self, rotation, matrix3D, face, matrix3D_2):
        angle=0
        while angle < HALF_PI:
            angle += 0.01
            for a in self.cubeList:
                for b in a:
                    for i in b:
                        if face == 'z':
                            check = i.z_curr
                        elif face == 'y':
                            check = i.y_curr
                        elif face == 'x':
                            check = i.x_curr
                        if check == rotation:
                            #altering position of each cube
                            
                            newx = matrix3D_2[0][0]*i.x_curr + matrix3D_2[0][1]*i.y_curr + matrix3D_2[0][2]*i.z_curr
                            newy = matrix3D_2[1][0]*i.x_curr + matrix3D_2[1][1]*i.y_curr + matrix3D_2[1][2]*i.z_curr
                            newz = matrix3D_2[2][0]*i.x_curr + matrix3D_2[2][1]*i.y_curr + matrix3D_2[2][2]*i.z_curr
                            i.x_curr = newx
                            i.y_curr = newy
                            i.z_curr = newz
                            strokeWeight(0)
            push()
            for n in self.cubeList:
                for each in n:
                    for q in each:
                        q.show()
            pop()
        strokeWeight(5)
        
        
        for a in self.cubeList:
            for b in a:
                for i in b:
                    i.x_curr = round(i.x_curr)
                    i.y_curr = round(i.y_curr)
                    i.z_curr = round(i.z_curr)
        
                    
        for a in self.cubeList:
            for b in a:
                for i in b:
                    if face == 'z':
                        check = i.z_curr
                    elif face == 'y':
                        check = i.y_curr
                    elif face == 'x':
                        check = i.x_curr
                    if check == rotation:
                        #altering the rotation of each cube
                        for each in i.faces:
                            if face == 'z':
                                a = -matrix3D[0][0]*each.pos_curr[0] + -matrix3D[0][1]*each.pos_curr[1] + -matrix3D[0][2]*each.pos_curr[2]
                                b = -matrix3D[1][0]*each.pos_curr[0] + -matrix3D[1][1]*each.pos_curr[1] + -matrix3D[1][2]*each.pos_curr[2]
                                c = matrix3D[2][0]*each.pos_curr[0] + matrix3D[2][1]*each.pos_curr[1] + matrix3D[2][2]*each.pos_curr[2]
                            elif face == 'x':
                                a = matrix3D[0][0]*each.pos_curr[0] + matrix3D[0][1]*each.pos_curr[1] + matrix3D[0][2]*each.pos_curr[2]
                                b = -matrix3D[1][0]*each.pos_curr[0] + -matrix3D[1][1]*each.pos_curr[1] + -matrix3D[1][2]*each.pos_curr[2]
                                c = -matrix3D[2][0]*each.pos_curr[0] + -matrix3D[2][1]*each.pos_curr[1] + -matrix3D[2][2]*each.pos_curr[2]
                            elif face == 'y':
                                a = -matrix3D[0][0]*each.pos_curr[0] + -matrix3D[0][1]*each.pos_curr[1] + -matrix3D[0][2]*each.pos_curr[2]
                                b = matrix3D[1][0]*each.pos_curr[0] + matrix3D[1][1]*each.pos_curr[1] + matrix3D[1][2]*each.pos_curr[2]
                                c = -matrix3D[2][0]*each.pos_curr[0] + -matrix3D[2][1]*each.pos_curr[1] + -matrix3D[2][2]*each.pos_curr[2]
                                a=-a
                                b=b
                                c=-c
                            newVector = [a,b,c]
                            each.pos_curr = newVector
                            

    def turnZ(self, move):
        #for z rotations
        #user = input('f, m, b, F, M or B')
        user= move
        if user == 'f':
            rotation = 1
            dir = -1
        elif user == 'F':
            rotation = 1
            dir = 1
        
        elif user == 's':
            rotation = 0
            dir = -1
        elif user == 'S':
            rotation =0
            dir = 1

        elif user == 'b':
            rotation = -1
            dir = -1
        elif user == 'B':
            rotation =-1
            dir = 1
        matrix3D = [[round(cos(dir*HALF_PI)),-round(sin(dir*HALF_PI)),0],[round(sin(dir*HALF_PI)),round(cos(dir*HALF_PI)),0],[0,0,1]]  
        matrix3D_2 = [[cos(dir*0.01),-sin(dir*0.01),0],[sin(dir*0.01),cos(dir*0.01),0],[0,0,1]]      
        self.applyMatrix(rotation, matrix3D, 'z', matrix3D_2)

    def turnX(self, move):
        #for x rotations
        user = move

        if user == 'r':
            rotation = 1
            dir = -1
        elif user == 'R':
            rotation = 1
            dir = 1
        
        elif user == 'm':
            rotation = 0
            dir = -1
        elif user == 'M':
            rotation =0
            dir = 1

        elif user == 'l':
            rotation = -1
            dir = -1
        elif user == 'L':
            rotation =-1
            dir = 1

        matrix3D = [[1,0,0],[0,round(cos(dir*HALF_PI)),-round(sin(dir*HALF_PI))],[0,round(sin(dir*HALF_PI)),round(cos(dir*HALF_PI))]]
        matrix3D_2 = [[1,0,0],[0,cos(dir*0.01),-sin(dir*0.01)],[0,sin(dir*0.01),cos(dir*0.01)]]    
        self.applyMatrix(rotation, matrix3D, 'x', matrix3D_2)
        
    def turnY(self, move):
        #for y rotations
        user = move

        if user == 'u':
            rotation = 1
            dir = -1
        elif user == 'U':
            rotation = 1
            dir = 1
        
        elif user == 'e':
            rotation = 0
            dir = -1
        elif user == 'E':
            rotation =0
            dir = 1

        elif user == 'd':
            rotation = -1
            dir = -1
        elif user == 'D':
            rotation =-1
            dir = 1

        matrix3D = [[round(cos(dir*HALF_PI)), 0, round(sin(dir*HALF_PI))], [0, 1, 0], [-round(sin(dir*HALF_PI)), 0, round(cos(dir*HALF_PI))]]
        matrix3D_2 = [[cos(dir*0.01), 0, sin(dir*0.01)], [0, 1, 0], [-sin(dir*0.01), 0, cos(dir*0.01)]]    
        self.applyMatrix(rotation, matrix3D, 'y', matrix3D_2)

    def axis(self, move):
        #a = input('Would you like to rotate along x, y or z axis? ')
        if  move == 'l' or move == 'm' or move == 'r' or move == 'L' or move == 'M' or move == 'R':
            self.turnX(move)
        elif move == 'u' or move == 'e' or move == 'd' or move == 'U' or move == 'E' or move == 'D':
            self.turnY(move)
        else:
            self.turnZ(move)

#Moves meaning

#Z axis
#f front face
#s middle face
#b back face

#Y axis
#u top face
#e middle face
#d bottom face

#X axis
#l left face
#m middle face
#r right face

a=Moves()
a.create()

move = 'U'


def draw():
    background(79,117,110)
    textSize(8)
    if keyPressed:
        if key == ' ':
            fill(0)
            text("Moves:", -50, -30,0)
            textSize(5)
            text("f- blue", -50, -20,0)
            text("b- green", -50, -13,0)
            text("u- white", -50, -6,0)
            text("d- yellow", -50, 1,0)
            text("l- red", -50, 8,0)
            text("r- orange", -50, 13,0)
    counter=0
    delay(50)
    for i in a.cubeList:
        for each in i:
            for z in each:
                z.show()
                counter+=1
    
    if keyPressed:
        finished = True
        if key == 'f':
            a.axis('F')
            delay(800)
        elif key == 'r':
            a.axis('r')
            delay(800)
        #elif key == 's':
        #    a.axis('S')
        #    delay(800)
        elif key == 'b':
            a.axis('B')
            delay(800)
        elif key == 'u':
            a.axis('D')
            delay(800)
        #elif key == 'e':
        #    a.axis('E')
        #    delay(800)
        elif key == 'd':
            a.axis('U')
            delay(800)
        elif key == 'l':
            a.axis('l')
            delay(800)
        #elif key == 'm':
        #    a.axis('m')
        #    delay(800)
            
        elif key == 'F':
            a.axis('f')
            delay(800)
        elif key == 'R':
            a.axis('R')
            delay(800)
        #elif key == 'S':
        #    a.axis('s')
        #   delay(800)
        elif key == 'B':
            a.axis('b')
            delay(800)
        elif key == 'U':
            a.axis('d')
            delay(800)
        #elif key == 'E':
        #    a.axis('e')
        #    delay(800)
        elif key == 'D':
            a.axis('u')
            delay(800)
        elif key == 'L':
            a.axis('L')
            delay(800)
        #elif key == 'M':
        #    a.axis('M')
        #    delay(800)

The animation occurs in the applyMatrix function in the moves class
Thanks, Daniel

I didn’t read through all your code. Maybe you could accomplish this with a ‘tween’ library? For Processing, there’s Ani. I don’t think it supports 3D, but it might adapt okay –

add_library('Ani')
import jycessing.primitives.PrimitiveFloat as Float
y_rot = Float(0.0)

def setup():
    size(500, 500, P3D)
    Ani.init(this)

def draw():
    background(200)
    translate(width/2, height/2, 0)
    rotateY(y_rot.value)
    box(100)

def mouseReleased():
    # rotate box to 0° when pointer clicked at left edge,
    # and to 360° (τ rad) for pointer click at right edge
    rad = map(mouseX, 0, width, 0, TAU)
    Ani.to(y_rot, 1, 'value', rad)
    print(degrees(rad))

In the Ani.to(y_rot, 1, 'value', rad) line –

  • the y_rot is your current rotation value
  • rad is the new/target y_rot value
  • 1 is the number of seconds to animate between y_rot and rad

Because of some Python-to-Java wierdness, you have to use jycessing.primitives.PrimitiveFloat for your Ani variables – hence the Float() to define y_rot, and accessing it with y_rot.value.

1 Like