Source code for marxs.math.pluecker

# Licensed under GPL version 3 - see LICENSE.rst
'''This module collects routines that deal with lines in Pluecker coordiantes incl. the
construction of the Pluecker coordinates from e.g. two points in space or a direction and
a point.
'''
import numpy as np

[docs] def angle_line_plane(p_line, h_plane): '''Compute angle between normal to plane and line Parameters ---------- p_line : array-like Line(s) in Pluecker coordinates h_plane : array-like Plane in homogeneous coordinates Returns ------- angle : array-like ''' l = p_line[:3] p = h_plane[:3] return np.arccos(np.dot(l, p) / (np.linalg.norm(l) * np.linalg.norm(p)))
# @ L = {U:V}, with 3-tuples U and V, with U.V = 0, and with U non-null.
[docs] def e_pointpoint2line(e_p1, e_p2): '''Return a line in Pluecker coordinates connecting two points. p1, p2 are distinct point on line, direction is p1 -> p2 Parameters ---------- e_p1, e_p2: array_like Array of Eucledian positions Returns ------- p_line : array-like Lines in Pluecker coordinates ''' p_line = np.empty(e_p1.shape[:-1] + (6,) ) p_line[..., :3] = e_p2 - e_p1 p_line[..., 3:] = np.cross(e_p2, e_p1) return p_line
[docs] def dir_point2line(e_dir, e_pos): '''Return a line in Pluecker coordinates connecting two points. p1, p2 are distinct point on line, direction is p1 -> p2 Parameters ---------- e_dir: array_like Array of Euclidean direction vectors e_point : array-like Array of points in eukledian coordinates Returns ------- p_line : array-like Lines in Pluecker coordinates ''' p_line = np.empty(e_dir.shape[:-1] + (6,) ) p_line[..., :3] = e_dir p_line[..., 3:] = np.cross(e_dir, e_pos) return p_line
[docs] def intersect_line_plane(p_line, h_plane): '''Intersect a line in Pluecker coordinates with a plane in homogeneous coordinates. This function returns the position of the intersection. If the line is parallel (but not identical) to the plane that intersection happens "at infinity" and thus the last component of the intersection coordinate is 0. If the line is in the plane, then all components of the return vector are 0. Parameters ---------- p_line : np.array (last dimension has 6 elements) Pluecker coordinates of a line or an array of lines h_plane : np.array with ``shape=(4, )`` Homogeneous coordinates of a plane. Returns ------- h_point : np.array Homogeneous coordinates of the intersection points of line and plane. Has the same shape as ``p_line``, but the last dimension has only 4 elements. ''' h_point = np.empty(p_line.shape[:-1] + (4,) ) h_point[..., :3] = np.cross(p_line[..., 3:], h_plane[:3]) - p_line[..., :3] * h_plane[3] h_point[..., 3] = np.dot(p_line[..., :3], h_plane[:3]) return h_point
[docs] def point_dir2plane(h_point, h_dir): '''Return a plane in homogeneous coordinates Parameters ---------- h_point : array-like Point in plane in homogeneous coordinates h_dir: array_like Normal vector of plane in homogeneous coordinates Returns ------- p_line : array-like Lines in Pluecker coordinates ''' h_plane = np.empty(4) h_dir_n = h_dir / np.linalg.norm(h_dir) h_plane[:3] = h_dir_n[:3] h_plane[3] = - np.dot(h_point, h_dir_n) / h_point[3] return h_plane
# @ L = {U:UxQ}, for U the direction of L and Q a point on L. # @ L = {qP-pQ:PxQ}, for (P:p) and (Q:q) distinct homogeneous points on L. # @ L = {ExF:fE-eF}, for [E:e] and [F:f] distinct planes containing L. # @ {U1:V1} =? s{U2:V2} tests if L1 = {U1:V1} equals L2 = {U2:V2}. # @ s > 0 if L1 and L2 have same orientation. # @ (V.V)/(U.U) is the minimum squared distance of L from the origin. # @ (VxU:U.U) is the point of L closest to the origin. # @ [UxV:V.V] is the plane through L perpendicular to its origin plane, for # non-null V. # @ (VxN-Un:U.N) is the point where L intersects plane [N:n] not parallel to L. # @ [UxP-Vw:V.P] is the plane containing L and point (P:w) not on L. # @ [UxN:V.N] is the plane containing L and direction N not parallel to L. # Let N, N1, N2 be unit vectors along the coordinate axes, with U.N non-zero. # @ (VxN:U.N) is a point on L if N is not perpendicular to U. # @ U and this point both satisfy a plane equation [E:e] if the plane # contains L. # @ Represent L as U and this point to transform by non-perspective # homogeneous matrix. # @ Represent L as two points to transform by perspective homogeneous matrix. # @ [UxN1:V.N1] and [UxN2:V.N2] are distinct planes containing L. # @ P satisfies both these plane equations if L contains P. # @ Pnt(t) = (VxU+tU:U.U) parameterizes points on L. # @ Pln(t) = (1-t^2)[UxN1:V.N1]+2t[UxN2:V.N2] parameterizes planes through L. # @ U1.V2 + U2.V1 =? 0 tests if L1 = {U1:V1} and L2 = {U2:V2} are coplanar # (intersect). # @ Sum positive if right-handed screw takes one into the other; negative # if left-handed. # @ U1xU2 =? 0 tests if lines are parallel. # Let N be a unit vector along a coordinate axis, with (U1xU2).N non-zero. # @ ((V1.N)U2-(V2.N)U1-(V1.U2)N:(U1xU2).N) is the point of intersection, if # any. # @ [U1xU2:V1.U2] is the common plane for non-parallel lines. # Let N, N1, N2 be unit vectors along the coordinate axes, with U1.N non-zero. # @ [(U1.N)V2-(U2.N)V1:(V1xV2).N] is the common plane for parallel distinct # lines. # @ [U1xN1:V1.N1] is the common plane for equal lines through origin. # Here are two related tricks, a lagniappe, as they say in New Orleans. # Let P be the point (x,y,z). # @ [(-1,0,0):x] and [(0,-1,0):y] and [(0,0,-1):z] are independent planes # through P. # Let [E:e] be a plane and N, N1, and N2 unit coordinate axis vectors with # E.N non-null. # @ Point (-eN:E.N) and distinct direction vectors ExN1 and ExN2 lie in the # plane.