//Derivative at point t
        public float ExactDerivative(float t)
        {
            MyVector3 A = posA;
            MyVector3 B = handle;
            MyVector3 C = posB;

            //Layer 1
            //(1-t)A + tB = A - At + Bt
            //(1-t)B + tC = B - Bt + Ct

            //Layer 2
            //(1-t)(A - At + Bt) + t(B - Bt + Ct)
            //A - At + Bt - At + At^2 - Bt^2 + Bt - Bt^2 + Ct^2
            //A - 2At + 2Bt + At^2 - 2Bt^2 + Ct^2
            //A - t(2(A - B)) + t^2(A - 2B + C)

            //Derivative: -(2(A - B)) + t(2(A - 2B + C))

            MyVector3 derivativeVector = t * (2f * (A - 2f * B + C));

            derivativeVector += -2f * (A - B);


            float derivative = MyVector3.Magnitude(derivativeVector);


            return(derivative);
        }
        //
        // Derivative
        //

        public override float GetDerivative(float t)
        {
            MyVector3 derivativeVec = GetDerivativeVec(posA, posB, handleA, handleB, t);

            float derivative = MyVector3.Magnitude(derivativeVec);

            return(derivative);
        }
        //
        // Calculate the area of a triangle in 3d space
        //
        //https://math.stackexchange.com/questions/128991/how-to-calculate-the-area-of-a-3d-triangle
        public static float CalculateTriangleArea(MyVector3 p1, MyVector3 p2, MyVector3 p3)
        {
            MyVector3 normal = CalculateTriangleNormal(p1, p2, p3, shouldNormalize: false);

            float parallelogramArea = MyVector3.Magnitude(normal);

            float triangleArea = parallelogramArea * 0.5f;

            return(triangleArea);
        }
        //
        // Derivative at point t
        //

        public override float GetDerivative(float t)
        {
            //Alternative 1. Estimated
            //float derivative = InterpolationHelpMethods.EstimateDerivative(this, t);

            //Alternative 2. Exact
            MyVector3 derivativeVec = GetDerivativeVec(posA, posB, handlePos, t);

            float derivative = MyVector3.Magnitude(derivativeVec);

            return(derivative);
        }
        //
        // Alternative 3. Rotation Minimising Frame (also known as "Parallel Transport Frame" or "Bishop Frame")
        //

        //Gets its stability by incrementally rotating a coordinate system (= frame) as it is translate along the curve
        //Has to be computed for the entire curve because we need the previous frame (previousTransform) belonging to a point before this point
        //Is initalized by using "Fixed Up" or "Frenet Normal"
        public static MyQuaternion GetOrientation_RotationFrame(MyVector3 position, MyVector3 tangent, InterpolationTransform previousTransform)
        {
            /*
             * //This version is from https://pomax.github.io/bezierinfo/#pointvectors3d
             * //Reflect the known frame onto the next point, by treating the plane through the curve at the point exactly between the next and previous points as a "mirror"
             * MyVector3 v1 = position - previousTransform.position;
             *
             * float c1 = MyVector3.Dot(v1, v1);
             *
             * MyVector3 riL = previousTransform.Right - v1 * (2f / c1) * MyVector3.Dot(v1, previousTransform.Right);
             *
             * MyVector3 tiL = previousTransform.Forward - v1 * (2f / c1) * MyVector3.Dot(v1, previousTransform.Forward);
             *
             * //This gives the next point a tangent vector that's essentially pointing in the opposite direction of what it should be, and a normal that's slightly off-kilter
             * //reflect the vectors of our "mirrored frame" a second time, but this time using the plane through the "next point" itself as "mirror".
             * MyVector3 v2 = tangent - tiL;
             *
             * float c2 = MyVector3.Dot(v2, v2);
             *
             * //Now we can calculate the normal and right vector belonging to this orientation
             * MyVector3 right = riL - v2 * (2f / c2) * MyVector3.Dot(v2, riL);
             *
             * //The source has right x tangent, but then every second normal is flipped
             * MyVector3 normal = MyVector3.Cross(tangent, right);
             *
             * MyQuaternion orientation = new MyQuaternion(tangent, normal);
             */


            //This version is from Game Programming Gems 2: The Parallel Transport Frame
            //They generate the same result and this one is easier to understand

            //The two tangents
            MyVector3 T1 = previousTransform.Forward;
            MyVector3 T2 = tangent;

            //You move T1 to the new position, so A is a vector going from the new position
            MyVector3 A = MyVector3.Cross(T1, T2);

            //This is the angle between T1 and T2
            float alpha = Mathf.Acos(MyVector3.Dot(T1, T2) / (MyVector3.Magnitude(T1) * MyVector3.Magnitude(T2)));

            //Now rotate the previous frame around axis A with angle alpha
            MyQuaternion F1 = previousTransform.orientation;

            MyQuaternion F2 = MyQuaternion.RotateQuaternion(F1, alpha * Mathf.Rad2Deg, A);

            MyQuaternion orientation = F2;


            return(orientation);
        }
Exemple #6
0
        //
        // Estimate the derivative at point t
        //
        //https://www.youtube.com/watch?v=pHMzNW8Agq4
        public static float EstimateDerivative(Curve curve, float t)
        {
            //We can estimate the derivative by taking a step in each direction of the point we are interested in
            //Should be around this number
            float derivativeStepSize = 0.0001f;

            MyVector3 valueMinus = curve.GetInterpolatedValue(t - derivativeStepSize);
            MyVector3 valuePlus  = curve.GetInterpolatedValue(t + derivativeStepSize);

            //Have to multiply by two because we are taking a step in each direction
            MyVector3 derivativeVector = (valuePlus - valueMinus) * (1f / (derivativeStepSize * 2f));


            float derivative = MyVector3.Magnitude(derivativeVector);


            return(derivative);
        }
        //
        // Calculate the center of circle in 3d space given three coordinates
        //
        //From https://gamedev.stackexchange.com/questions/60630/how-do-i-find-the-circumcenter-of-a-triangle-in-3d
        public static MyVector3 CalculateCircleCenter(MyVector3 a, MyVector3 b, MyVector3 c)
        {
            MyVector3 ac    = c - a;
            MyVector3 ab    = b - a;
            MyVector3 abXac = MyVector3.Cross(ab, ac);

            //This is the vector from a to the circumsphere center
            MyVector3 toCircumsphereCenter = MyVector3.Cross(abXac, ab) * Mathf.Pow(MyVector3.Magnitude(ac), 2f);

            toCircumsphereCenter += MyVector3.Cross(ac, abXac) * Mathf.Pow(MyVector3.Magnitude(ab), 2f);

            toCircumsphereCenter *= (1f / (2f * Mathf.Pow(MyVector3.Magnitude(abXac), 2f)));

            float circumsphereRadius = MyVector3.Magnitude(toCircumsphereCenter);

            //The circumsphere center becomes
            MyVector3 ccs = a + toCircumsphereCenter;

            return(ccs);
        }
        //Actual derivative at point t
        public float ExactDerivative(float t)
        {
            MyVector3 A = posA;
            MyVector3 B = handleA;
            MyVector3 C = handleB;
            MyVector3 D = posB;

            //Layer 1
            //(1-t)A + tB = A - At + Bt
            //(1-t)B + tC = B - Bt + Ct
            //(1-t)C + tD = C - Ct + Dt

            //Layer 2
            //(1-t)(A - At + Bt) + t(B - Bt + Ct) = A - At + Bt - At + At^2 - Bt^2 + Bt - Bt^2 + Ct^2 = A - 2At + 2Bt + At^2 - 2Bt^2 + Ct^2
            //(1-t)(B - Bt + Ct) + t(C - Ct + Dt) = B - Bt + Ct - Bt + Bt^2 - Ct^2 + Ct - Ct^2 + Dt^2 = B - 2Bt + 2Ct + Bt^2 - 2Ct^2 + Dt^2

            //Layer 3
            //(1-t)(A - 2At + 2Bt + At^2 - 2Bt^2 + Ct^2) + t(B - 2Bt + 2Ct + Bt^2 - 2Ct^2 + Dt^2)
            //A - 2At + 2Bt + At^2 - 2Bt^2 + Ct^2 - At + 2At^2 - 2Bt^2 - At^3 + 2Bt^3 - Ct^3 + Bt - 2Bt^2 + 2Ct^2 + Bt^3 - 2Ct^3 + Dt^3
            //A - 3At + 3Bt + 3At^2 - 6Bt^2 + 3Ct^2 - At^3 + 3Bt^3 - 3Ct^3 + Dt^3
            //A - 3t(A - B) + t^2(3A - 6B + 3C) + t^3(-A + 3B - 3C + D)
            //A - 3t(A - B) + t^2(3(A - 2B + C)) + t^3(-(A - 3(B - C) - D)

            //The derivative: -3(A - B) + 2t(3(A - 2B + C)) + 3t^2(-(A - 3(B - C) - D)
            //-3(A - B) + t(6(A - 2B + C)) + t^2(-3(A - 3(B - C) - D)

            MyVector3 derivativeVector = t * t * (-3f * (A - 3f * (B - C) - D));

            derivativeVector += t * (6f * (A - 2f * B + C));

            derivativeVector += -3f * (A - B);


            float derivative = MyVector3.Magnitude(derivativeVector);


            return(derivative);
        }