# Draw function, Processing, Python

**URL:** <https://discourse.processing.org/t/draw-function-processing-python/37451>\
**Category:** Processing.py\
**Created:** [June 10, 2022, 12:17pm UTC](https://discourse.processing.org/t/draw-function-processing-python/37451 "2022-06-10T12:17:10Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Daniel11](https://avatars.discourse-cdn.com/v4/letter/d/3d9bf3/32.png) [@Daniel11](https://discourse.processing.org/u/Daniel11)\
**Post date:** [June 10, 2022, 12:17pm UTC](https://discourse.processing.org/t/draw-function-processing-python/37451/1 "2022-06-10T12:17:10Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![javagar](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/javagar/32/11434_2.png) [@javagar](https://discourse.processing.org/u/javagar)\
**Post date:** [June 10, 2022, 12:38pm UTC](https://discourse.processing.org/t/draw-function-processing-python/37451/2 "2022-06-10T12:38:35Z")

</div>

Please post your code so that we can offer specific suggestions.

---

<div class="post-metadata">

**Author:** ![Daniel11](https://avatars.discourse-cdn.com/v4/letter/d/3d9bf3/32.png) [@Daniel11](https://discourse.processing.org/u/Daniel11)\
**Post date:** [June 10, 2022, 12:39pm UTC](https://discourse.processing.org/t/draw-function-processing-python/37451/3 "2022-06-10T12:39:46Z")

</div>

```auto
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

---

<div class="post-metadata">

**Author:** ![javagar](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/javagar/32/11434_2.png) [@javagar](https://discourse.processing.org/u/javagar)\
**Post date:** [June 10, 2022, 1:08pm UTC](https://discourse.processing.org/t/draw-function-processing-python/37451/4 "2022-06-10T13:08:22Z")

</div>

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:

```auto
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:

```auto
def draw():
    background(127)
    for i in range(frameCount % 10 + 1):
        rect(random(100, 300), random(100, 300), 100, 100)

```

---

<div class="post-metadata">

**Author:** ![tabreturn](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/tabreturn/32/3697_2.png) [@tabreturn](https://discourse.processing.org/u/tabreturn)\
**Post date:** [June 10, 2022, 8:17pm UTC](https://discourse.processing.org/t/draw-function-processing-python/37451/5 "2022-06-10T20:17:15Z")

</div>

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).

---

<div class="post-metadata">

**Author:** ![Daniel11](https://avatars.discourse-cdn.com/v4/letter/d/3d9bf3/32.png) [@Daniel11](https://discourse.processing.org/u/Daniel11)\
**Post date:** [June 11, 2022, 10:06am UTC](https://discourse.processing.org/t/draw-function-processing-python/37451/6 "2022-06-11T10:06:59Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![javagar](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/javagar/32/11434_2.png) [@javagar](https://discourse.processing.org/u/javagar)\
**Post date:** [June 11, 2022, 10:54am UTC](https://discourse.processing.org/t/draw-function-processing-python/37451/7 "2022-06-11T10:54:13Z")

</div>

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:

```auto
        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._

---

<div class="post-metadata">

**Author:** ![Daniel11](https://avatars.discourse-cdn.com/v4/letter/d/3d9bf3/32.png) [@Daniel11](https://discourse.processing.org/u/Daniel11)\
**Post date:** [June 11, 2022, 11:13am UTC](https://discourse.processing.org/t/draw-function-processing-python/37451/8 "2022-06-11T11:13:31Z")

</div>

Works amazingly tysm

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [June 11, 2022, 1:01pm UTC](https://discourse.processing.org/t/draw-function-processing-python/37451/9 "2022-06-11T13:01:52Z")

</div>

> [@javagar](#):
>
> 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.

No need for additional fixed increasing global variables if they’re updated once per [**draw()**](https://py.processing.org/reference/draw.html) iteration.

For example, if you need some global variable which is updated by `.01` steps, just multiply that value by [_frameCount_](https://py.processing.org/reference/frameCount.html) locally: `someLocalVariable = .01 * frameCount`
