예제 #1
0
    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);
    }
예제 #2
0
    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);
    }
예제 #3
0
    /** 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));
    }
예제 #4
0
    /** 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);
    }
예제 #5
0
    /** 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));
        }
    }