double R3Distance(const R3Point& point, const R3Line& line) { // Return distance from point to line (Riddle p. 904) R3Vector v = line.Vector(); v.Cross(point - line.Point()); return v.Length(); }
double R3Distance(const R3Line& line1, const R3Line& line2) { // Return distance from line to line (Riddle p. 905) R3Vector v = line1.Vector(); v.Cross(line2.Vector()); return v.Dot(line1.Point() - line2.Point()); }
R3Plane:: R3Plane(const R3Point& point, const R3Line& line) { // Construct plane through point and line v = point - line.Point(); v.Cross(line.Vector()); v.Normalize(); d = -(v[0]*point[0] + v[1]*point[1] + v[2]*point[2]); }
void R3Point:: Project(const R3Line& line) { // Move point to closest point on line const R3Point *p = &(line.Point()); const R3Vector *v = &(line.Vector()); RNScalar denom = v->Dot(*v); assert(denom != 0); RNScalar t = (v->X() * (X() - p->X()) + v->Y() *(Y() - p->Y()) + v->Z() * (Z() - p->Z())) / denom; *this = *p + *v * t; }
double R3SignedDistance(const R3Plane& plane, const R3Line& line) { // Return signed distance from plane to line if (plane.Normal().Dot(line.Vector()) == 0) { // Plane and line are parallel return R3SignedDistance(plane, line.Point()); } else { // Plane and line are not parallel return 0.0; } }
void R3Point:: Rotate(const R3Line& axis, RNAngle theta) { // Translate axis to origin R3Vector v = *this - axis.Point(); // Rotate point counterclockwise around axis through origin by radians ??? v.Rotate(axis.Vector(), theta); // Translate axis back from origin *this = axis.Point() + v; }
RNBoolean R3Parallel(const R3Line& line, const R3Ray& ray) { // Return whether line and ray are parallel return R3Parallel(line.Vector(), ray.Vector()); }
RNBoolean R3Parallel(const R3Line& line1, const R3Line& line2) { // Return whether line1 and line2 are parallel return R3Parallel(line1.Vector(), line2.Vector()); }
RNBoolean R3Parallel(const R3Vector& vector, const R3Line& line) { // Return whether vector and line are parallel return R3Parallel(vector, line.Vector()); }
RNBoolean R3Perpendicular(const R3Line& line, const R3Span& span) { // Return whether line and span are perpendicular return R3Perpendicular(line.Vector(), span.Vector()); }
RNBoolean R3Perpendicular(const R3Line& line, const R3Ray& ray) { // Return whether line and ray are perpendicular return R3Perpendicular(line.Vector(), ray.Vector()); }
RNBoolean R3Perpendicular(const R3Line& line1, const R3Line& line2) { // Return whether line1 and line2 are perpendicular return R3Perpendicular(line1.Vector(), line2.Vector()); }
RNBoolean R3Contains(const R3Halfspace& halfspace, const R3Line& line) { // Return whether halfspace contains line return (R3Parallel(halfspace.Plane(), line) && R3Contains(halfspace, line.Point())); }
RNBoolean R3Contains(const R3Plane& plane, const R3Line& line) { // Return whether plane contains line return (R3Parallel(plane, line) && R3Contains(plane, line.Point())); }
RNBoolean R3Contains(const R3Line& line1, const R3Line& line2) { // Return whether two lines are equal within tolerance return (R3Contains(line1.Vector(), line2.Vector()) && R3Contains(line1, line2.Point())); }
RNBoolean R3Parallel(const R3Line& line, const R3Span& span) { // Return whether line and span are parallel return R3Parallel(line.Vector(), span.Vector()); }
RNBoolean R3Parallel(const R3Line& line, const R3Plane& plane) { // Return whether line and plane are parallel return R3Perpendicular(line.Vector(), plane.Normal()); }
RNBoolean R3Perpendicular(const R3Vector& vector, const R3Line& line) { // Return whether vector and line are perpendicular return R3Perpendicular(vector, line.Vector()); }