RNLength R2SignedDistance(const R2Line& line, const R2Box& box) { // Return signed distance from line to box RNQuadrant quadrant = line.Normal().Quadrant(); RNScalar d1 = R2SignedDistance(line, box.Corner(~quadrant & 0x3)); if (RNIsPositiveOrZero(d1)) return d1; RNScalar d2 = R2SignedDistance(line, box.Corner(quadrant)); if (RNIsNegative(d2)) return d2; else return 0.0; }
void R2Point:: Mirror(const R2Line& line) { // Mirror point across line double d = R2SignedDistance(*this, line); *this += line.Normal() * (-2.0 * d); }
RNLength R2Distance(const R2Point& point, const R2Halfspace& halfspace) { // Return distance from point to halfspace RNScalar d = R2SignedDistance(halfspace.Line(), point); if (RNIsNegative(d)) return -d; else return 0.0; }
RNLength R2Distance(const R2Span& span, const R2Halfspace& halfspace) { // Return distance from span to halfspace RNScalar d = R2SignedDistance(halfspace.Line(), span); if (RNIsNegative(d)) return -d; else return 0.0; }
RNLength R2Distance(const R2Ray& ray, const R2Halfspace& halfspace) { // Return distance from ray to halfspace RNScalar d = R2SignedDistance(halfspace.Line(), ray); if (RNIsNegative(d)) return -d; else return 0.0; }
RNLength R2Distance(const R2Line& line, const R2Span& span) { // Return distance from span to line RNScalar d = R2SignedDistance(line, span); if (RNIsPositive(d)) return d; else if (RNIsNegative(d)) return -d; else return 0.0; }
RNLength R2Distance(const R2Point& point, const R2Arc& arc) { // Figure sector - positive ds are inside arc sector RNLength d1 = R2SignedDistance(R2Line(arc.StartPoint(), arc.Center()), point); RNLength d2 = R2SignedDistance(R2Line(arc.Center(), arc.StopPoint()), point); if (d1 > 0.0) { if (d2 > 0.0) { // Point is in arc sector RNLength d = R2Distance(arc.Center(), point) - arc.Radius(); return (d < 0) ? -d : d; } else { // Point may be in arc sector if (arc.SweepAngle() > RN_PI) { // Point is in arc sector RNLength d = R2Distance(arc.Center(), point) - arc.Radius(); return (d < 0) ? -d : d; } else { // Point is closest to stop point return R2Distance(arc.StopPoint(), point); } } } else { if (d2 > 0.0) { // Point may be in arc sector if (arc.SweepAngle() > RN_PI) { // Point is in arc sector RNLength d = R2Distance(arc.Center(), point) - arc.Radius(); return (d < 0) ? -d : d; } else { // Point is closest to start point return R2Distance(arc.StartPoint(), point); } } else { // Point is outside arc sector RNLength d = R2Distance(arc.Center(), point) - arc.Radius(); return (d < 0) ? -d : d; } } }
RNLength R2SignedDistance(const R2Line& line, const R2Span& span) { // Return signed distance from line to span RNLength d1 = R2SignedDistance(line, span.Start()); if (RNIsPositive(d1)) { // Start point is above line RNLength d2 = R2SignedDistance(line, span.End()); if (RNIsPositive(d2)) return ((d1 > d2) ? d2 : d1); else return 0.0; } else if (RNIsNegative(d1)) { // Start point is below line RNLength d2 = R2SignedDistance(line, span.End()); if (RNIsNegative(d2)) return ((d1 > d2) ? d1 : d2); else return 0.0; } else { // Start point is on line return 0.0; } }
RNLength R2SignedDistance(const R2Line& line, const R2Circle& circle) { RNLength d = R2SignedDistance(line, circle.Center()); if (d < 0.0) { d += circle.Radius(); if (d > 0.0) return 0.0; } else if (d > 0.0) { d -= circle.Radius(); if (d < 0.0) return 0.0; } return d; }