Based on the image below, I have a curve (orange) which is a bezier sub-curve of an original curve (longer black curve). The original curve consists of a number of cubic bezier curves joined together. How can I move the sub-curve (which could be contain more than one cubic bezier curve) along it’s original curve whiles preserving its length?
Please note that the original curve/spline could be open or closed curve with the ends joining. I know that arc length is key to achieving this, but I’m not sure to do this.
UPDATE
The smaller curve was reduced using the solution from How to move points of a multi-segmented bezier curve to one side. DMGregory recommended Moving ships between two planets along a bezier, missing some equations for acceleration, which I have to admit I didn’t understand enough to fully utilise to solve my problem. One thing though that I took away from the solution was I needed to express the smaller curve as percentage of the original curve, so I implemented a slider as below.
public void ReplaceCurveWithSubCurve(float curveVal) {
subCurve = IntervalFromTo(curve, 0, curveVal);
}
In CurveEditor:
curveLengthValue = EditorGUILayout.Slider("Curve Length", creator.curveSizeValue, 0f, 1.0f);
if (!Mathf.Approximately(creator.curveSizeValue, curveLengthValue))
{
creator.IntervalFromTo(curveLengthValue);
creator.curveSizeValue = curveLengthValue;
}
My general understanding is the original (full) curve say runs from some t = 0.0
to t = 1.0
and my sub curve at any given point is made of a subset of those values, so I need to change the values along the full curve whiles preserving the arc length. Below are the methods I use to calculate the arc length. My problem is how to tie all this together to arrive at a working solution.
public float SegLength(int segmentIndex)
{
var steps = 10;
var t = 1 / (float)steps;
var sumArc = 0.0f;
var j = 0.0f;
var a = new Vector2(0.0f, 0.0f);
var b = points[segmentIndex * 3];
var dX = 0.0f;
var dY = 0.0f;
var dS = 0.0f;
for (int i = 0; i < steps; j = j + t)
{
a = SegmentAtPoint(segmentIndex, j);
dX = a.x - b.x;
dY = a.y - b.y;
dS = Mathf.Sqrt((dX * dX) + (dY * dY));
sumArc = sumArc + dS;
b.x = a.x;
b.y = a.y;
i++;
}
return sumArc;
}
public float FullLength()
{
var totalLength = 0.0f;
for (int i = 0; i < NumSegments; i++)
{
totalLength += SegLength(i);
}
return totalLength;
}