Add PolygonShape.split_to_convex (polygon to convex tiles)
Ports geometry/planar/Polygon.java (corner de-duplication and collinear removal, winding number) and PolygonShape.java, including the recursive split_to_convex that decomposes a simple polygon into convex Simplex tiles by dividing at concave corners along minimal axis-parallel lines. Orientation and convexity tests are exact; the division-point search is approximate (float line evaluation, split point rounded to an integer corner) as upstream. The concave-corner search starts deterministically at corner 0 rather than a seeded PRNG; this only affects which valid decomposition is produced. Supporting additions: Simplex.from_corners (convex polygon to simplex) and Line.function_value_approx / function_in_y_value_approx. Invariant tests over L, plus, staircase and square polygons: tile areas sum to the polygon area (no gaps, no overlap), a point is in the polygon iff in some tile, and no point is strictly inside more than one tile (interiors disjoint). Also covers Polygon normalization and orientation.
This commit is contained in:
@@ -198,6 +198,28 @@ class Line:
|
||||
result = self.side_of(line_1.intersection(line_2))
|
||||
return result
|
||||
|
||||
def function_value_approx(self, x: float) -> float:
|
||||
"""Approximate ``y`` on this (non-vertical) line at abscissa ``x``."""
|
||||
p1 = self.a.to_float()
|
||||
p2 = self.b.to_float()
|
||||
dx = p2.x - p1.x
|
||||
if dx == 0:
|
||||
return 0.0
|
||||
dy = p2.y - p1.y
|
||||
det = p1.x * p2.y - p2.x * p1.y
|
||||
return (dy * x - det) / dx
|
||||
|
||||
def function_in_y_value_approx(self, y: float) -> float:
|
||||
"""Approximate ``x`` on this (non-horizontal) line at ordinate ``y``."""
|
||||
p1 = self.a.to_float()
|
||||
p2 = self.b.to_float()
|
||||
dy = p2.y - p1.y
|
||||
if dy == 0:
|
||||
return 0.0
|
||||
dx = p2.x - p1.x
|
||||
det = p1.x * p2.y - p2.x * p1.y
|
||||
return (dx * y + det) / dy
|
||||
|
||||
# --- intersection (exact) ----------------------------------------------
|
||||
|
||||
def intersection(self, other: Line) -> Point:
|
||||
|
||||
Reference in New Issue
Block a user