Skip to content

Commit

Permalink
fix(plane): Add method to project points onto planes
Browse files Browse the repository at this point in the history
  • Loading branch information
chriswmackey authored and Chris Mackey committed Feb 16, 2023
1 parent 312eb21 commit 4c35972
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 3 deletions.
22 changes: 20 additions & 2 deletions ladybug_geometry/geometry3d/plane.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@

from .pointvector import Point3D, Vector3D
from .ray import Ray3D
from ..intersection3d import intersect_line3d_plane, intersect_plane_plane, \
closest_point3d_on_plane, closest_point3d_between_line3d_plane
from ..intersection3d import intersect_line3d_plane, intersect_line3d_plane_infinite, \
intersect_plane_plane, closest_point3d_on_plane, \
closest_point3d_between_line3d_plane
from ..geometry2d.pointvector import Point2D, Vector2D
from ..geometry2d.ray import Ray2D

Expand Down Expand Up @@ -319,6 +320,23 @@ def distance_to_line(self, line_ray):
else:
return result[0].distance_to_point(result[1])

def project_point(self, point, projection_direction=None):
"""Project a point onto this Plane given a certain projection direction.
Args:
point: A Point3D to be projected onto the plane
projection_direction: A Line3D or Ray3D object to set the direction
of projection. If None, this Plane's normal will be
used. (Default: None).
Returns:
Point3D for the projected point. Will be None if the projection_direction
is parallel to the plane.
"""
int_ray = Ray3D(point, self.n) if projection_direction is None \
else Ray3D(point, projection_direction)
return intersect_line3d_plane_infinite(int_ray, self)

def intersect_line_ray(self, line_ray):
"""Get the intersection between this plane and the input Line3D or Ray3D.
Expand Down
22 changes: 21 additions & 1 deletion ladybug_geometry/intersection3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def intersect_line3d_plane(line_ray, plane):
plane: A Plane object to intersect.
Returns:
Point2D of intersection if it exists. None if no intersection exists.
Point3D of intersection if it exists. None if no intersection exists.
"""
d = plane.n.dot(line_ray.v)
if not d: # parallel
Expand All @@ -28,6 +28,26 @@ def intersect_line3d_plane(line_ray, plane):
line_ray.p.z + u * line_ray.v.z)


def intersect_line3d_plane_infinite(line_ray, plane):
"""Get the intersection between a Plane and Ray2D/LineSegment2D extended infinitely.
Args:
line_ray: ALineSegment2D or Ray2D that will be extended infinitely
for intersection.
plane: A Plane object to intersect.
Returns:
Point3D of intersection if it exists. None if no intersection exists.
"""
d = plane.n.dot(line_ray.v)
if not d: # parallel
return None
u = (plane.k - plane.n.dot(line_ray.p)) / d
return Point3D(line_ray.p.x + u * line_ray.v.x,
line_ray.p.y + u * line_ray.v.y,
line_ray.p.z + u * line_ray.v.z)


def intersect_plane_plane(plane_a, plane_b):
"""Get the intersection between two Plane objects.
Expand Down

0 comments on commit 4c35972

Please sign in to comment.