Hi just wondering if the draw function is called when a while loop is running. I would like the draw function to be called after every iteration of the while loop and I would like to put a delay in every iteration. However it does not seem to draw until the while loop is complete. I have tried adding delays and reDraw() but it still doesn’t work. Does anyone know how I could get this to work?
Thanks Daniel
Please post your code so that we can offer specific suggestions.
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(60)
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(100)
for i in a.cubeList:
for each in i:
for z in each:
z.show()
counter+=1
while keyPressed:
finished = True
if key == 'f':
a.axis('F')
delay(500)
elif key == 'r':
a.axis('r')
delay(500)
#elif key == 's':
# a.axis('S')
# delay(500)
elif key == 'b':
a.axis('B')
delay(500)
elif key == 'u':
a.axis('D')
delay(500)
#elif key == 'e':
# a.axis('E')
# delay(500)
elif key == 'd':
a.axis('U')
delay(500)
elif key == 'l':
a.axis('l')
delay(500)
#elif key == 'm':
# a.axis('m')
# delay(800)
elif key == 'F':
a.axis('f')
delay(500)
elif key == 'R':
a.axis('R')
delay(500)
#elif key == 'S':
# a.axis('s')
# delay(500)
elif key == 'B':
a.axis('b')
delay(500)
elif key == 'U':
a.axis('d')
delay(500)
#elif key == 'E':
# a.axis('e')
# delay(800)
elif key == 'D':
a.axis('u')
delay(500)
elif key == 'L':
a.axis('L')
delay(500)
#elif key == 'M':
# a.axis('M')
# delay(800)
break
The while loop concerned is in applyMatrix() in moves
One possible strategy would be to refactor your code so that the variables or other specifications that are currently updated in your loop are instead updated with each call of the draw()
function. Below is a simple example of refactoring.
Suppose we would like to draw some rectangles in cycles of 10. We draw 1 rectangle, then erase it and draw 2, then erase them and draw 3, et cetera. We could try this, but it does not work as intended:
def setup():
size(400, 400)
rectMode(CENTER)
frameRate(1)
def draw():
background(127)
for i in range(10):
background(127)
for j in range(i):
rect(random(100, 300), random(100, 300), 100, 100)
Refactoring the code as described above, we do this with the draw()
function instead, which works as intended:
def draw():
background(127)
for i in range(frameCount % 10 + 1):
rect(random(100, 300), random(100, 300), 100, 100)
Please post Python topics in the Processing.py category. See if you can move this thread there now (click the pencil icon on the title to reassign it).
Hi I think I’m being slightly stupid but I’m confused at how I would implement this into my code and what you mean by this.
Essentially, you need to identify what specifications need to change each time the sketch is drawn. Instead of representing those specifications within a while
loop, use global
variables to hold that information, so that it persists between the automatic calls of the draw()
function. Then, within the draw()
function, update those global
variables to prepare for the next call of the draw()
function. In a sense, the automatic calls to the draw()
function will become a replacement for the iterations of your while
loop.
The frameCount
variable that already exists is global
, and might be useful to you, but it appears that your sketch is complex enough to require additional global
variables. For example, you have this:
angle=0
while angle < HALF_PI:
angle += 0.01
Quite likely, one of your global
variables will be angle
. Make sure it is declared global
wherever it is used within a function. Assign it an initial value in the setup()
function, then make sure it gets updated each time draw()
gets called. The updating does not necessarily need to be performed within the draw()
function itself. Instead, it could be updated within a function that is called directly or indirectly by the draw()
function.
EDITED on June 11, 2022 to correct a typographical error.
Works amazingly tysm
No need for additional fixed increasing global variables if they’re updated once per draw() iteration.
For example, if you need some global variable which is updated by .01
steps, just multiply that value by frameCount locally: someLocalVariable = .01 * frameCount