[英]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處評估x
和y
。
這最容易使用線的參數表示來解決,其涉及字母向量數學。 但不要擔心,這很容易。
假設您的行由以下公式明確指定:
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
。 這允許我們分別處理方程的x
和y
部分。
如果我的線已被其端點指定,我可以改為編寫如下公式:
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點之間的距離,當t
從0
走到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 = 0
和a = 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.