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 and on his gist.
(Click the mouse to change mode: enclosing/avoidance)
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