# Complex Boundaries

**URL:** <https://discourse.processing.org/t/complex-boundaries/12088>\
**Category:** Coding Questions\
**Created:** [June 16, 2019, 1:19am UTC](https://discourse.processing.org/t/complex-boundaries/12088 "2019-06-16T01:19:51Z")\
**Posts on this page:** 1\
**Showing post:** 4

<div class="post-metadata">

**Author:** ![solub](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/solub/32/333_2.png) [@solub](https://discourse.processing.org/u/solub)\
**Post date:** [June 16, 2019, 11:15am UTC](https://discourse.processing.org/t/complex-boundaries/12088/4 "2019-06-16T11:15:07Z")

</div>

Hi @LordCacops,

I think @monkstone 's suggestion is well suited for what you’re trying to achieve.  
Here’s a simple example sketch in Python mode based on the (very useful) examples he provided in [this thread](https://discourse.processing.org/t/geomerative-fitting-text-inside-arbitrary-shapes/4917/3) and on [his gist](https://gist.github.com/monkstone/44aa5ae72d8305d97d990f94b506cdf3).

 ![ss85](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/2/21b918385b0c159b5c058c3f5f109578dd8e5b0a.png)

_(Click the mouse to change mode: enclosing/avoidance)_

```auto
add_library('geomerative')

# Polygon parameters
N = 10
angle = radians(360) / N
radius = 200

# Enclose Mode (enclosing or repulsing particles)
Enclose = True

def setup():
    size(1000, 600, P2D)
    smooth(8)
    
    global polyshape, balls, center

    # Array of Ball() objects
    balls = [Ball() for i in xrange(30)]
    
    # Instantiating our RPolygon
    RG.init(this)
    rpoly = RPolygon()
    
    # Building polygon from vertices location
    for i in xrange(N):
        r = random(.5, 1.3)
        x = cos(angle * i) * (radius * r) + width/2
        y = sin(angle * i) * (radius * r) + height/2
        rpoly.addPoint(RPoint(x, y))
     
    # Converting our RPolygon() to RShape()  
    polyshape = RShape(rpoly.toShape())
    
    # Stores location of its centroid
    center = polyshape.getCentroid()
    
    
def draw():
    pushStyle()
    noStroke()
    fill(255, 100)
    rect(0, 0, width, height)
    popStyle()
    
    # Displaying balls + updating location
    for b in balls:
        b.update()
        b.render()
    
    # Drawing our polygon shape
    pushStyle()
    stroke('#504AFF')
    strokeWeight(2)
    noFill()
    polyshape.draw()
    popStyle()
    

       
class Ball(object):
    def __init__ (self):
        self.loc = PVector(random(width), random(height))
        self.vel = PVector.random2D()
        
    def update(self):
        self.loc.add(self.vel) # Updating location
        self.vel.limit(2) # Limiting velocity
        
        dir = PVector(center.x, center.y).sub(self.loc) # Direction
        f = dir.sub(self.vel).normalize().mult(.1) # Force (remove 'mult()' for a hard stop)
        
        if Enclose:
            # If ball not within the boundaries of the polygon:
            # --> divert it back to the center of the poygon
            if not polyshape.contains(RPoint(self.loc.x, self.loc.y)):
                self.vel.add(f)
        
        # Else --> avoidance behavior
        elif polyshape.contains(RPoint(self.loc.x, self.loc.y)):
            self.vel.sub(f)
                
        # Canvas boundaries       
        if self.loc.x > width or self.loc.x < 0: self.vel.x *= -1
        if self.loc.y > height or self.loc.y < 0: self.vel.y *= -1

    def render(self):
        if polyshape.contains(RPoint(self.loc.x, self.loc.y)):
            strokeWeight(10)
            stroke('#FF4A62')
        else:
            strokeWeight(6)
            stroke('#69C375')
            
        point(self.loc.x, self.loc.y, self.loc.z)
        
def mouseClicked():
    global Enclose
    Enclose = not Enclose
    print "Enclose Mode is %s" % Enclose

```

---

_[View the full topic](https://discourse.processing.org/t/complex-boundaries/12088)._
