给定两点(x1,y1)(x2,y2),如何计算N个不同的点,它们均匀地位于给定点之间的直线上 [英] Given two points (x1,y1) (x2,y2), how can I compute N different points evenly lying on the line between the given points
问题描述
我有两个点,我想计算在由给定线创建的线顶部的n个均匀分布的点。如何在C ++中执行此操作?
线性插值(由Graphics社区亲切地称为lerp)是您想要的。给定终点,它可以用参数 t
产生点之间的点。
让终点为 A(Ax,Ay)
和 B(Bx,By)
。从 A
到 B
的矢量将由
V = B - A =< Vx,Vy>
L(t)= A + tV
这实际上意味着从点 A
,我们使用标量 t
来缩放向量 V
;点 A
被这个比例向量所取代,因此我们得到的点取决于 t
的值,参数。当 t = 0
时,我们得到 A
,如果 t = 1
我们得到 B
,如果它是 0.5
,我们得到 A
和 B
。
line A-- - | ---- | ---- | ---- B
t 0¼½¾1
它适用于任何线路(斜率无关紧要)。现在来解决 N
停止的问题。如果你需要 N
为10,那么你会有 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
以下是一种实现它的方法:
#include< iostream>
struct Point {
float x,y;
};
点运算符+(Point const& pt1,Point const& pt2){
return {pt1.x + pt2.x,pt1.y + pt2.y};
}
点运算符 - (Point const& pt1,Point const& pt2){
return {pt1.x - pt2.x,pt1.y - pt2。 y};
}
点标度(Point const& pt,float t){
return {pt.x * t,pt.y * t};
}
std :: ostream&运算符<<(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 < \\\
;
int main(){
lerp({0.0,0.0},{5.0f,5.0f},5.0f);
输出
<$ p (3,3)
(4,4)
(2,2)
(1,1)
(5,5)
Aside
请注意,在每次迭代中, t
都会增加Δt= 1 / N
。因此,在循环中更新 t
的另一种方法是
to = 0
t 1 = t 0 +Δt
t 2 = t 1 +Δt
$
t₉=t₈+Δt
t 10 =t₉+Δt
$ b然而,这并不是很平行,因为循环的每一次迭代都取决于以前的迭代。
I have two points and I would like to compute n evenly distributed points on top of the line created by the given line. How could I perform this in c++?
解决方案Linear interpolation (affectionately called lerp by the Graphics community) is what you want. Given the end points it can generate the points lying in between with a parameter
t
.Let the end points be
A (Ax, Ay)
andB (Bx, By)
. The vector spanning fromA
toB
would be given byV = B − A = <Vx, Vy> L(t) = A + tV
This essentially means that starting from the point
A
, we scale the vectorV
with the scalart
; the pointA
is displaced by this scaled vector and thus the point we get depends on the value oft
, the parameter. Whent = 0
, we get backA
, ift = 1
we getB
, if it's0.5
we get the point midway betweenA
andB
.line A----|----|----|----B t 0 ¼ ½ ¾ 1
It works for any line (slope doesn't matter). Now coming to your problem of
N
stops. If you needN
to be 10, then you'd havet
vary by1/N
, sot = i/10
, wherei
would be the loop iterator.i = 0, t = 0 i = 1, t = 0.1 i = 2, t = 0.2 ⋮ i = 9, t = 0.9 i = 10, t = 1.0
Here's one way to implement it:
#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); }
Output
(0, 0) (1, 1) (2, 2) (3, 3) (4, 4) (5, 5)
Aside
Notice that on every iteration
t
gets incremented byΔt = 1 / N
. Thus another way to updatet
in a loop would bet₀ = 0 t₁ = t₀ + Δt t₂ = t₁ + Δt ⋮ t₉ = t₈ + Δt t₁₀ = t₉ + Δt
However, this isn't very parallelizable since every iteration of the loop would depend on the previous iteration.
这篇关于给定两点(x1,y1)(x2,y2),如何计算N个不同的点,它们均匀地位于给定点之间的直线上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!