def random(cls, n=2): """Create a random pendulum.""" angles = [Motion(math.pi*Vector.random(d=1), Vector.null(d=1), Vector.null(d=1)) for i in range(n)] lengths = [random.uniform(0, 1) for i in range(n)] masses = [random.uniform(0, 1) for i in range(n)] return cls(angles, lengths, masses)
def createFromThreePoints(points): """Create an angle from 3 points.""" p1, p2, p3 = points v1 = Vector.createFromTwoPoints(p2, p1) v2 = Vector.createFromTwoPoints(p2, p3) angle = v2.angle() - v1.angle() return Angle(angle)
def random(cls, p=100, v=10): """Create a boid with a random motion.""" p = p * Vector.random() v = v * Vector.random() a = Vector.null() m = Motion(p, v, a) return cls(m)
def previous(self, t=1): """Return the previous motion using its actual one using optional time t.""" acceleration = Vector([a for a in self.acceleration]) velocity = Vector( [v - a * t for (v, a) in zip(self.velocity, self.acceleration)]) position = Vector( [p - v * t for (p, v) in zip(self.position, self.velocity)]) return Motion(position, velocity, acceleration)
def createRandomBody(): form=5*Form.random(n=5) form.side_color=mycolors.RED form.area_color=mycolors.BLACK form.fill=True motion=Motion(10*Vector.random(),Vector.random(),Vector.null()) moment=Motion(Vector([1]),Vector([0.1])) return Body(form,motion,moment)
def random(corners=[-1, -1, 1, 1], radius=random.uniform(0, 1), color=mycolors.WHITE): """Create a random material circle.""" p = Vector.random() v = Vector.random() a = Vector.random() m = Motion([p, v, a]) return MaterialCircle(m, radius, color)
def __init__(self,position,size=5): """Create an asteroid.""" form=size*Form.random(n=5) form.side_color=mycolors.RED form.area_color=mycolors.DARKGREY form.fill=True motion=Motion(Vector(*position),Vector.random(),Vector.null()) moment=Motion(Vector([0]),Vector([random.uniform(-1,1)])) super().__init__(form,motion,moment)
def updateAlignment(self, mates): """Alignment: Steer towards the average heading of local flockmates.""" #mates = self.getVisibleMates(mates, self.alignment_perception) if len(mates) == 0: return Vector.null() v = Vector.average([m.velocity for m in mates]) v.norm = self.max_velocity v -= self.velocity v.limit(self.max_acceleration) return v
def computeMotion(self): """Find the motion of a planet with its distance and its mass.""" angle = random.uniform(0, 2 * math.pi) norm = self.distance position = Vector.createFromPolar(norm, angle) angle = (angle + math.pi / 2) % (2 * math.pi) norm = self.speed # in m/s-1 velocity = Vector.createFromPolar(norm, angle) acceleration = Vector.null() return Motion(position, velocity, acceleration)
def events(self): """Deal with the user input.""" cursor = copy.deepcopy(Point(*self.context.point())) click = self.context.click() for event in pygame.event.get(): if event.type == QUIT: self.context.open = False if event.type == KEYDOWN: if event.key == K_ESCAPE: self.context.open = False if event.type == MOUSEBUTTONDOWN: if event.button == 1: self.focus_index = None for body in self.bodies: if cursor in body.absolute: self.focus_index = self.bodies.index(body) if self.focus_index: self.bodies[self.focus_index].position = Vector( *cursor) if event.button == 3: c = copy.deepcopy(cursor) if self.focus_index == None: self.focus_index = len(self.bodies) f = Form([c]) self.bodies.append(Body.createFromForm(f)) else: fa = copy.deepcopy( self.bodies[self.focus_index].absolute) fa.points.append(c) self.bodies[self.focus_index].absolute = fa if event.type == MOUSEMOTION: if self.focus and click: self.focus.position = Vector(*cursor) keys = pygame.key.get_pressed() if keys[K_DOWN]: self.context.draw.plane.position[1] -= 1 if keys[K_UP]: self.context.draw.plane.position[1] += 1 if keys[K_LEFT]: self.context.draw.plane.position[0] -= 1 if keys[K_RIGHT]: self.context.draw.plane.position[0] += 1 if keys[K_LSHIFT]: self.context.draw.plane.zoom([0.9, 0.9]) if keys[K_RSHIFT]: self.context.draw.plane.zoom([1.1, 1.1])
def updateCohesion(self, mates): """Cohesion: steer to move toward the average position of local flockmates.""" #mates = self.getVisibleMates(mates, self.cohesion_perception) if len(mates) == 0: return Vector.null() p = Vector.average([m.position for m in mates]) v = p - self.position v.norm = self.max_velocity v -= self.velocity v.limit(self.max_acceleration) return v
def __init__(self, n=10, s=5, g=10, radius_borns=[1, 10], **kwargs): super().__init__(**kwargs) # entities = [Entity(FormAnatomy.random(), # [Motion(s * Vector.random(), 10 * Vector.random(), Vector(0, -g)), # Moment(Vector.random(), 5*Vector.random())], friction=0) # for i in range(n)] self.group = Group(*[Entity(CircleAnatomy.random(radius_borns=radius_borns), \ [Motion(s*Vector.random(), Vector(0,0), Vector(0, -g))], friction=0.1) \ for i in range(n)]) self.collider = Collider(elasticity=0.9) self.born = s self.born_elasticity = 0.5 self.square = Square(0, 0, 2 * self.born) self.correctMasses()
def updateSeparation(self, mates): """Separation: Avoid crowding local flockmates.""" #mates = self.getVisibleMates(mates, self.separation_perception) if len(mates) == 0: return Vector.null() vs = [] for mate in mates: v = self.position - mate.position v.norm = 1 / v.norm vs.append(v) v = Vector.average(vs) v.norm = self.max_velocity v -= self.velocity v.limit(self.max_acceleration) return v
def enlarge(self, n): center = self.center for point in self.points: v = n * Vector.createFromTwoPoints(center, point) point.set(v(point)) # self._born *= n self.updateBorn()
def show(self, context): """Show all the objects on screen.""" for object in self.objects: object.center.showMotion(context) object.show(context) l = len(self.objects) for i in range(l): for j in range(i + 1, l): points = self.objects[i].abstract | self.objects[j].abstract if points != []: self.objects[i].velocity *= 0 print(points) l1 = Segment(*points[:2]) l1.color = mycolors.GREEN l1.show(context) p = l1.center p.show(context, mode="cross", color=mycolors.RED) c1 = self.objects[i].center.abstract v = Vector.createFromTwoPoints(c1, p) v.color = mycolors.GREEN v.show(context, c1) v.norm = 1 v.color = mycolors.BLUE v.show(context, p) v.showText(context, p, 'up') v.rotate(math.pi / 2) v.show(context, p) v.showText(context, p, 'uo')
def __init__(self,context,dt=0.5): """Create a game.""" self.context=context self.dt=dt self.asteroids=[Asteroid(self.random(-10,10,2)) for i in range(10)] self.spaceships=[Spaceship(Vector(0,100))] self.missiles=[]
def drawVectors(context, color, points): """Draw the vectors from the points.""" for i in range(len(points) - 1): v = Vector.createFromTwoTuples(points[i], points[i + 1], color=color) v.showFromTuple(context, points[i])
def random(cls, na=5, sparse=1e10): """Create a random astre.""" c = "bcdfghjklmnpqrstvwxyz" v = "aeiou" def rd(n): return c[random.randint(0, len(c) - 1) ] if n % 2 == 0 else v[random.randint(0, len(v) - 1)] name = "".join([rd(i) for i in range(na)]) radius = random.uniform(0, 1) mass = random.uniform(1e20, 1e26) position = 1e12 * Vector.random() velocity = 1e6 * Vector.random() velocity.angle = (position.angle + math.pi / 2) % (2 * math.pi) acceleration = Vector.null() motion = Motion(position, velocity, acceleration) color = mycolors.random() return cls(name, radius, mass, motion, color)
def update(self): v = Vector(*self.context.point()) self.l1.angle = v.angle self.intersection = self.l1.crossLine(self.l2) if self.intersection: self.intersection.color = mycolors.RED self.intersection.radius = 1
def showRadius(self,window,color=None,width=None): """Show the radius of the circle.""" if not color: color=self.radius_color if not width: width=self.radius_width vector=Vector.createFromPolarCoordonnates(self.radius,0,color=color) vector.show(window,self.center,width=width) vector.showText(surface,self.center,"radius",size=20)
def updateAstreMotion(self, n): """Update the motion of the n-th astre.""" f = Force.null() for i in range(len(self.astres)): if i != n: f += System.attraction(self.astres[n], self.astres[i]) self.astres[n].acceleration = Vector(*f)
def rotate(self, angle=math.pi, center=Point.origin()): """Rotate the point using an angle and the point of rotation.""" self.abstract.rotate(angle, center) point = self.abstract point.rotate(angle, center) vector = Vector.createFromPoint(point) self.motion.setPosition(vector)
def update(self): """Update the bodies.""" self.updateAsteroids() self.updateSpaceships() self.updateMissiles() self.handleCollision() if len(self.spaceships)==0: self.spaceships.append(Spaceship(Vector(0,100)))
def follow(self, point): """Follow the given point.""" p = Vector(*point) for boid in self.boids: v = (p - boid.position) / 10 print(v, boid.acceleration) boid.acceleration.set(boid.acceleration + v) print(boid.acceleration)
def __call__(self, position, velocity, born): """Return a missile with the same motion.""" s = SegmentAnatomy.createFromTuples((0, 0), (1, 0)) s.angle = velocity.angle m = Motion(copy.deepcopy(position), copy.deepcopy(velocity)) m.position += Vector.createFromPolar(born + 1, velocity.angle) m.velocity.norm += self.speed self.shooting = False return [self.type(s, [m], damage=self.damage, duration=self.duration)]
def onCollision(self, point): """React to a physical collision between two objects using the material point of collision.""" vector = Vector.createFromPoint(point) a = vector.angle() v1 = self.motion.getVelocity() v2 = point.motion.getVelocity() v1.rotate() pm = point.mass px, py = point.position
def show(self, context, point=Point(0, 0), angle=0): """Show the moment.""" if len(self) >= 1: mp = self.position v = Vector.createFromPolar(mp.norm, angle) v.color = mp.color v.show(context, point) if len(self) >= 2: angle += math.pi / 2 mv = self.velocity v = Vector.createFromPolar(mv.norm, angle) v.color = mv.color v.show(context, point) if len(self) >= 3: angle += math.pi / 2 ma = self.acceleration a = Vector.createFromPolar(ma.norm, angle) a.color = ma.color a.show(context, point)
def events(self): """Deal with the events.""" keys=self.context.press() p=Point(*self.context.point()) v=Vector(*(p-Point(*self.spaceships[0].position)))/10 self.spaceships[0].velocity=v self.context.draw.plane.position=copy.deepcopy(self.spaceships[0].position.components) missile=self.spaceships[0].shoot(self.context) if missile is not None: self.missiles.append(missile)
def getCenter(self): """Return the center of the material form.""" center=MaterialPoint.createFromform.center x,y=center position=Vector(x,y,color=mycolors.GREEN) point_motion=Motion() for point in self.points: point_motion+=point.getMotion() material_center=MaterialPoint(point_motion) material_center.setPosition(position) return material_center
def show(self, surface, points): """Show the angle between the points.""" p1, p2 = points #Need to be able to print arc of circles using pygame v1 = Vector.createFromTwoPoints(p1, p2) v1 = ~v1 v2 = v1 % self p3 = v2(p2) s1 = Segment(p1, p2) s2 = Segment(p2, p3) s1.show(surface) s2.show(surface)