簡體   English   中英

找到兩個坐標之間的等距點

[英]Find equidistant points between two coordinates

我有一個功能需要取出屏幕上兩點之間的等距點(2d)。
像這樣 -

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

距離已經確定。 例如,我把它當作2 ,然后我需要的點 -

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

這些點可以在2d平面上的任何位置,這意味着如果我在兩個點​​之間畫一條線,它可以是2d平面中的任何方向,即對角線,水平等。
我無法弄清楚如何在python中執行此操作。

我不知道該怎么去谷歌...我14歲所以我不知道任何類型的數學。
我知道如何計算線的距離和斜率,但我不知道如何繼續。
提前致謝!

給定兩個端點,您可以將“參數”形式的線表示為

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)位於連接線段上,並且為了獲得點之間距離的某一部分,將t設置為該分數。

例如,如在示例中那樣在距離10線上獲得具有間隔2的點,則在t = 0.2,0.4,0.6和0.8處評估xy

這最容易使用線的參數表示來解決,其涉及字母向量數學。 但不要擔心,這很容易。

假設您的行由以下公式明確指定:

y=ax+b

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

然后你的線有一個方向由矢量<1,a> ,這意味着該線在水平運行的每1單位上升m單位。

我們可以通過除以它的大小來標准化該向量。

矢量的大小由下式給出

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的線算法為您繪制圖形 - 當您有一個像素網格時,這是一種很好的方法來確定逼近線條的最佳方法。

而且,如果您在屏幕上繪制字符,您可能會對ANSI轉義碼感興趣,它可用於移動光標,顯示顏色和清除屏幕。

你需要做的是在兩點之間進行插值

例如,假設您的兩個端點具有坐標(x1, y1)(x2, y2) ,並且您希望將它們之間的距離分成n相等的部分,那么您可以計算它們之間的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) )

這里, a是內插點在原始點之間的線上的位置,按比例縮放,使得值a = 0a = 1對應於原始點本身。


或者,如果你想讓你的插值點相隔固定距離d ,那么你可以使用畢達哥拉斯定理計算原始點之間的距離d_full ,將d除以該距離得到s = d / d_full ,然后增加a s從0到1的步驟:

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 - s/2替換條件a < 1

編輯:上面的代碼以d為間隔放置點, (x1, x2) 這意味着如果,例如, d = 2且原始點位於(0,0)(0,5) ,您將獲得(0,2)(0,4)處的新點。 如果您希望新點在原始點之間居中(即示例中的(0,1)(0,3) ),您可以通過替換起點來修改代碼來實現這一點a = s a = (1 % s) / 2

%模數或余數運算符,因此在從0到1的距離被分割為長度為s片段之后, 1 % s給出剩余距離“剩余”。

暫時忘記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(math.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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM