Пример #1
0
        /*
         * Finds the point on a line segment closest to a given point.
         *
         * Solves the equation system that minimizes the point-line distance.
         * https://math.stackexchange.com/questions/846054/closest-points-on-two-line-segments
         */
        public static Vect3 FindClosestLinePoint(Vect3 lineStart, Vect3 lineEnd, Vect3 point)
        {
            Vect3 lineVector = lineEnd - lineStart;

            double lineVectorSquared           = Vect3.Dot(lineVector, lineVector);
            double pointToLineVectorDotProduct = Vect3.Dot((point - lineStart), lineVector);

            double vectorScalingFactor = pointToLineVectorDotProduct / lineVectorSquared;

            // Clamps the result to the line segment distance [0,1]
            // 0 is lineStart, 1 applies the entire lineVector from lineStart towards lineEnd.
            vectorScalingFactor = vectorScalingFactor < 0 ? 0 : vectorScalingFactor;
            vectorScalingFactor = vectorScalingFactor > 1 ? 1 : vectorScalingFactor;

            return(lineStart + lineVector * vectorScalingFactor);
        }
Пример #2
0
        /*
         * Calculates Line/Face intersections using the Möller-Trumbore intersection algorithm.
         *
         * https://en.wikipedia.org/wiki/Möller–Trumbore_intersection_algorithm
         */
        public static bool rayIntersectsTriangle(Vect3 rayOrigin,
                                                 Vect3 rayVector,
                                                 Vect3 vertex0,
                                                 Vect3 vertex1,
                                                 Vect3 vertex2)
        {
            double EPSILON = 1e-6;
            Vect3  edge1 = vertex1 - vertex0;
            Vect3  edge2 = vertex2 - vertex0;
            double a, f, u, v;
            Vect3  h = Vect3.Cross(rayVector, edge2);

            a = Vect3.Dot(edge1, h);
            if (a > -EPSILON && a < EPSILON)
            {
                return(false); // This ray is parallel to this triangle.
            }
            f = 1.0 / a;
            Vect3 s = rayOrigin - vertex0;

            u = f * Vect3.Dot(s, h);
            if (u < 0.0 || u > 1.0)
            {
                return(false);
            }
            Vect3 q = Vect3.Cross(s, edge1);

            v = f * Vect3.Dot(rayVector, q);
            if (v < 0.0 || u + v > 1.0)
            {
                return(false);
            }
            double t = f * Vect3.Dot(edge2, q);

            return(t > EPSILON);
        }