Ejemplo n.º 1
0
        // Solve a line segment using barycentric coordinates.
        //
        // p = a1 * w1 + a2 * w2
        // a1 + a2 = 1
        //
        // The vector from the origin to the closest point on the line is
        // perpendicular to the line.
        // e12 = w2 - w1
        // dot(p, e) = 0
        // a1 * dot(w1, e) + a2 * dot(w2, e) = 0
        //
        // 2-by-2 linear system
        // [1      1     ][a1] = [1]
        // [w1.e12 w2.e12][a2] = [0]
        //
        // Define
        // d12_1 =  dot(w2, e12)
        // d12_2 = -dot(w1, e12)
        // d12 = d12_1 + d12_2
        //
        // Solution
        // a1 = d12_1 / d12
        // a2 = d12_2 / d12
        /// <summary>
        ///     Solves the 2
        /// </summary>
        internal void Solve2()
        {
            Vec2 w1  = V1.W;
            Vec2 w2  = V2.W;
            Vec2 e12 = w2 - w1;

            // w1 region
            float d122 = -Vec2.Dot(w1, e12);

            if (d122 <= 0.0f)
            {
                // a2 <= 0, so we clamp it to 0
                V1.A  = 1.0f;
                Count = 1;
                return;
            }

            // w2 region
            float d121 = Vec2.Dot(w2, e12);

            if (d121 <= 0.0f)
            {
                // a1 <= 0, so we clamp it to 0
                V2.A  = 1.0f;
                Count = 1;
                V1    = V2;
                return;
            }

            // Must be in e12 region.
            float invD12 = 1.0f / (d121 + d122);

            V1.A  = d121 * invD12;
            V2.A  = d122 * invD12;
            Count = 2;
        }
Ejemplo n.º 2
0
        // Possible regions:
        // - points[2]
        // - edge points[0]-points[2]
        // - edge points[1]-points[2]
        // - inside the triangle
        /// <summary>
        ///     Solves the 3
        /// </summary>
        internal void Solve3()
        {
            Vec2 w1 = V1.W;
            Vec2 w2 = V2.W;
            Vec2 w3 = V3.W;

            // Edge12
            // [1      1     ][a1] = [1]
            // [w1.e12 w2.e12][a2] = [0]
            // a3 = 0
            Vec2  e12   = w2 - w1;
            float w1E12 = Vec2.Dot(w1, e12);
            float w2E12 = Vec2.Dot(w2, e12);
            float d121  = w2E12;
            float d122  = -w1E12;

            // Edge13
            // [1      1     ][a1] = [1]
            // [w1.e13 w3.e13][a3] = [0]
            // a2 = 0
            Vec2  e13   = w3 - w1;
            float w1E13 = Vec2.Dot(w1, e13);
            float w3E13 = Vec2.Dot(w3, e13);
            float d131  = w3E13;
            float d132  = -w1E13;

            // Edge23
            // [1      1     ][a2] = [1]
            // [w2.e23 w3.e23][a3] = [0]
            // a1 = 0
            Vec2  e23   = w3 - w2;
            float w2E23 = Vec2.Dot(w2, e23);
            float w3E23 = Vec2.Dot(w3, e23);
            float d231  = w3E23;
            float d232  = -w2E23;

            // Triangle123
            float n123 = Vec2.Cross(e12, e13);

            float d1231 = n123 * Vec2.Cross(w2, w3);
            float d1232 = n123 * Vec2.Cross(w3, w1);
            float d1233 = n123 * Vec2.Cross(w1, w2);

            // w1 region
            if (d122 <= 0.0f && d132 <= 0.0f)
            {
                V1.A  = 1.0f;
                Count = 1;
                return;
            }

            // e12
            if (d121 > 0.0f && d122 > 0.0f && d1233 <= 0.0f)
            {
                float invD12 = 1.0f / (d121 + d122);
                V1.A  = d121 * invD12;
                V2.A  = d121 * invD12;
                Count = 2;
                return;
            }

            // e13
            if (d131 > 0.0f && d132 > 0.0f && d1232 <= 0.0f)
            {
                float invD13 = 1.0f / (d131 + d132);
                V1.A  = d131 * invD13;
                V3.A  = d132 * invD13;
                Count = 2;
                V2    = V3;
                return;
            }

            // w2 region
            if (d121 <= 0.0f && d232 <= 0.0f)
            {
                V2.A  = 1.0f;
                Count = 1;
                V1    = V2;
                return;
            }

            // w3 region
            if (d131 <= 0.0f && d231 <= 0.0f)
            {
                V3.A  = 1.0f;
                Count = 1;
                V1    = V3;
                return;
            }

            // e23
            if (d231 > 0.0f && d232 > 0.0f && d1231 <= 0.0f)
            {
                float invD23 = 1.0f / (d231 + d232);
                V2.A  = d231 * invD23;
                V3.A  = d232 * invD23;
                Count = 2;
                V1    = V3;
                return;
            }

            // Must be in triangle123
            float invD123 = 1.0f / (d1231 + d1232 + d1233);

            V1.A  = d1231 * invD123;
            V2.A  = d1232 * invD123;
            V3.A  = d1233 * invD123;
            Count = 3;
        }