M_Rectangle3 M_RectangleFromPts3(M_Vector3 a, M_Vector3 b, M_Vector3 c) { M_Rectangle3 R; M_Vector3 d; M_Plane3 P; P = M_PlaneFromPts3(a, b, c); d.x = a.x; d.y = c.y; d.z = -(P.a*d.x + P.b*d.y + P.d)/P.d; R.a = M_LineFromPts3(a, b); R.b = M_LineFromPts3(b, c); R.c = M_LineFromPts3(c, d); R.d = M_LineFromPts3(d, a); return (R); }
/* * Compute a new line parallel to the given line, with perpendicular * endpoints. XXX this is a circle of solutions in R3 */ M_Line3 M_LineParallel3(M_Line3 L, M_Real dist) { M_Vector3 p1, p2, pd; M_LineToPts3(L, &p1, &p2); pd.x = L.d.y; pd.y = -L.d.x; M_VecScale3v(&pd, dist); M_VecAdd3v(&p1, &pd); M_VecAdd3v(&p2, &pd); return M_LineFromPts3(p1, p2); }
/* * Compute the shortest line segment connecting two lines in R^3. * Adapted from Paul Bourke's example code: * http://paulbourke.net/geometry/lineline3d */ int M_LineLineShortest3(M_Line3 L1, M_Line3 L2, M_Line3 *Ls) { M_Vector3 p1 = M_LineInitPt3(L1); M_Vector3 p2 = M_LineTermPt3(L1); M_Vector3 p3 = M_LineInitPt3(L2); M_Vector3 p4 = M_LineTermPt3(L2); M_Vector3 p13, p43, p21; M_Real d1343, d4321, d1321, d4343, d2121; M_Real numer, denom; M_Real muA, muB; p13 = M_VecSub3(p1, p3); p43 = M_VecSub3(p4, p3); if (Fabs(p43.x) < M_MACHEP && Fabs(p43.y) < M_MACHEP && Fabs(p43.z) < M_MACHEP) return (0); p21 = M_VecSub3(p2, p1); if (Fabs(p21.x) < M_MACHEP && Fabs(p21.y) < M_MACHEP && Fabs(p21.z) < M_MACHEP) return (0); d1343 = M_VecDot3p(&p13, &p43); d4321 = M_VecDot3p(&p43, &p21); d4343 = M_VecDot3p(&p43, &p43); d2121 = M_VecDot3p(&p21, &p21); denom = d2121*d4343 - d4321*d4321; if (Fabs(denom) < M_MACHEP) { return (0); } numer = d1343*d4321 - d1321*d4343; muA = numer/denom; muB = (d1343 + d4321*muA) / d4343; if (Ls != NULL) { *Ls = M_LineFromPts3( M_VecAdd3(p1, M_VecScale3(p21,muA)), M_VecAdd3(p3, M_VecScale3(p43,muB))); } return (1); }