A class representing a rectangle shape.
| 17 | |
| 18 | |
| 19 | class Rectangle(Shape): |
| 20 | """ |
| 21 | A class representing a rectangle shape. |
| 22 | """ |
| 23 | |
| 24 | def __init__(self, length: float, width: float, yaw: float = 0.0) -> None: |
| 25 | super().__init__() |
| 26 | self._length: float = length |
| 27 | self._width: float = width |
| 28 | self._yaw: float = yaw |
| 29 | |
| 30 | @property |
| 31 | def length(self) -> float: |
| 32 | return self._length |
| 33 | |
| 34 | @property |
| 35 | def width(self) -> float: |
| 36 | return self._width |
| 37 | |
| 38 | @property |
| 39 | def yaw(self) -> float: |
| 40 | return self._yaw |
| 41 | |
| 42 | def get_vertexes(self, center: np.ndarray) -> np.ndarray: |
| 43 | points = np.array([[self.length, self.width], |
| 44 | [-self.length, self.width], |
| 45 | [-self.length, -self.width], |
| 46 | [self.length, -self.width]]) / 2 |
| 47 | rotation = np.array([[np.cos(self.yaw), -np.sin(self.yaw)], |
| 48 | [np.sin(self.yaw), np.cos(self.yaw)]]) |
| 49 | return center + np.array([rotation.dot(point) for point in points]) |
| 50 | |
| 51 | def in_collision(self, self_center: np.ndarray, |
| 52 | other_rectangle: 'Rectangle', |
| 53 | other_center: np.ndarray) -> bool: |
| 54 | """check if two rectangles intersects (in collision) |
| 55 | |
| 56 | Args: |
| 57 | other_rectangle (Rectangle): another rectangle |
| 58 | |
| 59 | Returns: |
| 60 | bool: True if two rectangle intersects, False otherwise |
| 61 | """ |
| 62 | self_vertexes = self.get_vertexes(self_center) |
| 63 | other_vertexes = other_rectangle.get_vertexes(other_center) |
| 64 | |
| 65 | # first use AABB to filter impossible cases |
| 66 | self_x_max, self_y_max = np.max(self_vertexes, axis=0) |
| 67 | self_x_min, self_y_min = np.min(self_vertexes, axis=0) |
| 68 | other_x_max, other_y_max = np.max(other_vertexes, axis=0) |
| 69 | other_x_min, other_y_min = np.min(other_vertexes, axis=0) |
| 70 | |
| 71 | if self_x_max < other_x_min or self_x_min > other_x_max or \ |
| 72 | self_y_max < other_y_min or self_y_min > other_y_max: |
| 73 | return False |
| 74 | |
| 75 | # use separate axis theorem check in-collision or not |
| 76 | return separate_axis_theorem(self_vertexes, other_vertexes) |
no outgoing calls
no test coverage detected