Как растянуть точки?

Допустим, у меня есть 5 точек, где p0 и p4 зафиксированы значениями 0.0 и 4.0:

0 | 1.0 | 2.0 | 3.0 | 4

Точки в середине могут меняться, но они должны растягивать другие, когда они двигаются.

Так что для stretch «направо», оно должно enlarge предыдущие значения вокруг движущейся точки и press следующие между движущейся точкой и последней точкой, сохраняя пропорции между каждой точкой.

Я написал это код которые перемещают точку 3 ° к 2.5 от своего оригинала 2.0 х-положение:

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];

которые дают мне правильный результат для предыдущих баллов:

0 | 1.25 | 2.5 | 0.76 | 4

но когда я пытаюсь применить «same-wrapped-math» для следующих точек, я получаю непропорциональное масштабирование, которое дает странные результаты (4?)

Может кто-нибудь мне помочь?

0

Решение

Вы забыли о ненулевой отправной точке

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

Обратите внимание, что та же логика должна применяться к предыдущим точкам, если начальное значение не равно нулю

В общем, применять линейную интерполяцию для начального X0..X1 интервал и финал X0new..X1neинтервал w, нужно использовать

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

Другие решения

То, что вы сделали с левой стороны точки (и что работает), можно переписать примерно так:

//  double ratio = (points[stretchedPoint] - 0) / (prevX - 0);
//  points[prevPoint] = 0 + ratio * (points[prevPoint] - 0);

Чтобы добиться именно двойного на правой стороне, оно должно быть:

} else if (prevPoint > stretchedPoint) {
double ratio = (points[numPoints - 1] - points[stretchedPoint]) /
(points[numPoints - 1] - prevX);
points[prevPoint] = points[numPoints - 1] -
ratio * (points[numPoints-1] - points[prevPoint]);
}
1

По вопросам рекламы [email protected]