Merge pull request #10735 from Roy-043/Draft-Add-distance_to_plane-and-project_point_on_plane-to-geometry.py

Draft: Add distance_to_plane and project_point_on_plane to geometry.py
This commit is contained in:
Yorik van Havre
2023-09-21 11:11:44 +02:00
committed by GitHub
2 changed files with 84 additions and 9 deletions

View File

@@ -81,7 +81,9 @@ from draftgeoutils.geometry import (findPerpendicular,
mirror_matrix,
uv_vectors_from_face,
placement_from_face,
placement_from_points)
placement_from_points,
distance_to_plane,
project_point_on_plane)
from draftgeoutils.edges import (findEdge,
orientEdge,

View File

@@ -529,8 +529,8 @@ def mirror_matrix(mtx, pos, nor):
nor: Base::Vector3
Normal of mirror plane.
Return
------
Returns
-------
Base::Matrix
"""
# Code by Jolbas:
@@ -563,8 +563,8 @@ def uv_vectors_from_face(face, vec_z=App.Vector(0, 0, 1), tol=-1):
Defaults to -1.
Internal tolerance. 1e-7 is used if tol <=0.
Return
------
Returns
-------
tuple
U and v vector (Base::Vector3).
"""
@@ -608,8 +608,8 @@ def placement_from_face(face, vec_z=App.Vector(0, 0, 1), rotated=False, tol=-1):
Defaults to -1.
Internal tolerance. 1e-7 is used if tol <=0.
Return
------
Returns
-------
Base::Placement
See also
@@ -645,8 +645,8 @@ def placement_from_points(pt_pos, pt_x, pt_y, as_vectors=False, tol=-1):
Defaults to -1.
Internal tolerance. 1e-7 is used if tol <=0.
Return
------
Returns
-------
Base::Placement
See also
@@ -675,6 +675,79 @@ def placement_from_points(pt_pos, pt_x, pt_y, as_vectors=False, tol=-1):
return App.Placement(pt_pos, rot)
# Code separated from WorkingPlane.py (offsetToPoint function).
# Note that the return value of this function has the opposite sign.
def distance_to_plane(point, base, normal):
"""Return the signed distance from a plane to a point.
The distance is positive if the point lies on the +normal side of the plane.
Parameters
----------
point: Base::Vector3
Point to project.
base: Base::Vector3
Point on plane.
normal: Base::Vector3
Normal of plane.
Returns
-------
float
"""
return (point - base).dot(normal)
# Code separated from WorkingPlane.py (projectPoint function).
# See: https://github.com/FreeCAD/FreeCAD/pull/5307
def project_point_on_plane(point, base, normal, direction=None, force_projection=False, tol=-1):
"""Project a point onto a plane.
Parameters
----------
point: Base::Vector3
Point to project.
base: Base::Vector3
Point on plane.
normal: Base::Vector3
Normal of plane.
direction: Base::Vector3, optional
Defaults to `None` in which case the normal is used.
Direction of projection.
force_projection: Bool, optional
Defaults to `False`.
If `True` forces the projection if the deviation between the direction
and the normal is less than tol from the orthogonality. The direction
of projection is then modified to a tol deviation between the direction
and the orthogonal.
tol: float, optional
Defaults to -1.
Internal tolerance. 1e-7 is used if tol <=0.
Returns
-------
Base::Vector3 or `None`
"""
err = 1e-7 if tol <= 0 else tol
normal = App.Vector(normal).normalize()
if direction is None:
direction = normal
else:
direction = App.Vector(direction).normalize()
cos = direction.dot(normal)
delta_ax_proj = (point - base).dot(normal)
# check the only conflicting case: direction orthogonal to normal
if abs(cos) < err:
if force_projection:
cos = math.copysign(err, delta_ax_proj)
direction = normal.cross(direction).cross(normal) - cos * normal
else:
return None
return point - delta_ax_proj / cos * direction
#compatibility layer
getSplineNormal = get_spline_normal