C++ 给定两个点(x1,y1)(x2,y2),如何计算均匀分布在给定点之间直线上的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

我有两个点,我想计算n个均匀分布的点,位于给定直线创建的直线顶部。如何在C++中执行此操作?< /p> < p>可以使用以下代码> GiViSimple PosithPosix介于(m,n,NoMyPosits)< /C> >,它给出了<代码> > No.PosithPo> <代码> > <代码> m>代码>和<代码> n>代码>。这里我假设这条线不是垂直的(如果这条线可以是垂直的,请参见下文)

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>();
}