给定两点(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

查看:132
本文介绍了给定两点(x1,y1)(x2,y2),如何计算N个不同的点,它们均匀地位于给定点之间的直线上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个点,我想计算在由给定线创建的线顶部的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) and B (Bx, By). The vector spanning from A to B would be given by

V = B − A = <Vx, Vy>
L(t) = A + tV

This essentially means that starting from the point A, we scale the vector V with the scalar t; the point A is displaced by this scaled vector and thus the point we get depends on the value of t, the parameter. When t = 0, we get back A, if t = 1 we get B, if it's 0.5 we get the point midway between A and B.

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 need N to be 10, then you'd have t vary by 1/N, so t = i/10, where i 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 update t in a loop would be

t₀ = 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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆