private void BezierCubicTest(MyVector3 posA, MyVector3 posB, MyVector3 handleA, MyVector3 handleB) { //Store the interpolated values so we later can display them List <Vector3> interpolatedValues = new List <Vector3>(); //Loop between 0 and 1 in steps, where 1 step is minimum //So if steps is 5 then the line will be cut in 5 sections int steps = 20; float t_stepSize = 1f / (float)steps; float t = 0f; //+1 becuase wa also have to include the first point for (int i = 0; i < steps + 1; i++) { //Debug.Log(t); MyVector3 interpolatedPos = BezierCubic.GetPosition(posA, posB, handleA, handleB, t); interpolatedValues.Add(interpolatedPos.ToVector3()); t += t_stepSize; } //The curve DisplayInterpolation.DisplayCurve(interpolatedValues, useRandomColor: true); //The start and end values and the handle points DisplayInterpolation.DisplayHandle(handleA.ToVector3(), posA.ToVector3()); DisplayInterpolation.DisplayHandle(handleB.ToVector3(), posB.ToVector3()); }
//Uses transforms as start and end position, the length of the handles is determines by the z scale of each transform private void BezierCubicTest_Transform(InterpolationTransform transA, InterpolationTransform transB, float scaleA, float scaleB) { MyVector3 posA = transA.position; MyVector3 posB = transB.position; //The forward vector should move along from a to b MyVector3 handleA = posA + transA.Forward * scaleA; MyVector3 handleB = posB + -transB.Forward * scaleB; BezierCubic curve = new BezierCubic(posA, posB, handleA, handleB); //The interpolated values List <Vector3> positions = new List <Vector3>(); List <float> tValues = new List <float>(); //Loop between 0 and 1 in steps, where 1 step is minimum //So if steps is 5 then the line will be cut in 5 sections int steps = 30; float t_stepSize = 1f / (float)steps; float t = 0f; //+1 becuase wa also have to include the first point for (int i = 0; i < steps + 1; i++) { //Debug.Log(t); MyVector3 interpolatedPos = BezierCubic.GetPosition(posA, posB, handleA, handleB, t); positions.Add(interpolatedPos.ToVector3()); tValues.Add(t); t += t_stepSize; } //Different orientation algorithms List <InterpolationTransform> transforms = InterpolationTransform.GetTransforms_InterpolateBetweenUpVectors(curve, tValues, transA.Up, transB.Up); //List<InterpolationTransform> transforms = InterpolationTransform.GetTransforms_UpRef(curve, tValues, transA.Up); //List<InterpolationTransform> transforms = InterpolationTransform.GetTransforms_FrenetNormal(curve, tValues); //List<InterpolationTransform> transforms = InterpolationTransform.GetTransforms_RotationMinimisingFrame(curve, tValues, transA.Up); //The curve DisplayInterpolation.DisplayCurve(positions, useRandomColor: true); //The start and end values and the handle points DisplayInterpolation.DisplayHandle(handleA.ToVector3(), posA.ToVector3()); DisplayInterpolation.DisplayHandle(handleB.ToVector3(), posB.ToVector3()); //Display transform DisplayInterpolation.DisplayOrientations(transforms, 1f); //Mesh Mesh extrudedMesh = ExtrudeMeshAlongCurve.GenerateMesh(transforms, meshProfile, 0.25f); if (extrudedMesh != null && displayMeshFilter != null) { displayMeshFilter.sharedMesh = extrudedMesh; } }
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); }