Ejemplo n.º 1
0
        /// <summary> Attempts to calculate a sphere with center in 'c' and radius 'r' from four points </summary>
        public static bool TryCreate(Vector3 v0, Vector3 v1, Vector3 v2, Vector3 v3, out Vector3 c, out float r)
        {
            c = default;
            r = default;

            var p = new float[4, 4]
            {
                { v0.x, v0.y, v0.z, 1.0f },
                { v1.x, v1.y, v1.z, 1.0f },
                { v2.x, v2.y, v2.z, 1.0f },
                { v3.x, v3.y, v3.z, 1.0f }
            };
            var a = new float[4, 4];

            // Find minor 1, 1.
            for (int i = 0; i < 4; i++)
            {
                a[i, 0] = p[i, 0];
                a[i, 1] = p[i, 1];
                a[i, 2] = p[i, 2];
            }
            float detM11 = Mathx.Determinant(a);

            if (Mathx.IsZero(detM11))
            {
                return(false);
            }

            for (int i = 0; i < 4; i++)
            {
                a[i, 0] = p[i, 0] * p[i, 0] + p[i, 1] * p[i, 1] + p[i, 2] * p[i, 2];
            }

            for (int i = 0; i < 4; i++)
            {
                a[i, 1] = p[i, 1];
                a[i, 2] = p[i, 2];
            }
            float detM12 = Mathx.Determinant(a);

            for (int i = 0; i < 4; i++)
            {
                a[i, 1] = p[i, 0];
                a[i, 2] = p[i, 2];
            }
            float detM13 = Mathx.Determinant(a);

            for (int i = 0; i < 4; i++)
            {
                a[i, 1] = p[i, 0];
                a[i, 2] = p[i, 1];
            }
            float detM14 = Mathx.Determinant(a);

            for (int i = 0; i < 4; i++)
            {
                a[i, 1] = p[i, 0];
                a[i, 2] = p[i, 1];
                a[i, 3] = p[i, 2];
            }
            float detM15 = Mathx.Determinant(a);

            c.x = 0.5f * detM12 / detM11;
            c.y = -0.5f * detM13 / detM11;
            c.z = 0.5f * detM14 / detM11;
            r   = Mathf.Sqrt(c.x * c.x + c.y * c.y + c.z * c.z - detM15 / detM11);
            return(true);
        }