Beispiel #1
0
	def test_ray_intersection(self):
		data = CollisionDetection.get_intersection_data(self.first_line, self.second_line)
		self.assertIsNone(data, 'Data should be null' + str(data) + ' ' + str(self.second_line))

		data = CollisionDetection.get_intersection_data(self.second_line, self.first_line)
		self.assertIsNone(data, 'Data should be null' + str(data) + ' ' + str(self.second_line))

		data = CollisionDetection.get_intersection_data(self.seventh_ray, self.eighth_ray)
		self.assertIsNone(data, 'Data should be null' + str(data) + ' ' + str(self.second_line))

		data = CollisionDetection.get_intersection_data(self.eighth_ray, self.seventh_ray)
		self.assertIsNone(data, 'Data should be null' + str(data) + ' ' + str(self.second_line))

		data1 = CollisionDetection.get_intersection_data(self.sixth_ray, self.fifth_ray)
		self.assertIsNotNone(data1, 'data1 shouldn\'t be null')
		point = data1.intersection_points
		self.assertEqual(point, [Vector2d(-2.53, -0.4)],
		                 'Intersection point for data1 does not equal to the expected')

		data2 = CollisionDetection.get_intersection_data(self.fifth_ray, self.sixth_ray)
		self.assertIsNotNone(data2, 'data2 shouldn\'t be null')
		point = data2.intersection_points
		self.assertEqual(point, [Vector2d(-2.53, -0.4)], 'Intersection point for data2 does not equal to '
		                                                 'the expected')

		data3 = CollisionDetection.get_intersection_data(self.third_ray, self.fourth_ray)
		self.assertIsNotNone(data3, 'Data3 should not be null')

		data4 = CollisionDetection.get_intersection_data(self.fourth_ray, self.third_ray)
		self.assertIsNotNone(data4, 'Data4 should not be null')
    def test_ray_interaction(self):
        data = self.first_ray.get_intersection_data(self.second_ray)
        self.assertIsNone(
            data,
            'Data should be null' + str(data) + ' ' + str(self.second_ray))

        data = self.second_ray.get_intersection_data(self.first_ray)
        self.assertIsNone(
            data,
            'Data should be null' + str(data) + ' ' + str(self.second_ray))

        data1 = self.sixth_ray.get_intersection_data(self.fifth_ray)
        self.assertIsNotNone(data1, 'data1 shouldn\'t be null')
        point = data1[0]
        self.assertEqual(point, [Vector2d(2, 4)], 'Intersection point for data1 does not equal to ' \
                                                  'the expected')

        data2 = self.fifth_ray.get_intersection_data(self.sixth_ray)
        self.assertIsNotNone(data2, 'data2 shouldn\'t be null')
        point = data2[0]
        self.assertEqual(
            point, [Vector2d(2, 4)],
            'Intersection point for data2 does not equal to '
            'the expected')

        data3 = self.third_ray.get_intersection_data(self.fourth_ray)
        self.assertIsNotNone(data3, 'Data3 should not be null')

        data4 = self.fourth_ray.get_intersection_data(self.third_ray)
        self.assertIsNotNone(data4, 'Data4 should not be null')
Beispiel #3
0
    def get_the_most_distant_points(
            self) -> Tuple[Vector2d, Vector2d, Vector2d, Vector2d]:
        """Return tuple of four the most distant points (x, y coordinates) starting from max x
		and by clockwise

		(max_x_point, max_y_point, min_x_point, min_y_point)
		"""
        max_x = -math.inf
        min_x = math.inf
        max_y = -math.inf
        min_y = math.inf
        max_x_point, max_y_point, min_x_point, min_y_point = Vector2d(
            0, 0), Vector2d(0, 0), Vector2d(0, 0), Vector2d(0, 0)

        for point in self.points:
            if max_x < point.x:
                max_x = point.x
                max_x_point = point

            elif min_x > point.x:
                min_x = point.x
                min_x_point = point

            if max_y < point.y:
                max_y = point.y
                max_y_point = point

            elif min_y > point.y:
                min_y = point.y
                min_y_point = point

        return max_x_point, max_y_point, min_x_point, min_y_point
Beispiel #4
0
 def test_project_on(self):
     self.assertEqual(self.second_vector.project_on(self.first_vector),
                      Vector2d(1, 0))
     self.assertEqual(self.third_vector.project_on(self.first_vector),
                      Vector2d(-1, 0))
     self.assertEqual(self.fourth_vector.project_on(self.first_vector),
                      Vector2d(0, 0))
Beispiel #5
0
    def __init__(self,
                 name: str,
                 attached_obj: Entity,
                 linear_drag: float,
                 mass: float = 1.0,
                 angular_drag: float = 1.0,
                 rb_type: str = "dynamic",
                 velocity: Vector2d = Vector2d(0, 0),
                 force: Vector2d = Vector2d(0, 0)):
        if not rb_type in RB_TYPES:
            raise AttributeError(
                "Rigid body time should be one of the following values {}, but not {}"
                .format(RB_TYPES, rb_type))
        super().__init__(name, CT_RIGID_BODY, attached_obj)

        self.mass = 1
        self.inverted_mass = 1 / mass

        self.result_force = force
        self.velocity = velocity

        self.linear_drag = linear_drag
        self.angular_drag = angular_drag

        self.simulate = True
        self.type = rb_type
class TestBaseForceGenerators(unittest.TestCase):

    shape = Circle(Vector2d(0, 0),1)

    _object = Object(shape)

    static_force_generator = StaticForceGenerator(
        "Test Static Force", Vector2d(0, -10), [_object])
    calculated_force_generator = CalculatedForceGenerator(
        "Test Calculated Force", [_object], calculator)
    temporary_force_generator = TemporaryForceGenerator(
        "Test Temporary Force", Vector2d(10, 0), [_object], 2000)
    conditional_force_generator = ConditionalForceGenerator(
        "Test Conditional Force", Vector2d(-10, 0), [_object], condition)

    def test_static_force(self):

        self.static_force_generator.apply_force(1)

        self.assertEqual(self._object.result_force,
                         Vector2d(0, -10), )

        self._object.clear_force()

    def test_calculated_force(self):

        self.calculated_force_generator.apply_force(1)

        self.assertEqual(self._object.result_force,
                         Vector2d(1, 1).scale(self._object.mass), "Calculated force error")

        self._object.clear_force()

    def test_conditional_force(self):

        self.conditional_force_generator.apply_force(1)

        self.assertEqual(self._object.result_force,
                         Vector2d(0, 0), "Conditional force (condition == False) error")

        self._object.mass = 10

        self.conditional_force_generator.apply_force(1)

        self.assertEqual(self._object.result_force,
                         Vector2d(-10, 0), "Conditional force (condition == True) error")

        self._object.mass = 1

        self._object.clear_force()
def get_dist_convex_polygons(first_polygon: "ConvexPolygon",
                             second_polygon: "ConvexPolygon") -> float:
    """Uses the Gilbert-Johnson-Keerthi Algorithm to get penetration depth and intersection points"""

    new_polygon_points = polygons_difference(first_polygon, second_polygon)
    convex_hull = create_convex_hull(new_polygon_points)

    closest_point = get_closest_support_point(convex_hull, Vector2d(0, 0))
    penetration = (closest_point - Vector2d(0, 0)).get_magnitude()

    if convex_hull.is_point_belongs(Vector2d(0, 0)):
        return -penetration

    return penetration
Beispiel #8
0
    def get_centroid(self) -> Vector2d:
        # https://en.wikipedia.org/wiki/Polygon
        centroid = Vector2d(0, 0)
        signed_area = 0.0

        for i in range(self.points_count - 1):
            x0 = self.points[i].x
            y0 = self.points[i].y
            x1 = self.points[i + 1].x
            y1 = self.points[i + 1].y

            temp_area = x0 * y1 - x1 * y0
            signed_area += temp_area
            centroid.x += (x0 + x1) * temp_area
            centroid.y += (y0 + y1) * temp_area

        x0 = self.points[self.points_count - 1].x
        y0 = self.points[self.points_count - 1].y
        x1 = self.points[0].x
        y1 = self.points[0].y
        temp_area = x0 * y1 - x1 * y0
        signed_area += temp_area
        centroid.x += (x0 + x1) * temp_area
        centroid.y += (y0 + y1) * temp_area

        signed_area *= 0.5
        centroid.x /= (6.0 * signed_area)
        centroid.y /= (6.0 * signed_area)

        return centroid
Beispiel #9
0
    def calculate_force(self, _object: BaseNonStaticObject) -> Vector2d:
        """Calculates gravity force for an object"""
        force_magnitude = self.free_fall_coefficient * _object.mass

        force = Vector2d(0, force_magnitude)

        return force
Beispiel #10
0
    def test_static_force(self):

        self.static_force_generator.apply_force(1)

        self.assertEqual(self._object.result_force,
                         Vector2d(0, -10), )

        self._object.clear_force()
Beispiel #11
0
    def test_calculated_force(self):

        self.calculated_force_generator.apply_force(1)

        self.assertEqual(self._object.result_force,
                         Vector2d(1, 1).scale(self._object.mass), "Calculated force error")

        self._object.clear_force()
Beispiel #12
0
    def test_conditional_force(self):

        self.conditional_force_generator.apply_force(1)

        self.assertEqual(self._object.result_force,
                         Vector2d(0, 0), "Conditional force (condition == False) error")

        self._object.mass = 10

        self.conditional_force_generator.apply_force(1)

        self.assertEqual(self._object.result_force,
                         Vector2d(-10, 0), "Conditional force (condition == True) error")

        self._object.mass = 1

        self._object.clear_force()
Beispiel #13
0
    def test_add_vector(self):
        self.assertEqual(
            self.integer_case.add_vector(self.float_case),
            Vector2d(self.integer_case.x + self.float_case.x,
                     self.integer_case.y + self.float_case.y),
            "Integer addition fails")

        self.assertEqual(
            self.integer_negative_case.add_vector(self.float_negative_case),
            Vector2d(self.integer_negative_case.x + self.float_negative_case.x,
                     self.integer_negative_case.y +
                     self.float_negative_case.y), "Integer addition fails")

        self.assertEqual(
            self.negative_case.add_vector(self.zero_case),
            Vector2d(self.negative_case.x + self.zero_case.x,
                     self.negative_case.y + self.zero_case.y),
            "Integer addition fails")
Beispiel #14
0
def is_intersect_convexpolygons(first_poly: "ConvexPolygon",
                                second_poly: "ConvexPolygon") -> bool:
    new_polygon_points = polygons_difference(first_poly, second_poly)
    convex_hull = create_convex_hull(new_polygon_points)

    if not convex_hull.is_point_belongs(Vector2d(0, 0)):
        return False

    return True
Beispiel #15
0
def get_shadow_polygon(poly: "BasePolygon", normal: Vector2d) -> Tuple[float, float]:
	min_shadow = float("inf")
	max_shadow = -float("inf")
	for point in poly.points:
		product = normal.dot_product(point)

		min_shadow = min(min_shadow, product)
		max_shadow = max(min_shadow, product)

	return min_shadow, max_shadow
Beispiel #16
0
    def test_subtract_vector(self):
        self.assertEqual(
            self.integer_case.subtract_vector(self.float_case),
            Vector2d(self.integer_case.x - self.float_case.x,
                     self.integer_case.y - self.float_case.y),
            "Integer subtraction fails")

        self.assertEqual(
            self.integer_negative_case.subtract_vector(
                self.float_negative_case),
            Vector2d(self.integer_negative_case.x - self.float_negative_case.x,
                     self.integer_negative_case.y -
                     self.float_negative_case.y), "Integer subtraction fails")

        self.assertEqual(
            self.negative_case.subtract_vector(self.zero_case),
            Vector2d(self.negative_case.x - self.zero_case.x,
                     self.negative_case.y - self.zero_case.y),
            "Integer subtraction fails")
Beispiel #17
0
    def get_support_point(self, direction: Vector2d) -> Vector2d:
        support_point = None
        max_product = -1

        for point in self.points:
            product = direction.dot_product(point)

            if product > max_product:
                max_product = product
                support_point = point

        return support_point
Beispiel #18
0
def get_segments_intersection_points(
        segment: Union["Line", "Segment", "Ray"],
        penetration_coefficients: Tuple[float, float]) -> List[Vector2d]:
    t, u = penetration_coefficients

    intersection_point_x = segment.first_point.x + t * (
        segment.second_point.x - segment.first_point.x)
    intersection_point_y = segment.first_point.y + t * (
        segment.second_point.y - segment.first_point.y)
    intersection_point = Vector2d(intersection_point_x, intersection_point_y)

    return [intersection_point]
Beispiel #19
0
	def test_segments_intersection(self):
		data = CollisionDetection.get_intersection_data(self.first_segment, self.second_segment)
		self.assertIsNone(data, 'Data should be null' + str(data) + ' ' + str(self.second_segment))

		data = CollisionDetection.get_intersection_data(self.second_segment, self.first_segment)
		self.assertIsNone(data, 'Data should be null' + str(data) + ' ' + str(self.second_segment))

		data1 = CollisionDetection.get_intersection_data(self.third_segment, self.fourth_segment)
		self.assertIsNotNone(data1, 'data1 shouldn\'t be null')
		point = data1.intersection_points
		self.assertEqual(point, [Vector2d(2, 4)], 'Intersection point for data1 does not equal to ' \
		                                          'the expected')

		data2 = CollisionDetection.get_intersection_data(self.fourth_segment, self.third_segment)
		self.assertIsNotNone(data2, 'data2 shouldn\'t be null')
		point = data2.intersection_points
		self.assertEqual(point, [Vector2d(2, 4)], 'Intersection point for data2 does not equal to '
		                                          'the expected')

		self.assertEqual(data1.intersection_points, data2.intersection_points,
		                 'data1[0] and data2[0] does not equal')
Beispiel #20
0
    def test_scale_integer(self):
        self.assertEqual(
            self.integer_case.scale(3),
            Vector2d(self.integer_case.x * 3, self.integer_case.y * 3),
            "Integer scale fails")

        self.assertEqual(
            self.float_case.scale(3),
            Vector2d(self.float_case.x * 3, self.float_case.y * 3),
            "Integer scale fails")

        self.assertEqual(
            self.integer_negative_case.scale(3),
            Vector2d(self.integer_negative_case.x * 3,
                     self.integer_negative_case.y * 3), "Integer scale fails")

        self.assertEqual(
            self.float_negative_case.scale(3),
            Vector2d(self.float_negative_case.x * 3,
                     self.float_negative_case.y * 3), "Integer scale fails")

        self.assertEqual(
            self.negative_case.scale(3),
            Vector2d(self.negative_case.x * 3, self.negative_case.y * 3),
            "Integer scale fails")

        self.assertEqual(self.zero_case.scale(3),
                         Vector2d(self.zero_case.x * 3, self.zero_case.y * 3),
                         "Integer scale fails")
Beispiel #21
0
    def test_scale_negative_float(self):
        self.assertEqual(
            self.integer_case.scale(-3.5),
            Vector2d(self.integer_case.x * -3.5, self.integer_case.y * -3.5),
            "Integer scale fails")

        self.assertEqual(
            self.float_case.scale(-3.5),
            Vector2d(self.float_case.x * -3.5, self.float_case.y * -3.5),
            "Integer scale fails")

        self.assertEqual(
            self.integer_negative_case.scale(-3.5),
            Vector2d(self.integer_negative_case.x * -3.5,
                     self.integer_negative_case.y * -3.5),
            "Integer scale fails")

        self.assertEqual(
            self.float_negative_case.scale(-3.5),
            Vector2d(self.float_negative_case.x * -3.5,
                     self.float_negative_case.y * -3.5), "Integer scale fails")

        self.assertEqual(
            self.negative_case.scale(-3.5),
            Vector2d(self.negative_case.x * -3.5, self.negative_case.y * -3.5),
            "Integer scale fails")

        self.assertEqual(
            self.zero_case.scale(-3.5),
            Vector2d(self.zero_case.x * -3.5, self.zero_case.y * -3.5),
            "Integer scale fails")
Beispiel #22
0
    def test_add_scaled_vector(self):
        self.assertEqual(
            self.integer_case.add_scaled_vector(self.float_case, -3.25),
            Vector2d(self.integer_case.x + self.float_case.x * -3.25,
                     self.integer_case.y + self.float_case.y * -3.25),
            "Integer scaled addition fails")

        self.assertEqual(
            self.integer_negative_case.add_scaled_vector(
                self.float_negative_case, -3.25),
            Vector2d(
                self.integer_negative_case.x +
                self.float_negative_case.x * -3.25,
                self.integer_negative_case.y +
                self.float_negative_case.y * -3.25),
            "Integer scaled addition fails")

        self.assertEqual(
            self.negative_case.add_scaled_vector(self.zero_case, -3.25),
            Vector2d(self.negative_case.x + self.zero_case.x * -3.25,
                     self.negative_case.y + self.zero_case.y * -3.25),
            "Integer scaled addition fails")
def get_two_inter_points_circle_circle(first_circle: "Circle", second_circle: "Circle") \
  -> List[Vector2d]:
    # https://planetcalc.com/8098/
    r1 = first_circle.radius
    r2 = second_circle.radius
    d = r1 + r2

    center1 = first_circle.center
    center2 = second_circle.center

    a = (r1**2 - r2**2 + d**2) / (2 * d)
    h = math.sqrt(r1**2 - a**2)
    middle_point = center1.add_vector(
        center1.subtract_vector(center2).scale(a / d))

    p1_x = middle_point.x + h / d * (center2.y - center1.y)
    p1_y = middle_point.x - h / d * (center2.x - center1.x)

    p2_x = middle_point.x - h / d * (center2.y - center1.y)
    p2_y = middle_point.x + h / d * (center2.x - center1.x)

    return [Vector2d(p1_x, p1_y), Vector2d(p2_x, p2_y)]
Beispiel #24
0
    def calculate_force(self, attracting_object_pos: Vector2d,
                        obj: BaseNonStaticObject) -> Vector2d:
        current_spring_length = obj.position - attracting_object_pos

        if current_spring_length.get_magnitude() <= self.rest_length:
            return Vector2d(0, 0)

        force_direction = current_spring_length.normalize()

        force_magnitude = current_spring_length.get_magnitude()
        force_magnitude = abs(force_magnitude - self.rest_length)
        force_magnitude *= self.spring_coefficient

        force = force_direction.scale(force_magnitude)
        return force
Beispiel #25
0
def get_ellipse_shape_line_intersection_points(line: Union["Segment", "Line"],
                                               ellipse: Union["Circle", "Ellipse"], get_x_coord_func) -> \
  Optional[List[Vector2d]]:
    inter_points_x_coordinates = get_x_coord_func(line, ellipse)
    if not inter_points_x_coordinates:
        return None

    int_points_y_coordinates = get_y_coordinates_line(
        line, inter_points_x_coordinates)

    points: List[Vector2d] = []
    for x, y in zip(inter_points_x_coordinates, int_points_y_coordinates):
        points.append(Vector2d(x, y))

    for i in range(len(points)):
        if not line.is_point_belongs(points[i]):
            del points[i]

    return points
Beispiel #26
0
    def __init__(self, name: str, force: Vector2d,
                 trigger_object_density: float,
                 trigger_object: BaseNonStaticObject,
                 force_direction: Vector2d,
                 targeted_objects: List[BaseNonStaticObject]) -> None:
        """
        Parameters:
        name (str): name of the force
        force (Vector2d): force that will applied to the objects
        rest_length (float): length of a spring in rest state
        trigger_object (BaseNonStaticObject): object that will trigger force generator if targets
                                              collide with the object
        trigger_object_density (float): density of a pure water is 1000 kg per cubic meter
        targeted_objects (List[BaseNonStaticObject]): objects on which the force will be applied
        all static objects will be omitted
        duration (float): the time that a force will be active
        """

        super().__init__(name, force, targeted_objects)

        self.trigger_object = trigger_object
        self.trigger_object_density = trigger_object_density
        self.force_direction = force_direction.normalize()
class TestObjectComponents(unittest.TestCase):
    
    circle_shape = Circle(Vector2d(0, 0), 1.0)
    polygon_shape = ConvexPolygon([Vector2d(0, 1), Vector2d(1, 1), Vector2d(1, 0), Vector2d(0, 0)])

    _object = Object(circle_shape)

    def test_force_adding(self):
        self._object.add_force(Vector2d(10, 10))

        self.assertEqual(self._object.result_force, Vector2d(10, 10))

        self._object.clear_force()

    def test_force_subtraction(self):
	    self._object.subtract_force(Vector2d(10, 10))

        self.assertEqual(self._object.result_force, Vector2d(-10, -10))

        self._object.clear_force()
Beispiel #28
0
    def test_normalize(self):
        self.assertEqual(
            self.integer_case.normalize(),
            Vector2d(self.integer_case.x / self.integer_case.get_magnitude(),
                     self.integer_case.y / self.integer_case.get_magnitude()),
            "Integer subtraction fails")

        self.assertEqual(
            self.float_case.normalize(),
            Vector2d(self.float_case.x / self.float_case.get_magnitude(),
                     self.float_case.y / self.float_case.get_magnitude()),
            "Integer subtraction fails")

        self.assertEqual(
            self.integer_negative_case.normalize(),
            Vector2d(
                self.integer_negative_case.x /
                self.integer_negative_case.get_magnitude(),
                self.integer_negative_case.y /
                self.integer_negative_case.get_magnitude()),
            "Integer subtraction fails")

        self.assertEqual(
            self.float_negative_case.normalize(),
            Vector2d(
                self.float_negative_case.x /
                self.float_negative_case.get_magnitude(),
                self.float_negative_case.y /
                self.float_negative_case.get_magnitude()),
            "Integer subtraction fails")

        self.assertEqual(
            self.negative_case.normalize(),
            Vector2d(self.negative_case.x / self.negative_case.get_magnitude(),
                     self.negative_case.y /
                     self.negative_case.get_magnitude()),
            "Integer subtraction fails")

        self.assertEqual(self.zero_case.normalize(), Vector2d(0, 0),
                         "Integer subtraction fails")
Beispiel #29
0
def calculator(obj: BaseNonStaticObject, time: float):
    mass = obj.mass

    return Vector2d(1, 1).scale(mass)
Beispiel #30
0
	def cursor_pos_callback(self, window, x_pos, y_pos):
		event = events.mouse_events.MouseMovedEvent(Vector2d(x_pos, y_pos))
		self.events_callback(event)