/** * */ package wblut.geom; import java.util.List; import wblut.WB_Epsilon; // TODO: Auto-generated Javadoc /** * The Class WB_Distance. * * @author Frederik Vanhoutte, W:Blut */ public class WB_Distance { // POINT-POINT /** * Squared distance between 2 points. * * @param p the p * @param q the q * @return squared distance */ public static double sqDistance(final WB_Point3d p, final WB_Point3d q) { return ((q.x - p.x) * (q.x - p.x) + (q.y - p.y) * (q.y - p.y) + (q.z - p.z) * (q.z - p.z)); } /** * Distance between 2 points. * * @param p the p * @param q the q * @return distance */ public static double distance(final WB_Point3d p, final WB_Point3d q) { return Math.sqrt(sqDistance(p, q)); } /** * Squared distance between 2 points. * * @param p the p * @param q the q * @return squared distance */ public static double sqDistance(final WB_Point4d p, final WB_Point4d q) { return ((q.x - p.x) * (q.x - p.x) + (q.y - p.y) * (q.y - p.y) + (q.z - p.z) * (q.z - p.z) + (q.w - p.w) * (q.w - p.w)); } /** * Distance between 2 points. * * @param p the p * @param q the q * @return distance */ public static double distance(final WB_Point4d p, final WB_Point4d q) { return Math.sqrt(sqDistance(p, q)); } // POINT-PLANE /** * Squared distance between point and plane. * * @param p point * @param P plane * @return squared distance */ public static double sqDistance(final WB_Point3d p, final WB_Plane P) { final double d = P.getNormal().dot(p) - P.d(); return d * d; } /** * Distance between point and plane. * * @param p point * @param P plane * @return distance */ public static double distance(final WB_Point3d p, final WB_Plane P) { return P.getNormal().dot(p) - P.d(); } // POINT-SEGMENT /** * Squared distance between point and segment. * * @param p point * @param S segment * @return squared distance */ public static double sqDistance(final WB_Point3d p, final WB_Segment S) { final WB_Vector3d ab = S.getEnd().subToVector(S.getOrigin()); final WB_Vector3d ac = p.subToVector(S.getOrigin()); final WB_Vector3d bc = p.subToVector(S.getEnd()); final double e = ac.dot(ab); if (e <= 0) { return ac.dot(ac); } final double f = ab.dot(ab); if (e >= f) { return bc.dot(bc); } return ac.dot(ac) - e * e / f; } /** * Distance between point and segment. * * @param p point * @param S segment * @return distance */ public static double distance(final WB_Point3d p, final WB_Segment S) { return Math.sqrt(sqDistance(p, S)); } /** * Squared distance between point and segment. * * @param p point * @param a segment start * @param b segment end * @return squared distance */ public static double sqDistanceToSegment(final WB_Point3d p, final WB_Point3d a, final WB_Point3d b) { final WB_Vector3d ab = b.subToVector(a); final WB_Vector3d ac = p.subToVector(a); final WB_Vector3d bc = p.subToVector(b); final double e = ac.dot(ab); if (e <= 0) { return ac.dot(ac); } final double f = ab.dot(ab); if (e >= f) { return bc.dot(bc); } return ac.dot(ac) - e * e / f; } /** * Distance between point and segment. * * @param p point * @param a segment start * @param b segment end * @return distance */ public static double distanceToSegment(final WB_Point3d p, final WB_Point3d a, final WB_Point3d b) { return Math.sqrt(sqDistanceToSegment(p, a, b)); } // POINT-LINE /** * Squared distance between point and line. * * @param p point * @param L line * @return squared distance */ public static double sqDistance(final WB_Point3d p, final WB_Line L) { final WB_Vector3d ab = L.getDirection(); final WB_Vector3d ac = p.subToVector(L.getOrigin()); final double e = ac.dot(ab); final double f = ab.dot(ab); return ac.dot(ac) - e * e / f; } /** * Distance between point and line. * * @param p point * @param L line * @return distance */ public static double distance(final WB_Point3d p, final WB_Line L) { return Math.sqrt(sqDistance(p, L)); } /** * Squared distance between point and line. * * @param p point * @param a point on line * @param b point on line * @return squared distance */ public static double sqDistanceToLine(final WB_Point3d p, final WB_Point3d a, final WB_Point3d b) { final WB_Vector3d ab = b.subToVector(a); final WB_Vector3d ac = p.subToVector(a); final double e = ac.dot(ab); final double f = ab.dot(ab); return ac.dot(ac) - e * e / f; } /** * Distance between point and line. * * @param p point * @param a point on line * @param b point on line * @return distance */ public static double distanceToLine(final WB_Point3d p, final WB_Point3d a, final WB_Point3d b) { return Math.sqrt(sqDistanceToLine(p, a, b)); } // POINT-RAY /** * Squared distance between point and ray. * * @param p point * @param R ray * @return squared distance */ public static double sqDistance(final WB_Point3d p, final WB_Ray R) { final WB_Vector3d ab = R.getDirection(); final WB_Vector3d ac = p.subToVector(R.getOrigin()); final double e = ac.dot(ab); if (e <= 0) { return ac.dot(ac); } final double f = ab.dot(ab); return ac.dot(ac) - e * e / f; } /** * Distance between point and ray. * * @param p point * @param R ray * @return distance */ public static double distance(final WB_Point3d p, final WB_Ray R) { return Math.sqrt(sqDistance(p, R)); } /** * Squared distance between point and ray. * * @param p point * @param a ray origin * @param b point on ray * @return squared distance */ public static double sqDistanceToRay(final WB_Point3d p, final WB_Point3d a, final WB_Point3d b) { final WB_Vector3d ab = b.subToVector(a); final WB_Vector3d ac = p.subToVector(a); final double e = ac.dot(ab); if (e <= 0) { return ac.dot(ac); } final double f = ab.dot(ab); return ac.dot(ac) - e * e / f; } /** * Distance between point and ray. * * @param p point * @param a ray origin * @param b point on ray * @return distance */ public static double distanceToRay(final WB_Point3d p, final WB_Point3d a, final WB_Point3d b) { return Math.sqrt(sqDistanceToRay(p, a, b)); } // POINT-AABB /** * Squared distance between point and axis-aligned box. * * @param p point * @param AABB AABB * @return squared distance */ public static double sqDistance(final WB_Point3d p, final WB_AABB3D AABB) { double sqDist = 0; double v = p.x; if (v < AABB.min.x) { sqDist += (AABB.min.x - v) * (AABB.min.x - v); } if (v > AABB.max.x) { sqDist += (v - AABB.max.x) * (v - AABB.max.x); } v = p.y; if (v < AABB.min.y) { sqDist += (AABB.min.y - v) * (AABB.min.y - v); } if (v > AABB.max.y) { sqDist += (v - AABB.max.y) * (v - AABB.max.y); } v = p.z; if (v < AABB.min.z) { sqDist += (AABB.min.z - v) * (AABB.min.z - v); } if (v > AABB.max.z) { sqDist += (v - AABB.max.z) * (v - AABB.max.z); } return sqDist; } /** * Distance between point and axis-aligned box. * * @param p point * @param AABB AABB * @return distance */ public static double distance(final WB_Point3d p, final WB_AABB3D AABB) { return Math.sqrt(sqDistance(p, AABB)); } /** * Squared distance between point and polygon. * * @param p point * @param poly polygon * @return squared distance */ public static double sqDistance(final WB_Point3d p, final WB_Polygon poly) { final List<WB_IndexedTriangle> tris = poly.triangulate(); final int n = tris.size(); double dmax2 = Double.POSITIVE_INFINITY; WB_Point3d tmp; WB_IndexedTriangle T; for (int i = 0; i < n; i++) { T = tris.get(i); tmp = WB_Intersection.closestPoint(p, T); final double d2 = WB_Distance.distance(tmp, p); if (d2 < dmax2) { dmax2 = d2; if (WB_Epsilon.isZeroSq(dmax2)) { break; } } } return dmax2; } /** * Distance between point and polygon. * * @param p point * @param poly polygon * @return squared distance */ public static double distance(final WB_Point3d p, final WB_Polygon poly) { return Math.sqrt(sqDistance(p, poly)); } /** * Sq distance. * * @param S the s * @param T the t * @return the double */ public static double sqDistance(final WB_Segment S, final WB_Segment T) { return WB_Intersection.getIntersection(S, T).sqDist; } /** * Distance. * * @param S the s * @param T the t * @return the double */ public static double distance(final WB_Segment S, final WB_Segment T) { return Math.sqrt(WB_Intersection.getIntersection(S, T).sqDist); } }