我有一个功能需要取出屏幕上两点之间的等距点(2d) 像这样 -
|--------------|
距离已经确定。例如,我在此处将其视为2
,然后是我需要的点 -
|--.--.--.--.--|
这些点可以在2d平面上的任何位置,这意味着如果我在两个点之间画一条线,它可以是2d平面中的任何方向,即对角线,水平等。
我无法弄清楚如何在python中做到这一点。
我不知道该为什么谷歌...我14岁所以我不知道任何类型的数学。
我知道如何计算线的距离和斜率,但我不知道如何继续。
提前谢谢!
答案 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处评估x
和y
。
答案 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
。这样我们就可以分别处理等式的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'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) )
是原始点之间的线上插值点的位置,按比例缩放,以便值a
和a = 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)