线性插值(图形社区亲切地称为lerp)就是你想要的.给定端点,它可以用参数生成介于两者之间的点t.
让终点为A (Ax, Ay)和B (Bx, By).从跨越的载体A,以B由下式给出
V = B ? A = <Vx, Vy>
L(t) = A + tV
Run Code Online (Sandbox Code Playgroud)
这基本上意味着从这一点开始A,我们V用标量缩放向量t; 该点A被这个缩放的矢量所取代,因此我们得到的点取决于t参数的值.当t = 0我们回来A,如果t = 1我们得到B,如果这是0.5我们得到的中间点A和B.
line A----|----|----|----B
t 0 ¼ ½ ¾ 1
Run Code Online (Sandbox Code Playgroud)
它适用于任何线路(坡度无关紧要).现在来看你的N停止问题.如果你需要N10,那么你就会t变化1/N,所以t = i/10,i循环迭代器在哪里.
i = 0, t = 0
i = 1, t = 0.1
i = 2, t = 0.2
?
i = 9, t = 0.9
i = 10, t = 1.0
Run Code Online (Sandbox Code Playgroud)
这是实现它的一种方法:
#include <iostream>
struct Point {
float x, y;
};
Point operator+ (Point const &pt1, Point const &pt2) {
return { pt1.x + pt2.x, pt1.y + pt2.y };
}
Point operator- (Point const &pt1, Point const &pt2) {
return { pt1.x - pt2.x, pt1.y - pt2.y };
}
Point scale(Point const &pt, float t) {
return { pt.x * t, pt.y * t };
}
std::ostream& operator<<(std::ostream &os, Point const &pt) {
return os << '(' << pt.x << ", " << pt.y << ')';
}
void lerp(Point const &pt1, Point const &pt2, float stops) {
Point const v = pt2 - pt1;
float t = 0.0f;
for (float i = 0.0f; i <= stops; ++i) {
t = i / stops;
Point const p = pt1 + scale(v, t);
std::cout << p << '\n';
}
}
int main() {
lerp({0.0, 0.0}, {5.0f, 5.0f}, 5.0f);
}
Run Code Online (Sandbox Code Playgroud)
(0, 0)
(1, 1)
(2, 2)
(3, 3)
(4, 4)
(5, 5)
Run Code Online (Sandbox Code Playgroud)
请注意,每次迭代t都会增加?t = 1 / N.因此,t在循环中更新的另一种方法是
t? = 0
t? = t? + ?t
t? = t? + ?t
?
t? = t? + ?t
t?? = t? + ?t
Run Code Online (Sandbox Code Playgroud)
但是,这不是很可并行化,因为循环的每次迭代都取决于前一次迭代.