C++ 给定两个点(x1,y1)(x2,y2),如何计算均匀分布在给定点之间直线上的N个不同点
我有两个点,我想计算n个均匀分布的点,位于给定直线创建的直线顶部。如何在C++中执行此操作?< /p> < p>可以使用以下代码> GiViSimple PosithPosix介于(m,n,NoMyPosits)< /C> >,它给出了<代码> > No.PosithPo> <代码> > <代码> m>代码>和<代码> n>代码>。这里我假设这条线不是垂直的(如果这条线可以是垂直的,请参见下文)C++ 给定两个点(x1,y1)(x2,y2),如何计算均匀分布在给定点之间直线上的N个不同点,c++,math,geometry,line,point,C++,Math,Geometry,Line,Point,我有两个点,我想计算n个均匀分布的点,位于给定直线创建的直线顶部。如何在C++中执行此操作?< /p> < p>可以使用以下代码> GiViSimple PosithPosix介于(m,n,NoMyPosits)< /C> >,它给出了 > No.PosithPo> > m>代码>和 n>代码>。这里我假设这条线不是垂直的(如果这条线可以是垂直的,请参见下文) std::vector在(常量点&M、常量点&N、常量无符号数点)之间给出统一点{ std::向量结果; //得到方程y=ax+b
std::vector在(常量点&M、常量点&N、常量无符号数点)之间给出统一点{
std::向量结果;
//得到方程y=ax+b
浮动a=(N.y-M.y)/(N.x-M.x);
浮动b=N.y-a*N.x;
浮动步长=标准::晶圆厂(M.x-N.x)/num_点;
对于(浮动x=std::min(M.x,N.x);x
演示:
结果是:
(-3,9);(-2.3,7.6);(-1.6,6.2);(-0.9,4.8);(-0.2,3.4);(0.5,2);(1.2,0.6);(1.9,-0.8);(2.6,-2.2);(3.3,-3.6);
解释
从两点(x1,y1)
和(x2,y2)
可以猜出通过这些点的直线方程
该方程的形式为a*x+b*y+c=0
其中a=(y2-y1)/(x2-x1)
,然后推导出b,如代码所示
然后,您可以沿直线以最小值坐标为起点改变x
或y
所有这些
(x,y)
点都在您的线路上,应该均匀分布(由于固定的步骤)。您可以使用以下在(M,N,num\u点)之间给出统一的点,它给出了M
和N
之间的许多num\u点。这里我假设这条线不是垂直的(如果这条线可以是垂直的,请参见下文)
std::vector在(常量点&M、常量点&N、常量无符号数点)之间给出统一点{
std::向量结果;
//得到方程y=ax+b
浮动a=(N.y-M.y)/(N.x-M.x);
浮动b=N.y-a*N.x;
浮动步长=标准::晶圆厂(M.x-N.x)/num_点;
对于(浮动x=std::min(M.x,N.x);x
演示:
结果是:
(-3,9);(-2.3,7.6);(-1.6,6.2);(-0.9,4.8);(-0.2,3.4);(0.5,2);(1.2,0.6);(1.9,-0.8);(2.6,-2.2);(3.3,-3.6);
解释
从两点(x1,y1)
和(x2,y2)
可以猜出通过这些点的直线方程
该方程的形式为a*x+b*y+c=0
其中a=(y2-y1)/(x2-x1)
,然后推导出b,如代码所示
然后,您可以沿直线以最小值坐标为起点改变x
或y
所有这些(x,y)
点都位于直线上,并且应该均匀分布(由于固定的步骤)。将直线视为(x1,y1)+λ(x2-x1,y2-y1),即第一个点加上它们之间向量的倍数
当λ=0时有第一个点,当λ=1时有第二个点。
所以你只需要取n个分布均匀的λ值,在0和1之间
你如何做到这一点取决于你所说的中间点:是否包括终点
例如,你可以取λ=0/(n-1),λ=1/(n-1),λ=2/(n-1)。。。λ=(n-1)/(n-1)。
这将给出n个均匀分布的点,包括端点
或者你可以取λ=1/(n+1),λ=2/(n+1)。。。λ=n/(n+1)。
这将给出n个均匀分布的点,不包括端点。将直线视为(x1,y1)+λ(x2-x1,y2-y1),即第一个点加上它们之间向量的倍数
当λ=0时有第一个点,当λ=1时有第二个点。
所以你只需要取n个分布均匀的λ值,在0和1之间
你如何做到这一点取决于你所说的中间点:是否包括终点
例如,你可以取λ=0/(n-1),λ=1/(n-1),λ=2/(n-1)。。。λ=(n-1)/(n-1)。
这将给出n个均匀分布的点,包括端点
或者你可以取λ=1/(n+1),λ=2/(n+1)。。。λ=n/(n+1)。
这将产生n个均匀分布的点,不包括端点。(图形社区亲切地称为lerp)是您想要的。给定端点,它可以使用参数t
生成介于两者之间的点
设端点为A(Ax,Ay)
和B(Bx,By)
。从A
到B
的向量由下式给出
V = B − A = <Vx, Vy>
L(t) = A + tV
它适用于任何直线(坡度无关紧要)。现在来谈谈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 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);
}
在一边
注意,在每次迭代中,t
都会增加Δt=1/N
。因此,在循环中更新t
的另一种方法是
t₀ = 0
t₁ = t₀ + Δt
t₂ = t₁ + Δt
⋮
t₉ = t₈ + Δt
t₁₀ = t₉ + Δt
然而,这并不是非常可并行化,因为循环的每个迭代都依赖于上一个迭代。(图形社区亲切地称为lerp)是您想要的。给定端点,它可以使用参数t
生成介于两者之间的点
设端点为A(Ax,Ay)
和B(Bx,By)
。从A
到B#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);
}
(0, 0)
(1, 1)
(2, 2)
(3, 3)
(4, 4)
(5, 5)
t₀ = 0
t₁ = t₀ + Δt
t₂ = t₁ + Δt
⋮
t₉ = t₈ + Δt
t₁₀ = t₉ + Δt
vector<Rect> Utils::createReactsOnLine(Point pt1, Point pt2, int numRects, int height, int width){
float x1 = pt1.x;
float y1 = pt1.y;
float x2 = pt2.x;
float y2 = pt2.y;
float x_range = std::abs(x2 - x1);
float y_range = std::abs(y2 - y1);
// Find center points of rects on the line
float x_step_size = x_range / (float)(numRects-1);
float y_step_size = y_range / (float)(numRects-1);
float x_min = std::min(x1,x2);
float y_min = std::min(x1,x2);
float x_max = std::max(x1,x2);
float y_max = std::max(x1,x2);
cout << numRects << endl;
float next_x = x1;
float next_y = y1;
cout << "Next x, y: "<< next_x << "," << next_y << endl;
for(int i = 0; i < numRects-1; i++){
if (x1 < x2)
next_x = next_x + x_step_size;
else
next_x = next_x - x_step_size;
if (y1 < y2)
next_y = next_y + y_step_size;
else
next_y = next_y - y_step_size;
cout << "Next x, y: "<< next_x << "," << next_y << endl;
}
return vector<Rect>();
}