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

Outside the canvas

Posted by Nortis on Aug 27, 2008

When I'm placing things randomly on the canvas. How can I make shore that nothing gets placed outside the screen?

I'm pretty shore there is a silly simple solution to this that just are to simple to think of.


 
Posted by fdb on Aug 28, 2008

It depends on the type of shape you're placing, but for simple rects or ovals, this will do:

size(200, 200)
 
for i in range(100):
    fill(random(), 0, 0)
    rect(random(WIDTH-30), random(HEIGHT-30), 30, 30)
For the x and y values, I use random values that lie between zero and the width of the canvas, minus the size of the shape. This will make sure they stay in the canvas.



Posted by fdb on Aug 28, 2008

As an alternative, if you want to use any shape, and compare it to any other shape, consider the following approach. Here, we use boolean operations to check if paths don't intersect eachother. This is the most generic and powerful way to do shape-in-shape placement.

size(200, 200)
 
canvas_rect = rect(0, 0, WIDTH, HEIGHT, draw=False)
 
path = textpath("A", 10, 10)
path.fit(0, 0, WIDTH, HEIGHT)
 
# As an alternative, you can use any shape, such as this oval.
# Comment out this line to use an oval instead of a letter.
# path = oval(0,0,WIDTH,HEIGHT, draw=False)
 
# We need to check if the shape falls fully within the bounds
# of the shape. To do that, we check if it *doesn't* intersect
# with the negative of this shape. So we take a shape as big as
# the canvas, and punch our path out of that, resulting in the
# negative shape.
negative = canvas_rect.difference(path)
 
# Now we place shapes by brute-force. We want 200 shapes,
# so we run a loop that doesn't finish until we have 200 shapes.
shapes = []
while len(shapes) < 200:
    # Place a random shape somewhere. This can be any shape.
    # Just don't make it too big, or it will never fit,
    # resulting in an infinite loop.
    r = rect(random(WIDTH), random(HEIGHT), 4, 4, draw=False)
    # If this path doesn't intersect with the negative of the 
    # original path, append it to the list of shapes.
    if not negative.intersects(r):
        shapes.append(r)
 
# Now, draw each of the shapes.
for shape in shapes:
    fill(random(), 0, 0)
    drawpath(shape)
See the documentation on compound paths to get the details behind this method: http://nodebox.net/code/index.php/Compound_paths



Posted by Nortis on Sep 01, 2008

Nice! Thank you both of you :)