1. NodeBox 1
    1. Homepage
    2. NodeBox 3Node-based app for generative design and data visualization
    3. NodeBox OpenGLHardware-accelerated cross-platform graphics library
    4. NodeBox 1Generate 2D visuals using Python code (Mac OS X only)
  2. Gallery
  3. Documentation
  4. Forum
  5. Blog

push() and pop()

Posted by Bill Mill on Mar 17, 2008

I'm not quite clear on what push() and pop() do, and my confusion is partially due to the fact that the example given in the graphics state tutorial,

size(450, 450)
speed(30)
 
def draw():
    
    transform(CORNER)
    
    # This is the starting origin point,
    # where we place the sun.
    translate(225, 225)
    oval(-5, -5, 10, 10)
    text("sun", 10, 0)
    
    rotate(FRAME)
    
    # What is being rotated is a group
    # with its own internal transformations.
    push()
    
    stroke(0)
    line(0, 0, 120, 0)
    
    # The earth acts as a local origin point
    # for the moon.
    translate(120, 0)
    oval(-5, -5, 10, 10)
    text("earth", 10, 0)
    
    # Keep rotating around the local origin.
    rotate(FRAME*6)
    
    line(0, 0, 30, 0)
    text("moon", 32, 0)
    
    pop()
Does not seem to change if you comment out the push() and pop(). What is supposed to be demonstrated here?


 
Posted by fdb on Mar 19, 2008

Hi,

push() and pop() respectively save and restore the transformation state of the canvas. They sort of do what brackets do in language: in the middle of the sentence, they can sidetrack, then go back to the sentence.

Here's a short example that demonstrates their use: Note that the last rectangle isn't rotated. That's because the rotation happens between the push and pop "brackets".

rect(20, 20, 40, 40)
push()
rotate(45)
rect(120, 20, 40, 40)
pop()
rect(220, 20, 40, 40)
As for the example in the graphics state tutorial, try appending a line after the last pop() command, e.g.
text("venus", 32, 0)
Now, note that that line doesn't move together with the moon, whereas if you comment out the push and pop statements, it does move with the moon.

Hope this helps.

Kind regards,

Frederik



Posted by Tom De Smedt on Mar 21, 2008

I've made some adjustments to the tutorial regarding push() and pop(), including Frederik's analogy of brackets.

The given example is perhaps more clear if you add more planets in a loop:

size(450, 450)
speed(30)
 
def draw():
    
    stroke(0)
    transform(CORNER)
    
    # This is the starting origin point,
    # where we place the sun.
    translate(225, 225)
    oval(-5, -5, 10, 10)
    text("sun", 10, 0)
    
    for i in range(3):
        
        # Each planet acts as a local origin for the orbitting moon.
        # Comment out the push() and pop() and see what happens.
        push()
        
        # This is a line with a length of 120,
        # that starts at the sun and has an angle of i * 120.
        rotate(FRAME+i*120)
        line(0, 0, 120, 0)
        
        # Move the origin to the end of the line.
        translate(120, 0)
        oval(-5, -5, 10, 10)
        text("planet", 10, 0)
        
        # Keep rotating around the local planet.
        rotate(FRAME*6)
        line(0, 0, 30, 0)
        text("moon", 32, 0)
        
        # Move the origin back to the sun.
        pop()