Normalize quadrilateral to canvas geometry.
(self, polygon: list[tuple[float, float]])
| 31 | self.uniform_scale = min(self.scale_x, self.scale_y) |
| 32 | |
| 33 | def normalize_polygon(self, polygon: list[tuple[float, float]]) -> NormalizedCoords: |
| 34 | """Normalize quadrilateral to canvas geometry.""" |
| 35 | if len(polygon) < 4: |
| 36 | return NormalizedCoords(0, 0, 0, 0, 0, 0) |
| 37 | |
| 38 | # 缩放坐标 |
| 39 | normalized_points = [ |
| 40 | (p[0] * self.uniform_scale, p[1] * self.uniform_scale) |
| 41 | for p in polygon |
| 42 | ] |
| 43 | |
| 44 | p0, p1, p2, p3 = normalized_points[:4] |
| 45 | rotation = self._calculate_rotation(p0, p1) |
| 46 | center_x = sum(p[0] for p in normalized_points) / 4 |
| 47 | center_y = sum(p[1] for p in normalized_points) / 4 |
| 48 | edge_top = math.sqrt((p1[0] - p0[0])**2 + (p1[1] - p0[1])**2) |
| 49 | edge_left = math.sqrt((p3[0] - p0[0])**2 + (p3[1] - p0[1])**2) |
| 50 | is_vertical = abs(abs(rotation) - 90) < 15 |
| 51 | |
| 52 | if is_vertical: |
| 53 | width = edge_top |
| 54 | height = edge_left |
| 55 | else: |
| 56 | width = edge_top |
| 57 | height = edge_left |
| 58 | |
| 59 | # 计算左上角坐标(draw.io 从左上角定位) |
| 60 | x = center_x - width / 2 |
| 61 | y = center_y - height / 2 |
| 62 | |
| 63 | # 计算基线位置 |
| 64 | baseline_y = (p2[1] + p3[1]) / 2 |
| 65 | |
| 66 | return NormalizedCoords( |
| 67 | x=x, y=y, width=width, height=height, |
| 68 | baseline_y=baseline_y, rotation=rotation |
| 69 | ) |
| 70 | |
| 71 | def _calculate_rotation(self, p0: tuple, p1: tuple) -> float: |
| 72 | """ |
no test coverage detected