A simple rectangle representation length w ---------------------------- i - - d - center - t - - h ---------------------------- yaw is in radians and in anti-clockwise direction
| 81 | |
| 82 | @dataclass |
| 83 | class Rectangle: |
| 84 | """A simple rectangle representation |
| 85 | |
| 86 | length |
| 87 | w ---------------------------- |
| 88 | i - - |
| 89 | d - center - |
| 90 | t - - |
| 91 | h ---------------------------- |
| 92 | yaw is in radians and in anti-clockwise direction |
| 93 | """ |
| 94 | center: np.ndarray |
| 95 | width: float |
| 96 | length: float |
| 97 | yaw: float |
| 98 | |
| 99 | def __repr__(self) -> str: |
| 100 | return f"center={self.center}, width={self.width}, length={self.length}, yaw={self.yaw}" |
| 101 | |
| 102 | def corners(self) -> np.ndarray: |
| 103 | """Get the coordinates of corners of a rectangle |
| 104 | |
| 105 | Returns: |
| 106 | List[np.ndarray]: an array of shape (4, 2) |
| 107 | each of them represents the coordinate of a corner |
| 108 | """ |
| 109 | points = np.array([[self.length, self.width], [ |
| 110 | -self.length, self.width |
| 111 | ], [-self.length, -self.width], [self.length, -self.width]]) / 2 |
| 112 | rotation = np.array([[np.cos(self.yaw), -np.sin(self.yaw)], |
| 113 | [np.sin(self.yaw), |
| 114 | np.cos(self.yaw)]]) |
| 115 | return self.center + np.array( |
| 116 | [rotation.dot(point) for point in points]) |
| 117 | |
| 118 | def in_collision(self, other_rectangle: 'Rectangle') -> bool: |
| 119 | """check if two rectangles intersects (in collision) |
| 120 | |
| 121 | Args: |
| 122 | other_rectangle (Rectangle): another rectangle |
| 123 | |
| 124 | Returns: |
| 125 | bool: True if two rectangle intersects, False otherwise |
| 126 | """ |
| 127 | self_corners = self.corners() |
| 128 | other_corners = other_rectangle.corners() |
| 129 | |
| 130 | # first use AABB to filter impossible cases |
| 131 | self_x_max, self_y_max = np.max(self_corners, axis=0) |
| 132 | self_x_min, self_y_min = np.min(self_corners, axis=0) |
| 133 | other_x_max, other_y_max = np.max(other_corners, axis=0) |
| 134 | other_x_min, other_y_min = np.min(other_corners, axis=0) |
| 135 | |
| 136 | if self_x_max < other_x_min or self_x_min > other_x_max or \ |
| 137 | self_y_max < other_y_min or self_y_min > other_y_max: |
| 138 | return False |
| 139 | |
| 140 | # use separate axis theorem check in-collision or not |
no outgoing calls
no test coverage detected