Applying forces of a compound field to a non-IGeo object
co-ord opened this issue · comments
Dear Sugihara San,
I would like to apply forces of 2 ICompoundField()
(curl field + attractor field) to a Boid()
object that I've coded myself. This boid has an applyForce()
function where it reads the force value corresponding to its position in the compound field and then add it to its acceleration vector.
def applyForce(self):
curlForce = curl.get(IVec(self.pos.x, self.pos.y, self.pos.z))
curlForce = PVector(curlForce.x(), curlForce.y(), curlForce.z())
attrForce = attr.get(IVec(self.pos.x, self.pos.y, self.pos.z))
attrForce = PVector(attrForce.x(), attrForce.y(), attrForce.z())
self.acc.add(curlForce + attrForce) # simple addition of the 2 forces
Unfortunately, doing so gives me very different results from your original sketch entitled "Swarm Formation by Force Fields".
- Particles (boids) are sucked by the attractors instead of flocking around
- Gravity doesn't seem to apply (despite
IGravity(0,0,-2)
insetup()
) - Curl force is too strong when attraction force is removed (boids seem to be on rails)
I would really appreciate if you could explain how did you mix the curl force and attraction force together to get such a smooth motion.
Respectfully,
solub
Edit: Full script if needed
add_library('peasycam')
add_library('hemesh')
add_library('igeo')
W, H, D, s = 10, 15, 10, 100
N = W*H*D
def setup():
#size(1000, 600, P3D)
fullScreen(P3D)
randomSeed(1008)
strokeWeight(.7)
stroke(60)
noFill()
global curl, attr, boids
cam = PeasyCam(this, 1600)
boids = [Boid() for i in xrange(25)]
curl = ICompoundField()
attr = ICompoundField()
for i in xrange(10):
pt = IRand.pt(W*s*.25, 100, D*s*.25, W*s*.75, H*s, D*s*.75)
curl.add(IPointCurlField(pt, IVec(0, -1, 0)).intensity(-20))
attr.add(IAttractor(pt).intensity(20))
IGravity(0,0,-2)
def draw():
background('#FFFFFF')
translate((-W*s)>>1, (-H*s)>>1, (-D*s)>>1)
# Displaying the random points in the field
pushStyle()
stroke(255, 30, 30)
strokeWeight(8)
for p in curl.pointFields:
point(p.pos().x(), p.pos().y(), p.pos().z())
popStyle()
# Updating boids
for b in boids:
b.render()
b.update()
b.flock()
b.applyForce() #Trying to apply the forces of the compound fields to the boids
class Boid(object):
def __init__(self):
self.pos = PVector(random(W*s), 0, random(D*s))
self.vel = PVector().setMag(3)
self.acc = PVector()
self.radius = 50
self.maxSpeed = 1.5
self.maxForce = .1
self.trail = []
def update(self):
self.pos.add(self.vel)
self.vel.add(self.acc)
self.vel.limit(self.maxSpeed)
self.acc.mult(0)
def applyForce(self):
curlForce = curl.get(IVec(self.pos.x, self.pos.y, self.pos.z))
curlForce = PVector(curlForce.x(), curlForce.y(), curlForce.z())
attrForce = attr.get(IVec(self.pos.x, self.pos.y, self.pos.z))
attrForce = PVector(attrForce.x(), attrForce.y(), attrForce.z())
self.acc.add(curlForce + attrForce)
def flock(self):
count = 0
aVel = PVector() #average velocity
aPos = PVector() #average position
aDif = PVector() #average difference
for b in boids:
d = self.pos.dist(b.pos)
if b != self and d < self.radius:
count += 1
aVel += b.vel
aPos += b.pos
diff = self.pos.copy().sub(b.pos)
aDif += diff.div(d) #inversional to distance (the farther, the lower the magnitude)
if count > 0:
#Alignment
aVel.div(count).setMag(self.maxSpeed) #maxSpeed prevent from steering too hard
alignSteering = aVel.sub(self.vel).limit(self.maxForce)
#Cohesion
aPos.div(count)
coheSteering = aPos.sub(self.pos).setMag(self.maxSpeed).sub(self.vel).limit(self.maxForce)
#Separation
aDif.div(count)
sepaSteering = aDif.setMag(self.maxSpeed).sub(self.vel).limit(self.maxForce)
self.acc.add(coheSteering + sepaSteering) #+ alignSteering # Alignment set to 0 by Sugihara san in his original sketch
def render(self):
pushStyle()
strokeWeight(8)
point(self.pos.x, self.pos.y, self.pos.z)
popStyle()
# Trail
if frameCount%10 == 0:
self.trail.append(PVector(self.pos.x, self.pos.y, self.pos.z))
if len(self.trail) > 0:
for i in xrange(1, len(self.trail)):
line(self.trail[i-1].x, self.trail[i-1].y, self.trail[i-1].z, self.trail[i].x, self.trail[i].y, self.trail[i].z)