找到两个坐标之间的等距点

时间:2014-01-04 16:58:48

标签: python algorithm geometry points

我有一个功能需要取出屏幕上两点之间的等距点(2d) 像这样 -

|--------------|

距离已经确定。例如,我在此处将其视为2,然后是我需要的点 -

|--.--.--.--.--|

这些点可以在2d平面上的任何位置,这意味着如果我在两个点​​之间画一条线,它可以是2d平面中的任何方向,即对角线,水平等。
我无法弄清楚如何在python中做到这一点。

我不知道该为什么谷歌...我14岁所以我不知道任何类型的数学。
我知道如何计算线的距离和斜率,但我不知道如何继续。
提前谢谢!

4 个答案:

答案 0 :(得分:6)

给定两个端点,您可以将“参数”形式的线表示为

x = x1 + (x2-x1) * t
y = y1 + (y2-y1) * t

您可以在t == 0(x,y) == (x1,y1)t == 1(x,y) == (x2,y2)时进行验证。通过更多调查,您可以看到当t介于0和1之间时,(x,y)位于连接线段上,并且为了获得点之间距离的某一部分,请设置{{1到那个分数。

例如,要像在示例中那样在距离10行上获得具有分隔2的点,请在t = 0.2,0.4,0.6和0.8处评估xy

答案 1 :(得分:2)

这最容易使用线的参数表示来解决,其涉及字母矢量数学。但不要担心,这很容易。

假设您的行由以下公式明确指定:

y=ax+b

其中a是斜率,b是y轴截距。

然后,您的行具有向量<1,a>给出的方向,这意味着该行在水平运行的每个m单位上升1个单位。

我们可以通过除以它的大小来规范化这个向量。

矢量的大小由

给出
m=sqrt(a**2+b**2)

归一化向量由v=<1/m,a/m>给出。

现在,我们可以按如下方式绘制您的行:

for t in range(50):
  xp=0+t*v[0]
  yp=b+t*v[1]
  plot_point(xp,yp,'-')

你看我在那里做了什么?我将正在循环的变量从x更改为t。这样我们就可以分别处理等式的xy部分。

如果我的线已被其终点指定,我可以改为编写如下公式:

for t in range(0,1,0.01):
  xp=x1+t*(x2-x1)
  yp=y1+t*(y2-y1)
  plot_point(xp,yp,'-')

由于x1是该行的x部分的起点,x2-x1是行x点之间的距离,因为t0走到1,它会传递该行的所有x点。 y的工作方式类似。

现在,我们可以抽象我们的线条绘制功能,使它看起来像这样:

def draw_line(a,b,len,skip,sym):
  m=sqrt(a**2+b**2)
  v=(1/m,a/m)
  for t in range(0,len,skip):
    xp=0+t*v[0]
    yp=b+t*v[1]
    plot_point(xp,yp,sym)

现在,我们通过输入以下内容来绘制您的行:

draw_line(a,b,50,1,'-')

划出差距
draw_line(a,b,50,3,'.')

其中50是行的长度,3是间隙之间的距离。

如果我们使用了该行的起点和终点,我们的函数将如下所示:

def draw_line(x1,y1,x2,y2,skip,sym):
  dist=sqrt((x1-x2)**2)+(y1-y2)**2)
  skip=skip/dist
  for t in range(0,1,skip):
    xp=x1+t*(x2-x1)
    yp=y1+t*(y2-y1)
    plot_point(xp,yp,sym)

这会将您要跳过的距离转换为线条总长度的一部分。您可能希望使用1或更小的跳过值来绘制线,使用更大的跳过值来取出等距点。

您可能希望使用Bresenham's Line Algorithm来为您绘制图形 - 当您有一个像素网格时,这是一种很好的方法来计算逼近线条的最佳方法。

而且,如果你在屏幕上绘制字符,你可能会对ANSI escape codes感兴趣,它可以用来移动光标,显示颜色和清除屏幕。

答案 2 :(得分:2)

您需要做的是interpolate两点之间。

例如,假设您的两个端点的坐标为(x1, y1)(x2, y2),并且您希望将它们之间的距离分成n个相等的部分,然后您可以计算{{1他们之间的新点如下:

n-1

此处,points = [] for i in range(1, n): a = float(i) / n # rescale 0 < i < n --> 0 < a < 1 x = (1 - a) * x1 + a * x2 # interpolate x coordinate y = (1 - a) * y1 + a * y2 # interpolate y coordinate points.append( (x,y) ) 是原始点之间的线上插值点的位置,按比例缩放,以便值aa = 0对应于原始点本身。


或者,如果您想让插值点与固定距离a = 1分开,则可以使用Pythagorean theorem计算原始点之间的距离d,除以{{1通过该距离获取d_full,然后以d从0到1的步长递增s = d / d_full

a

请注意,这可能会导致新点位于s或非常靠近它,具体取决于d_full = ( (x2 - x1)**2 + (y2 - y1)**2 )**0.5 s = d / d_full points = [] a = s # start at s so we don't duplicate (x1, y1) while a < 1: x = (1 - a) * x1 + a * x2 y = (1 - a) * y1 + a * y2 points.append( (x,y) ) a += s 对点之间距离的确切程度。如果您想避免这种情况,可以将条件(x2, y2)替换为d

修改:上面的代码会在a < 1处以a < 1 - s/2 的间隔开始。这意味着,如果d和原始点位于(x1, x2)d = 2,您将获得(0,0)(0,5)的新积分。 如果您希望新点在原始点之间居中(例如,在示例中为(0,2)(0,4)),则可以通过替换起点{{}修改代码来执行此操作。 1}}与(0,1)

(0,3)modulo或余数运算符,因此{0}给出了从0到1的距离被分割为长度为{{a = s之后的剩余距离。 1}}。

答案 3 :(得分:1)

暂时忘记python方面,我们可以看看所需的数学。有可能在14岁时你已经涵盖了其中的一部分,但可能没有意识到它适用,我们需要的是一些三角法。

让我们把两点放在计划上

Point 1 = (x1,y1)
Point 2 = (x2,y2)

想象一下,这两个点是三角形直角三角形的角,第三个虚点构成三角形的第三个角。

P1-----I
  -    |
   -   |
    -  |
     -P2

在P1和P2之间移动时找到点。

Start point = P1 (x1,y1)
First point = (x1+u,y1+t)S
Second point = (x1+2u,y1+2n)
Nth point = (x1+nu,y1+nu)

我们需要u和t的值。为了解决这些问题,我们首先需要从P1的起点开始角度(轴承移入)。 atan2函数可以用弧度来获取这个方位。

import math
bearing = math.atan2(y2-y1,x2-x1)

如需进一步阅读,请参阅(http://en.wikipedia.org/wiki/Atan2

鉴于方位,我们现在可以使用sin和余弦来计算u和t的值。这些函数基本上给出了每个步骤在x轴和y轴上的总移动量的比率。

u = d * cos(bearing)
t = d * sin(bearing)

其中d是固定距离。

看一下教科书中sin和cos函数的定义 - 在python中,看看当你从sin(0)移动到sin(math.pi)和cos(0)到cos(数学)时会发生什么。 PI)。

总的来说,我们的脚本看起来像这样

import math
#CONSTANTS -- modify these 
POINT1 = (0,0)
POINT2 = (10,10)
STEP_SIZE = 2

dx = POINT2[0] - POINT1[0]
dy = POINT2[1] - POINT1[1]

bearing = math.atan2(dy,dx)
print "Bearing: {b}".format(b=bearing)
#Use pythagoras to work out the distance
distance_between_points = math.sqrt(dx**2+dy**2) 

for p in range(0,int(round(distance_between_points,0)),STEP_SIZE):
    x = POINT1[0] + p * math.cos(bearing)
    y = POINT1[1] + p * math.sin(bearing)
    print "Intermediate point {x},{y}".format(x=x,y=y)