mirror of
https://github.com/gumyr/build123d.git
synced 2025-12-06 02:30:55 -08:00
Add geometry intersection tests. Tighten intersection with Vector from Location and coplanar Planes.
This commit is contained in:
parent
a291a942a1
commit
da1294a390
2 changed files with 91 additions and 19 deletions
|
|
@ -909,15 +909,15 @@ class Axis(metaclass=AxisMeta):
|
|||
"""Find intersection of vector and axis"""
|
||||
|
||||
@overload
|
||||
def intersect(self, location: Location) -> Location | None:
|
||||
def intersect(self, location: Location) -> Vector | Location | None:
|
||||
"""Find intersection of location and axis"""
|
||||
|
||||
@overload
|
||||
def intersect(self, axis: Axis) -> Axis | None:
|
||||
def intersect(self, axis: Axis) -> Vector | Axis | None:
|
||||
"""Find intersection of axis and axis"""
|
||||
|
||||
@overload
|
||||
def intersect(self, plane: Plane) -> Axis | None:
|
||||
def intersect(self, plane: Plane) -> Vector | Axis | None:
|
||||
"""Find intersection of plane and axis"""
|
||||
|
||||
def intersect(self, *args, **kwargs):
|
||||
|
|
@ -965,12 +965,12 @@ class Axis(metaclass=AxisMeta):
|
|||
# Find the "direction" of the location
|
||||
location_dir = Plane(location).z_dir
|
||||
|
||||
# Is the location on the axis with the same direction?
|
||||
if (
|
||||
self.intersect(location.position) is not None
|
||||
and location_dir == self.direction
|
||||
):
|
||||
return location
|
||||
if self.intersect(location.position) is not None:
|
||||
# Is the location on the axis with the same direction?
|
||||
if location_dir == self.direction:
|
||||
return location
|
||||
else:
|
||||
return location.position
|
||||
|
||||
if shape is not None:
|
||||
return shape.intersect(self)
|
||||
|
|
@ -1932,15 +1932,15 @@ class Location:
|
|||
"""Find intersection of vector and location"""
|
||||
|
||||
@overload
|
||||
def intersect(self, location: Location) -> Location | None:
|
||||
def intersect(self, location: Location) -> Vector | Location | None:
|
||||
"""Find intersection of location and location"""
|
||||
|
||||
@overload
|
||||
def intersect(self, axis: Axis) -> Location | None:
|
||||
def intersect(self, axis: Axis) -> Vector | Location | None:
|
||||
"""Find intersection of axis and location"""
|
||||
|
||||
@overload
|
||||
def intersect(self, plane: Plane) -> Location | None:
|
||||
def intersect(self, plane: Plane) -> Vector | Location | None:
|
||||
"""Find intersection of plane and location"""
|
||||
|
||||
def intersect(self, *args, **kwargs):
|
||||
|
|
@ -1956,8 +1956,11 @@ class Location:
|
|||
if vector is not None and self.position == vector:
|
||||
return vector
|
||||
|
||||
if location is not None and self == location:
|
||||
return self
|
||||
if location is not None:
|
||||
if self == location:
|
||||
return self
|
||||
elif self.position == location.position:
|
||||
return self.position
|
||||
|
||||
if shape is not None:
|
||||
return shape.intersect(self)
|
||||
|
|
@ -3131,15 +3134,15 @@ class Plane(metaclass=PlaneMeta):
|
|||
"""Find intersection of vector and plane"""
|
||||
|
||||
@overload
|
||||
def intersect(self, location: Location) -> Location | None:
|
||||
def intersect(self, location: Location) -> Vector | Location | None:
|
||||
"""Find intersection of location and plane"""
|
||||
|
||||
@overload
|
||||
def intersect(self, axis: Axis) -> Axis | Vector | None:
|
||||
def intersect(self, axis: Axis) -> Vector | Axis | None:
|
||||
"""Find intersection of axis and plane"""
|
||||
|
||||
@overload
|
||||
def intersect(self, plane: Plane) -> Axis | None:
|
||||
def intersect(self, plane: Plane) -> Axis | Plane | None:
|
||||
"""Find intersection of plane and plane"""
|
||||
|
||||
@overload
|
||||
|
|
@ -3172,6 +3175,9 @@ class Plane(metaclass=PlaneMeta):
|
|||
return intersection_point
|
||||
|
||||
if plane is not None:
|
||||
if self.contains(plane.origin) and self.z_dir == plane.z_dir:
|
||||
return self
|
||||
|
||||
surface1 = Geom_Plane(self.wrapped)
|
||||
surface2 = Geom_Plane(plane.wrapped)
|
||||
intersector = GeomAPI_IntSS(surface1, surface2, TOLERANCE)
|
||||
|
|
@ -3187,8 +3193,11 @@ class Plane(metaclass=PlaneMeta):
|
|||
|
||||
if location is not None:
|
||||
pln = Plane(location)
|
||||
if pln.origin == self.origin and pln.z_dir == self.z_dir:
|
||||
return location
|
||||
if self.contains(pln.origin):
|
||||
if self.z_dir == pln.z_dir:
|
||||
return location
|
||||
else:
|
||||
return pln.origin
|
||||
|
||||
if shape is not None:
|
||||
return shape.intersect(self)
|
||||
|
|
|
|||
|
|
@ -59,6 +59,69 @@ def make_params(matrix):
|
|||
return params
|
||||
|
||||
|
||||
# Geometric test objects
|
||||
ax1 = Axis.X
|
||||
ax2 = Axis.Y
|
||||
ax3 = Axis((0, 0, 5), (1, 0, 0))
|
||||
pl1 = Plane.YZ
|
||||
pl2 = Plane.XY
|
||||
pl3 = Plane.XY.offset(5)
|
||||
pl4 = Plane((0, 5, 0))
|
||||
vl1 = Vector(2, 0, 0)
|
||||
vl2 = Vector(2, 0, 5)
|
||||
lc1 = Location((2, 0, 0))
|
||||
lc2 = Location((2, 0, 5))
|
||||
lc3 = Location((0, 0, 0), (0, 90, 90))
|
||||
lc4 = Location((2, 0, 0), (0, 90, 90))
|
||||
|
||||
# Geometric test matrix
|
||||
geometry_matrix = [
|
||||
Case(ax1, ax3, None, "parallel/skew", None),
|
||||
Case(ax1, ax1, Axis, "collinear", None),
|
||||
Case(ax1, ax2, Vector, "intersecting", None),
|
||||
|
||||
Case(ax1, pl3, None, "parallel", None),
|
||||
Case(ax1, pl2, Axis, "coplanar", None),
|
||||
Case(ax1, pl1, Vector, "intersecting", None),
|
||||
|
||||
Case(ax1, vl2, None, "non-coincident", None),
|
||||
Case(ax1, vl1, Vector, "coincident", None),
|
||||
|
||||
Case(ax1, lc2, None, "non-coincident", None),
|
||||
Case(ax1, lc4, Location, "intersecting, co-z", None),
|
||||
Case(ax1, lc1, Vector, "intersecting", None),
|
||||
|
||||
Case(pl2, pl3, None, "parallel", None),
|
||||
Case(pl2, pl4, Plane, "coplanar", None),
|
||||
Case(pl1, pl2, Axis, "intersecting", None),
|
||||
|
||||
Case(pl3, ax1, None, "parallel", None),
|
||||
Case(pl2, ax1, Axis, "coplanar", None),
|
||||
Case(pl1, ax1, Vector, "intersecting", None),
|
||||
|
||||
Case(pl1, vl2, None, "non-coincident", None),
|
||||
Case(pl2, vl1, Vector, "coincident", None),
|
||||
|
||||
Case(pl1, lc2, None, "non-coincident", None),
|
||||
Case(pl1, lc3, Location, "intersecting, co-z", None),
|
||||
Case(pl2, lc4, Vector, "coincident", None),
|
||||
|
||||
Case(vl1, vl2, None, "non-coincident", None),
|
||||
Case(vl1, vl1, Vector, "coincident", None),
|
||||
|
||||
Case(vl1, lc2, None, "non-coincident", None),
|
||||
Case(vl1, lc1, Vector, "coincident", None),
|
||||
|
||||
Case(lc1, lc2, None, "non-coincident", None),
|
||||
Case(lc1, lc4, Vector, "coincident", None),
|
||||
Case(lc1, lc1, Location, "coincident, co-z", None),
|
||||
]
|
||||
|
||||
@pytest.mark.parametrize("obj, target, expected", make_params(geometry_matrix))
|
||||
def test_geometry(obj, target, expected):
|
||||
run_test(obj, target, expected)
|
||||
|
||||
|
||||
# FreeCAD issue example
|
||||
c1 = CenterArc((0, 0), 10, 0, 360).edge()
|
||||
c2 = CenterArc((19, 0), 10, 0, 360).edge()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue