Beispiel #1
0
 def test_(self):
     a = (98, 28)
     b = (72, 33)
     c = (10, -5)
     d = (20, 88)
     result =  Vector.line_intersection(a, b, c, d)
     self.assertEqual(result.x, 15.25931928687196)
     self.assertEqual(result.y, 43.911669367909241)
Beispiel #2
0
 def test_(self):
     a = (98, 28)
     b = (72, 33)
     c = (10, -5)
     d = (20, 88)
     result = Vector.line_intersection(a, b, c, d)
     self.assertEqual(result.x, 15.25931928687196)
     self.assertEqual(result.y, 43.911669367909241)
Beispiel #3
0
    def check_deflector_collision(self, deflector):
        # Here we have a collision Bullet <--> Deflector-bounding-box. But that doesn't mean
        # that there's a collision with the deflector LINE yet. So here's some math stuff
        # for the freaks :) It includes vector calculations, distance problems and trigonometry

        # first thing to do is: we need a vector describing the bullet. Length isn't important.
        bullet_position = Vector(self.center)
        bullet_direction = Vector(1, 0).rotate(self.angle * 360 / (2 * pi))
        deflector_point1 = Vector(
            deflector.to_parent(deflector.point1.center[0],
                                deflector.point1.center[1]))
        deflector_point2 = Vector(
            deflector.to_parent(deflector.point2.center[0],
                                deflector.point2.center[1]))

        # then we need a vector describing the deflector line.
        deflector_vector = Vector(deflector_point2 - deflector_point1)

        # now we do a line intersection with the deflector line:
        intersection = Vector.line_intersection(
            bullet_position, bullet_position + bullet_direction,
            deflector_point1, deflector_point2)

        # now we want to proof if the bullet comes from the 'right' side.
        # Because it's possible that the bullet is colliding with the deflectors bounding box but
        # would miss / has already missed the deflector line.
        # We do that by checking if the expected intersection point is BEHIND the bullet position.
        # ('behind' means the bullets direction vector points AWAY from the vector
        # [bullet -> intersection]. That also means the angle between these two vectors is not 0
        # -> due to some math-engine-internal inaccuracies, i have to check if the angle is greater than one:
        if abs(bullet_direction.angle(intersection - bullet_position)) > 1:
            # if the bullet missed the line already - NO COLLISION
            return False

        # now we finally check if the bullet is close enough to the deflector line:
        distance = abs(
            sin(radians(bullet_direction.angle(deflector_vector)) %
                (pi / 2))) * Vector(intersection - bullet_position).length()
        if distance < (self.width / 2):
            # there is a collision!
            # kill the animation!
            self.animation.unbind(on_complete=self.on_collision_with_edge)
            self.animation.stop(self)
            # call the collision handler
            self.on_collision_with_deflector(deflector, deflector_vector)
Beispiel #4
0
 def check_deflector_collision(self, deflector):
     # Here we have a collision Bullet <--> Deflector-bounding-box. But that doesn't mean
     # that there's a collision with the deflector LINE yet. So here's some math stuff
     # for the freaks :) It includes vector calculations, distance problems and trigonometry
     
     # first thing to do is: we need a vector describing the bullet. Length isn't important.
     bullet_position = Vector(self.center)
     bullet_direction = Vector(1, 0).rotate(self.angle * 360 / (2*pi))
     deflector_point1 = Vector(deflector.to_parent(deflector.point1.center[0], deflector.point1.center[1]))
     deflector_point2 = Vector(deflector.to_parent(deflector.point2.center[0], deflector.point2.center[1]))
     
     # then we need a vector describing the deflector line.
     deflector_vector = Vector(deflector_point2 - deflector_point1)
     
     # now we do a line intersection with the deflector line:
     intersection = Vector.line_intersection(bullet_position, bullet_position + bullet_direction, deflector_point1, deflector_point2)
     
     # now we want to proof if the bullet comes from the 'right' side.
     # Because it's possible that the bullet is colliding with the deflectors bounding box but
     # would miss / has already missed the deflector line.
     # We do that by checking if the expected intersection point is BEHIND the bullet position.
     # ('behind' means the bullets direction vector points AWAY from the vector 
     # [bullet -> intersection]. That also means the angle between these two vectors is not 0
     # -> due to some math-engine-internal inaccuracies, i have to check if the angle is greater than one:
     if abs(bullet_direction.angle(intersection - bullet_position)) > 1:
         # if the bullet missed the line already - NO COLLISION
         return False
     
     # now we finally check if the bullet is close enough to the deflector line:
     distance = abs(sin(radians(bullet_direction.angle(deflector_vector)) % (pi/2))) * Vector(intersection - bullet_position).length()
     if distance < (self.width / 2):
         # there is a collision!
         # kill the animation!
         self.animation.unbind(on_complete=self.on_collision_with_edge)
         self.animation.stop(self)
         # call the collision handler
         self.on_collision_with_deflector(deflector, deflector_vector)
Beispiel #5
0
    def collide_wall(self, wall):
        # don't collide with this wall if we just did so; this
        # eliminates a huge class of weird behaviors
        if self.last_bounced_wall == wall and self.last_bounced_ticks < 5:
            return

        deflect_edge = None
        velocity_v = Vector(self.velocity)
        pos_v = Vector(self.pos)

        edge_points = zip(wall.quad_points[0::2], wall.quad_points[1::2])
        edges = [
            (edge_points[0], edge_points[1]),
            (edge_points[1], edge_points[2]),
            (edge_points[2], edge_points[3]),
            (edge_points[3], edge_points[0]),
        ]

        closest_point = None

        for point in edge_points:
            if (pos_v - Vector(point)).length() < self.r:
                if not closest_point or \
                   (pos_v - Vector(point)).length() < (Vector(closest_point) - Vector(point)).length():
                    closest_point = point

        if closest_point:
            # take the deflection edge to be the normal of here to the corner
            deflect_edge = (pos_v - Vector(point)).rotate(90)

        else:
            for edge in edges:
                e0 = Vector(edge[0])
                e1 = Vector(edge[1])

                ortho_v = (e0 - e1).rotate(90).normalize()
                dist_v = Vector.line_intersection(self.pos, pos_v + ortho_v,
                                                  edge[0], edge[1])

                # dist_v will be None if we happen to be parallel
                if not dist_v:
                    continue

                dist_from_edge = (pos_v - dist_v).length()

                # if the shot touches the wall here
                if min(e0[0], e1[0]) <= dist_v[0] <= max(e0[0], e1[0]) and \
                   min(e0[1], e1[1]) <= dist_v[1] <= max(e0[1], e1[1]) and \
                   dist_from_edge < self.r + (wall.thickness / 2.):
                    if not deflect_edge:
                        deflect_edge = e0 - e1
                        dist_from_deflect_edge = dist_from_edge

                    elif dist_from_edge < dist_from_deflect_edge:
                        deflect_edge = e0 - e1
                        dist_from_deflect_edge = dist_from_edge

        if deflect_edge:
            self.velocity = velocity_v.rotate(-2 *
                                              velocity_v.angle(deflect_edge))
            self.last_bounced_wall = wall
            self.last_bounced_ticks = 0
Beispiel #6
0
    def collide_wall(self, wall):
        # don't collide with this wall if we just did so; this
        # eliminates a huge class of weird behaviors
        if self.last_bounced_wall == wall and self.last_bounced_ticks < 5:
            return

        deflect_edge = None
        velocity_v = Vector(self.velocity)
        pos_v = Vector(self.pos)

        edge_points = zip(wall.quad_points[0::2], wall.quad_points[1::2])
        edges = [
            (edge_points[0], edge_points[1]),
            (edge_points[1], edge_points[2]),
            (edge_points[2], edge_points[3]),
            (edge_points[3], edge_points[0]),
        ]

        closest_point = None

        for point in edge_points:
            if (pos_v - Vector(point)).length() < self.r:
                if (
                    not closest_point
                    or (pos_v - Vector(point)).length() < (Vector(closest_point) - Vector(point)).length()
                ):
                    closest_point = point

        if closest_point:
            # take the deflection edge to be the normal of here to the corner
            deflect_edge = (pos_v - Vector(point)).rotate(90)

        else:
            for edge in edges:
                e0 = Vector(edge[0])
                e1 = Vector(edge[1])

                ortho_v = (e0 - e1).rotate(90).normalize()
                dist_v = Vector.line_intersection(self.pos, pos_v + ortho_v, edge[0], edge[1])

                # dist_v will be None if we happen to be parallel
                if not dist_v:
                    continue

                dist_from_edge = (pos_v - dist_v).length()

                # if the shot touches the wall here
                if (
                    min(e0[0], e1[0]) <= dist_v[0] <= max(e0[0], e1[0])
                    and min(e0[1], e1[1]) <= dist_v[1] <= max(e0[1], e1[1])
                    and dist_from_edge < self.r + (wall.thickness / 2.0)
                ):
                    if not deflect_edge:
                        deflect_edge = e0 - e1
                        dist_from_deflect_edge = dist_from_edge

                    elif dist_from_edge < dist_from_deflect_edge:
                        deflect_edge = e0 - e1
                        dist_from_deflect_edge = dist_from_edge

        if deflect_edge:
            self.velocity = velocity_v.rotate(-2 * velocity_v.angle(deflect_edge))
            self.last_bounced_wall = wall
            self.last_bounced_ticks = 0