class Wanderer: def __init__(self, car, radius): self.car = car self.predict = Pvector(self.car.location.x, self.car.location.y) self.radius = radius def generate_target(self): if self.car.location.x < 0 or self.car.location.x > 800: self.car.velocity.x *= -1 if self.car.location.y < 0 or self.car.location.y > 800: self.car.velocity.y *= -1 self.predict = Pvector(self.car.location.x, self.car.location.y) self.predict.add(self.car.velocity) theta = uniform(self.car.velocity.heading() - np.pi / 2, self.car.velocity.heading() + np.pi / 2) randvec = Pvector(np.cos(theta), np.sin(theta)) randvec.mult(self.radius) self.predict.add(randvec) def display(self): self.generate_target() self.car.seek(self.predict) self.car.update() self.car.display()
def get_normal(a,b,v): global points predict=v.velocity.get() predict.setMag(50) predict.add(v.location) predict.sub(a) alongpath=Pvector(b.x-a.x,b.y-a.y) alongpath.norm() mag=predict.dot(alongpath) alongpath.mult(mag) alongpath.add(a) if points.points[-1].x>points.points[0].x: if alongpath.x>b.x or alongpath.x<a.x: alongpath=b.get() else: if alongpath.x<b.x or alongpath.x>a.x: alongpath=b.get() return alongpath
def seperate(self,others): sum=Pvector(0,0) count=0 for v in others: loc=self.location.get() loc.sub(v.location) d=loc.magnitude() if d>0 and d<50: loc.mult(1/d) sum.add(loc) count=count+1 if count!=0: sum.mult(1/count) sum.norm() sum.mult(self.maxspeed) sum.sub(self.velocity) sum.limit(self.maxforce) return sum
def draw(): global points,vehicles #gf.record() for v in vehicles: worldRecord=100000 bestPath=None if points.points[0].x<points.points[-1].x: if v.location.x>points.points[-1].x: v.location.x=points.points[0].x v.location.y=points.points[0].y+(v.location.y-points.points[-1].y) else: if v.location.x<points.points[-1].x: v.location.x=points.points[0].x v.location.y=points.points[0].y+(v.location.y-points.points[-1].y) for i in range(len(points.points)-1): a=points.points[i].get() b=points.points[i+1].get() if points.points[0].x<points.points[-1].x: if b.x<v.location.x: continue else: if v.location.x<b.x: continue norm=get_normal(a,b,v) dist=get_distance(norm.get(),v.location) if dist<worldRecord: worldRecord=dist bestNorm=norm bestPath=Pvector(b.x-a.x,b.y-a.y) bestPath.setMag(50) if worldRecord>50: bestNorm.add(bestPath) seek=v.seek(bestNorm) else: bestPath.add(v.location) seek=v.seek(bestPath) seperate=v.seperate(vehicles) seperate.mult(0.8) v.applyForce(seek) v.applyForce(seperate) v.update() v.display() background(255) points.display()
class vehicle: def __init__(self,location=(400,400),velocity=(0,0),acceleration=(0,0),maxspeed=10,maxforce=3,field=None): # add field for field followers self.location=Pvector(location[0],location[1]) self.velocity=Pvector(velocity[0],velocity[1]) self.acceleration=Pvector(acceleration[0],acceleration[1]) self.maxspeed=maxspeed self.maxforce=maxforce self.radius=8 self.field=field def seek(self,target): desired=Pvector(target.x,target.y) desired.sub(self.location) mag=desired.magnitude() if mag<100: setmag=mag*self.maxspeed/100 desired.setMag(setmag) else: desired.setMag(self.maxspeed) desired.sub(self.velocity) desired.limit(self.maxforce) return desired def seperate(self,others): sum=Pvector(0,0) count=0 for v in others: loc=self.location.get() loc.sub(v.location) d=loc.magnitude() if d>0 and d<50: loc.mult(1/d) sum.add(loc) count=count+1 if count!=0: sum.mult(1/count) sum.norm() sum.mult(self.maxspeed) sum.sub(self.velocity) sum.limit(self.maxforce) return sum def seek_flow(self): if self.location.x<0: self.location.x=799 if self.location.x>799: self.location.x=0 if self.location.y<0: self.location.y=799 if self.location.y>799: self.location.y=0 desired=Pvector(self.lookup(self.location).x,self.lookup(self.location).y) desired.setMag(self.maxspeed) desired.sub(self.velocity) desired.limit(self.maxforce) self.applyForce(desired) def lookup(self,location): k=800/self.field.shape[0] return self.field[m.floor(location.x/k)][m.floor(location.y/k)] def update(self): self.velocity.add(self.acceleration) self.velocity.limit(self.maxspeed) self.location.add(self.velocity) self.acceleration.mult(0) def applyForce(self,force): self.acceleration.add(force) def display(self): theta=self.velocity.heading()+m.pi/2 stroke_weight(1) stroke(0) fill(0) push_matrix() translate(self.location.x,self.location.y) rotate(theta) begin_shape() vertex(-self.radius,2*self.radius) vertex(0,-2*self.radius) vertex(self.radius,2*self.radius) end_shape(CLOSE) pop_matrix()