//Display curve with high resolution, which is useful if we want to compare the actual curve with a curve split into steps
    //Unity has built-in Handles.DrawBezier but doesn't exist for other curve types
    public static void DisplayCurve(_Curve curve, Color color)
    {
        int steps = 200;

        List <MyVector3> positionsOnCurve = InterpolationHelpMethods.SplitCurve(curve, steps, tEnd: 1f);

        List <Vector3> positionsOnCurveStandardized = positionsOnCurve.ConvertAll(x => x.ToVector3());

        DisplayCurve(positionsOnCurveStandardized, false, color, false);
    }
    private void BezierCubicEqualSteps(MyVector3 posA, MyVector3 posB, MyVector3 handleA, MyVector3 handleB)
    {
        //Store the interpolated values so we later can display them
        List <Vector3> actualPositions = new List <Vector3>();

        //Create a curve which is the data structure used in the following calculations
        BezierCubic bezierCubic = new BezierCubic(posA, posB, handleA, handleB);


        //Step 1. Calculate the length of the entire curve
        //This is needed to so we know how long we should walk each step
        float lengthNaive = InterpolationHelpMethods.GetLength_Naive(bezierCubic, steps: 20, tEnd: 1f);

        float lengthExact = InterpolationHelpMethods.GetLength_SimpsonsRule(bezierCubic, tStart: 0f, tEnd: 1f);

        Debug.Log("Naive length: " + lengthNaive + " Exact length: " + lengthExact);



        int steps = 5;

        //Important not to confuse this with the step size we use to iterate t
        //This step size is distance in m
        float length = lengthNaive;

        float lengthStepSize = length / (float)steps;

        float stepSize = 1f / (float)steps;

        float t = 0f;

        float distanceTravelled = 0f;

        for (int i = 0; i < steps + 1; i++)
        {
            //MyVector3 inaccuratePos = bezierCubic.GetInterpolatedValue(t);



            //Calculate t to get to this distance
            //Method 1
            //float actualT = InterpolationHelpMethods.Find_t_FromDistance_Iterative(bezierCubic, distanceTravelled, length);
            //Method 2
            float actualT = InterpolationHelpMethods.Find_t_FromDistance_Lookup(bezierCubic, distanceTravelled, accumulatedDistances: null);

            MyVector3 actualPos = bezierCubic.GetInterpolatedValue(actualT);

            actualPositions.Add(actualPos.ToVector3());



            //Test that the derivative calculations are working
            float dEst = InterpolationHelpMethods.EstimateDerivative(bezierCubic, t);
            float dAct = bezierCubic.ExactDerivative(t);

            Debug.Log("Estimated derivative: " + dEst + " Actual derivative: " + dAct);



            //Debug.Log("Distance " + distanceTravelled);

            //Move on to next iteration
            distanceTravelled += lengthStepSize;

            t += stepSize;
        }

        //List<MyVector3> positionsOnCurve = InterpolationHelpMethods.SplitCurve(bezierCubic, 20, tEnd: 1f);

        //foreach (MyVector3 p in positionsOnCurve)
        //{
        //    Gizmos.DrawWireSphere(p.ToVector3(), 0.1f);
        //}

        DisplayInterpolatedValues(actualPositions, useRandomColor: true);

        //Display the start and end values and the handle points
        DisplayHandle(handleA.ToVector3(), posA.ToVector3());
        DisplayHandle(handleB.ToVector3(), posB.ToVector3());


        //Display the actual Bezier cubic for reference
        Handles.DrawBezier(posA.ToVector3(), posB.ToVector3(), handleA.ToVector3(), handleB.ToVector3(), Color.blue, EditorGUIUtility.whiteTexture, 1f);
    }
Esempio n. 3
0
    private void BezierCubicTest_EqualSteps(MyVector3 posA, MyVector3 posB, MyVector3 handleA, MyVector3 handleB)
    {
        //Create a curve which is the data structure used in the following calculations
        BezierCubic bezierCubic = new BezierCubic(posA, posB, handleA, handleB);


        //Step 1. Calculate the length of the entire curve
        //This is needed so we know for how long we should walk each step
        float lengthNaive = InterpolationHelpMethods.GetLength_Naive(bezierCubic, steps: 20, tEnd: 1f);

        float lengthExact = InterpolationHelpMethods.GetLength_SimpsonsRule(bezierCubic, tStart: 0f, tEnd: 1f);

        //Debug.Log("Naive length: " + lengthNaive + " Exact length: " + lengthExact);


        //Step 2. Convert the t's to be percentage along the curve
        //Save the accurate t at each position on the curve
        List <float> accurateTs = new List <float>();

        //The number of sections we want to divide the curve into
        int steps = 20;

        //Important not to confuse this with the step size we use to iterate t
        //This step size is distance in m
        float curveLength = lengthNaive;

        float curveLength_stepSize = curveLength / (float)steps;

        float t_stepSize = 1f / (float)steps;

        float t = 0f;

        float distanceTravelled = 0f;

        for (int i = 0; i < steps + 1; i++)
        {
            //MyVector3 inaccuratePos = bezierCubic.GetPosition(t);

            //Calculate the t needed to get to this distance along the curve
            //Method 1
            //float accurateT = InterpolationHelpMethods.Find_t_FromDistance_Iterative(bezierCubic, distanceTravelled, length);
            //Method 2
            float accurateT = InterpolationHelpMethods.Find_t_FromDistance_Lookup(bezierCubic, distanceTravelled, accumulatedDistances: null);

            accurateTs.Add(accurateT);

            //Debug.Log(accurateT);


            //Test that the derivative calculations are working
            //float dEst = InterpolationHelpMethods.EstimateDerivative(bezierCubic, t);
            //float dAct = bezierCubic.ExactDerivative(t);

            //Debug.Log("Estimated derivative: " + dEst + " Actual derivative: " + dAct);

            //Debug.Log("Distance " + distanceTravelled);


            //Move on to next iteration
            distanceTravelled += curveLength_stepSize;

            t += t_stepSize;
        }


        //Step3. Use the new t's to get information from the curve

        //The interpolated positions
        List <Vector3> actualPositions = new List <Vector3>();
        //Save the tangent at each position on the curve
        List <Vector3> tangents = new List <Vector3>();

        //Save the orientation, which includes the tangent
        //List<InterpolationTransform> orientations = new List<InterpolationTransform>();

        for (int i = 0; i < accurateTs.Count; i++)
        {
            float accurateT = accurateTs[i];

            //Position on the curve
            MyVector3 actualPos = bezierCubic.GetPosition(accurateT);

            actualPositions.Add(actualPos.ToVector3());

            //Tangent at each position
            MyVector3 tangentDir = BezierCubic.GetTangent(posA, posB, handleA, handleB, accurateT);

            tangents.Add(tangentDir.ToVector3());

            //Orientation, which includes both position and tangent
            //InterpolationTransform orientation = InterpolationTransform.GetTransform(bezierCubic, accurateT);

            //orientations.Add(orientation);
        }


        //The orientation at each t position
        MyVector3 startUpRef = MyVector3.Up;

        List <InterpolationTransform> orientationsFrames = InterpolationTransform.GetTransforms_RotationMinimisingFrame(bezierCubic, accurateTs, startUpRef);


        //Display stuff

        //The curve which is split into steps
        //DisplayInterpolation.DisplayCurve(actualPositions, useRandomColor: true);
        DisplayInterpolation.DisplayCurve(actualPositions, Color.gray);

        //The start and end values and the handle points
        DisplayInterpolation.DisplayHandle(handleA.ToVector3(), posA.ToVector3());
        DisplayInterpolation.DisplayHandle(handleB.ToVector3(), posB.ToVector3());

        //The actual Bezier cubic for reference
        DisplayInterpolation.DisplayCurve(bezierCubic, Color.black);
        //Handles.DrawBezier(posA.ToVector3(), posB.ToVector3(), handleA.ToVector3(), handleB.ToVector3(), Color.black, EditorGUIUtility.whiteTexture, 1f);

        //The tangents
        //DisplayInterpolation.DisplayDirections(actualPositions, tangents, 1f, Color.red);

        //The orientation
        //DisplayInterpolation.DisplayOrientations(orientations, 1f);
        DisplayInterpolation.DisplayOrientations(orientationsFrames, 1f);

        //Extrude mesh along the curve
        //InterpolationTransform testTrans = orientationsFrames[1];

        //MyVector3 pos = testTrans.LocalToWorld(MyVector3.Up * 2f);
        //MyVector3 pos = testTrans.LocalToWorld(MyVector3.Right * 2f);

        //Gizmos.DrawSphere(pos.ToVector3(), 0.1f);

        //DisplayInterpolation.DisplayExtrudedMesh(orientationsFrames, meshProfile);
    }
Esempio n. 4
0
    private void BezierQuadraticTest_EqualSteps(MyVector3 posA, MyVector3 posB, MyVector3 handle)
    {
        //Create a curve which is the data structure used in the following calculations
        BezierQuadratic bezierQuadratic = new BezierQuadratic(posA, posB, handle);


        //Step 1. Calculate the length of the entire curve
        //This is needed to so we know how long we should walk each step
        float lengthNaive = InterpolationHelpMethods.GetLength_Naive(bezierQuadratic, steps: 20, tEnd: 1f);

        float lengthExact = InterpolationHelpMethods.GetLength_SimpsonsRule(bezierQuadratic, tStart: 0f, tEnd: 1f);

        //Debug.Log("Naive length: " + lengthNaive + " Exact length: " + lengthExact);


        //Step 2. Convert the t's to be percentage along the curve
        //Save the accurate t at each position on the curve
        List <float> accurateTs = new List <float>();

        int steps = 5;

        //Important not to confuse this with the step size we use to iterate t
        //This step size is distance in m
        float length = lengthNaive;

        float lengthStepSize = length / (float)steps;

        float stepSize = 1f / (float)steps;

        float t = 0f;

        float distanceTravelled = 0f;

        for (int i = 0; i < steps + 1; i++)
        {
            //MyVector3 inaccuratePos = bezierCubic.GetInterpolatedValue(t);

            //Calculate t to get to this distance
            //Method 1
            //float accurateT = InterpolationHelpMethods.Find_t_FromDistance_Iterative(bezierQuadratic, distanceTravelled, length);
            //Method 2
            float accurateT = InterpolationHelpMethods.Find_t_FromDistance_Lookup(bezierQuadratic, distanceTravelled, accumulatedDistances: null);

            accurateTs.Add(accurateT);

            //Test that the derivative calculations are working
            //float dEst = InterpolationHelpMethods.EstimateDerivative(bezierQuadratic, t);
            //float dAct = bezierQuadratic.GetDerivative(t);

            //Debug.Log("Estimated derivative: " + dEst + " Actual derivative: " + dAct);



            //Debug.Log("Distance " + distanceTravelled);

            //Move on to next iteration
            distanceTravelled += lengthStepSize;

            t += stepSize;
        }


        //Get the data we want from the curve

        //Store the interpolated values so we later can display them
        List <Vector3> actualPositions = new List <Vector3>();
        //
        List <Vector3> tangents = new List <Vector3>();
        //Orientation, which includes the tangent and position
        List <InterpolationTransform> orientations = new List <InterpolationTransform>();

        for (int i = 0; i < accurateTs.Count; i++)
        {
            float accurateT = accurateTs[i];

            MyVector3 actualPos = bezierQuadratic.GetPosition(accurateT);

            actualPositions.Add(actualPos.ToVector3());


            MyVector3 tangent = bezierQuadratic.GetTangent(accurateT);

            tangents.Add(tangent.ToVector3());


            //Orientation, which includes both position and tangent
            InterpolationTransform orientation = InterpolationTransform.GetTransform_UpRef(bezierQuadratic, accurateT, MyVector3.Up);

            orientations.Add(orientation);
        }



        //Display

        //Unity doesnt have a built-in method to display an accurate Qudratic bezier, so we have to create our own
        //DisplayInterpolation.DisplayBezierQuadratic(bezierQuadratic, Color.black);
        DisplayInterpolation.DisplayCurve(bezierQuadratic, Color.black);

        //DisplayInterpolation.DisplayCurve(actualPositions, useRandomColor: true);
        DisplayInterpolation.DisplayCurve(actualPositions, Color.gray);

        //Display the start and end values and the handle points
        DisplayInterpolation.DisplayHandle(handle.ToVector3(), posA.ToVector3());
        DisplayInterpolation.DisplayHandle(handle.ToVector3(), posB.ToVector3());


        //Stuff on the curve
        //DisplayInterpolation.DisplayDirections(actualPositions, tangents, 1f, Color.red);

        DisplayInterpolation.DisplayOrientations(orientations, 1f);
    }