public static float NearestPointFloatXZ(VInt3 lineStart, VInt3 lineEnd, VInt3 point) { VInt2 b = new VInt2(lineEnd.x - lineStart.x, lineEnd.z - lineStart.z); double num = (double)b.sqrMagnitude; VInt2 a = new VInt2(point.x - lineStart.x, point.z - lineStart.z); double num2 = (double)VInt2.Dot(a, b); if (num != 0.0) { num2 /= num; } return((float)num2); }
public static float NearestPointFactorXZ(VInt3 lineStart, VInt3 lineEnd, VInt3 point) { VInt2 b = new VInt2(lineEnd.x - lineStart.x, lineEnd.z - lineStart.z); double sqrMagnitude = b.sqrMagnitude; VInt2 a = new VInt2(point.x - lineStart.x, point.z - lineStart.z); double num4 = VInt2.Dot(a, b); if (sqrMagnitude != 0.0) { num4 /= sqrMagnitude; } return((float)num4); }
/** Returns the closest point on the segment in the XZ plane. * The y coordinate of the result will be the same as the y coordinate of the \a point parameter. * * The segment is NOT treated as infinite. * \see ClosestPointOnSegment * \see ClosestPointOnLine */ public static VInt2 ClosestPointOnSegmentXZ(VInt2 lineStart, VInt2 lineEnd, VInt2 point) { lineStart.y = point.y; lineEnd.y = point.y; VInt2 fullDirection = lineEnd - lineStart; VInt2 fullDirection2 = fullDirection; fullDirection2.y = 0; int magn = fullDirection2.magnitude; VInt2 lineDirection = magn > float.Epsilon ? fullDirection2 / magn : VInt2.zero; int closestPoint = VInt2.Dot((point - lineStart), lineDirection); int a = (int)Clamp(closestPoint, 0, fullDirection2.magnitude); return(lineStart + (lineDirection * a)); }
/** Closest point on the triangle \a abc to the point \a p. * \see 'Real Time Collision Detection' by Christer Ericson, chapter 5.1, page 141 */ public static VInt2 ClosestPointOnTriangle(VInt2 a, VInt2 b, VInt2 c, VInt2 p) { // Check if p is in vertex region outside A var ab = b - a; var ac = c - a; var ap = p - a; var d1 = VInt2.Dot(ab, ap); var d2 = VInt2.Dot(ac, ap); // Barycentric coordinates (1,0,0) if (d1 <= 0 && d2 <= 0) { return(a); } // Check if p is in vertex region outside B var bp = p - b; var d3 = VInt2.Dot(ab, bp); var d4 = VInt2.Dot(ac, bp); // Barycentric coordinates (0,1,0) if (d3 >= 0 && d4 <= d3) { return(b); } // Check if p is in edge region outside AB, if so return a projection of p onto AB if (d1 >= 0 && d3 <= 0) { var vc = d1 * d4 - d3 * d2; if (vc <= 0) { // Barycentric coordinates (1-v, v, 0) var v = d1 / (d1 - d3); return(a + ab * v); } } // Check if p is in vertex region outside C var cp = p - c; var d5 = VInt2.Dot(ab, cp); var d6 = VInt2.Dot(ac, cp); // Barycentric coordinates (0,0,1) if (d6 >= 0 && d5 <= d6) { return(c); } // Check if p is in edge region of AC, if so return a projection of p onto AC if (d2 >= 0 && d6 <= 0) { var vb = d5 * d2 - d1 * d6; if (vb <= 0) { // Barycentric coordinates (1-v, 0, v) var v = d2 / (d2 - d6); return(a + ac * v); } } // Check if p is in edge region of BC, if so return projection of p onto BC if ((d4 - d3) >= 0 && (d5 - d6) >= 0) { var va = d3 * d6 - d5 * d4; if (va <= 0) { var v = (d4 - d3) / ((d4 - d3) + (d5 - d6)); return(b + (c - b) * v); } } return(p); }
/** Closest point on the triangle \a abc to the point \a p when seen from above. * \see 'Real Time Collision Detection' by Christer Ericson, chapter 5.1, page 141 */ public static VInt3 ClosestPointOnTriangleXZ(VInt3 a, VInt3 b, VInt3 c, VInt3 p) { // Check if p is in vertex region outside A var ab = new VInt2(b.x - a.x, b.z - a.z); var ac = new VInt2(c.x - a.x, c.z - a.z); var ap = new VInt2(p.x - a.x, p.z - a.z); var d1 = VInt2.Dot(ab, ap); var d2 = VInt2.Dot(ac, ap); // Barycentric coordinates (1,0,0) if (d1 <= 0 && d2 <= 0) { return(a); } // Check if p is in vertex region outside B var bp = new VInt2(p.x - b.x, p.z - b.z); var d3 = VInt2.Dot(ab, bp); var d4 = VInt2.Dot(ac, bp); // Barycentric coordinates (0,1,0) if (d3 >= 0 && d4 <= d3) { return(b); } // Check if p is in edge region outside AB, if so return a projection of p onto AB var vc = d1 * d4 - d3 * d2; if (d1 >= 0 && d3 <= 0 && vc <= 0) { // Barycentric coordinates (1-v, v, 0) var v = d1 / (d1 - d3); return(a * (1 - v) + b * v); } // Check if p is in vertex region outside C var cp = new VInt2(p.x - c.x, p.z - c.z); var d5 = VInt2.Dot(ab, cp); var d6 = VInt2.Dot(ac, cp); // Barycentric coordinates (0,0,1) if (d6 >= 0 && d5 <= d6) { return(c); } // Check if p is in edge region of AC, if so return a projection of p onto AC var vb = d5 * d2 - d1 * d6; if (d2 >= 0 && d6 <= 0 && vb <= 0) { // Barycentric coordinates (1-v, 0, v) var v = d2 / (d2 - d6); return(a * (1 - v) + c * v); } // Check if p is in edge region of BC, if so return projection of p onto BC var va = d3 * d6 - d5 * d4; if ((d4 - d3) >= 0 && (d5 - d6) >= 0 && va <= 0) { var v = (d4 - d3) / ((d4 - d3) + (d5 - d6)); return(b + (c - b) * v); } else { // P is inside the face region. Compute the point using its barycentric coordinates (u, v, w) // Note that the x and z coordinates will be exactly the same as P's x and z coordinates var denom = 1000 / (va + vb + vc); var v = vb * denom; var w = vc * denom; return(new VInt3(p.x, (1 - v - w) * a.y + v * b.y + w * c.y, p.z)); } }