Search code examples
c++algorithmstretching

How to stretch points?


Let say I've 5 points, where p0 and p4 are fixed with values 0.0 and 4.0:

0 | 1.0 | 2.0 | 3.0 | 4

The points in the middle can change, but they must stretch the others once moving.

So for a stretch "to right", it must enlarge the prev values around the moving point and press the next ones between the moving point and the last point, keeping the proportions between each points.

I've write this code which move the 3° point to 2.5 from its original 2.0 x-position:

const int numPoints = 5;
double points[numPoints] = { 0.0, 1.0, 2.0, 3.0, 4.0 };

int stretchedPoint = 2;
double prevX = points[stretchedPoint];
points[stretchedPoint] = 2.5;

std::cout<< points[0];
for (int prevPoint = 1; prevPoint < numPoints - 1; prevPoint++) {
    // prev points
    if (prevPoint < stretchedPoint) {
        double ratio = points[stretchedPoint] / prevX;
        points[prevPoint] *= ratio;
    // next points
    } else if (prevPoint > stretchedPoint) {
        double ratio = (points[numPoints - 1] - prevX) / (points[numPoints - 1] - points[stretchedPoint]);
        points[prevPoint] *= ratio;
    }

    std::cout << " | " << points[prevPoint];
}
std::cout << " | " << points[numPoints - 1];

which give to me right result for prev points:

0 | 1.25 | 2.5 | 0.76 | 4

but when I try to apply the "same-wrapped-math" for the next points, I get a non-proportional scaling, which give weird results (4?)

Can anyone help me?


Solution

  • You forgot about non-zero starting point

     points[prevPoint] = points[stretchedPoint] + ratio * (points[prevPoint] - prevX)
    

    Note that same logic should be applied to previos points, if start value is non-zero

    In general, to apply linear interpolation for initial X0..X1 interval and final X0new..X1new interval, one have to use

     (Xnew - X0new) / (X1new - X0new) = (X - X0) / (X1 - X0)
     so
     XNew = X0new + (X1new - X0new) * (X - X0) / (X1 - X0)