我想使用numpy.cross
测试两个线段是否大致共线(在同一条线上)。我有每段的米坐标。
import numpy as np
segment_A_x1 = -8020537.5158307655
segment_A_y1 = 5674541.918222183
segment_A_x2 = -8020547.42095263
segment_A_y2 = 5674500.781350276
segment_B_x1 = -8020556.569040865
segment_B_y1 = 5674462.788207927
segment_B_x2 = -8020594.740831952
segment_B_y2 = 5674328.095911447
a = np.array([[segment_A_x1, segment_A_y1], [segment_A_x2, segment_A_y2]])
b = np.array([[segment_B_x1, segment_B_y1], [segment_B_x2, segment_B_y2]])
crossproduct = np.cross(a, b)
>>>array([7.42783487e+08, 1.65354844e+09])
字符串crossproduct
值相当高,即使我会说这两个部分大致共线。为什么?为什么?
如何确定线段是否与crossproduct
结果共线?
是否有可能使用以米为单位的公差来判断线段是否大致共线?
4条答案
按热度按时间ffdz8vbo1#
两个向量
a
和b
的cross-product可以定义为:其中θ
是两个向量之间的Angular 。问题是,即使θ
很小,两个范数的乘积也可能很大,并且可能导致很大的叉积。这是你的案子:字符串
实际上,
sinθ
非常小。这意味着θ
也非常小(实际上,θ
大致等于sinθ
的值,因为sin(θ)
与θ = 1
的导数为1)。如何确定线段是否与叉积结果共线?
您可以根据上面的代码计算值
np.abs(sinθ)
,设置任意阈值并检查该值是否小于所选阈值。阈值的最佳值取决于您的实际应用程序/输入(例如:统计噪声、输入精度、计算精度等)。如果你不知道该使用什么,你可以从1e-4
开始。是否有可能使用以米为单位的公差来判断线段是否大致共线?
请注意,假设输入向量以米为单位,则基于上述公式,叉积的值以平方米为单位。因此,以米为单位的公差没有多大意义。更一般地说,设置一个绝对的公差肯定是一个坏主意.上述解决方案使用相对于输入向量的容差来工作。
64jmpszr2#
共线性有两个方面:段之间的Angular 和接近度。您可以分别测试这些方面,并根据其中任何一个来简化检查。我提出了一个接近度检查,完全消除了Angular 检查的需要。以下显示的Angular 检查是出于传统原因,因为它可能对其他原因有用。
**Angular **
叉积只有在3D中才能真正定义。点积到处都有定义。两个向量之间的Angular 定义为它们的单位向量的点积的反余弦。这适用于2D和10 D。
您可以将两个从原点开始的向量定义为
字符串
angle
将在-np.pi
与np.pi
之间运行.接近pi的Angular 表示反平行线,而接近零的Angular 表示平行线。您可以实现如下测试型
如果您发现自己经常进行这种计算,则可以完全跳过
arccos
,从而保存一些周期。当Angular 变为0或pi时,点积分别变为+1或-1。这意味着您只需要预先计算dot_threshold = np.cos(angular_threshold)
一次:型
接近度
若要测试接近度,您需要定义如何测量距离。对于完全平行的线,这是明确的:这两条线必须在彼此的
distance_threshold
内。对于不完全平行的线,可以执行类似的操作:在一个线段上没有点可以比另一个线段的线的
distance_threshold
更远。使用此定义,您可以将单独Angular 计算的需求直接纳入计算中。请参考下图:
x1c 0d1x的数据
您必须对照其他缐检查所有四个端点。如果您选择这样做,您可以根据距离的差异计算Angular ,并可能根据线段的长度将缩放系数套用至临界值。
您也可以使用点积来计算距离:
型
在我创建的实用程序库
haggis
中有一个更健壮的dist
版本。可以按如下方式使用haggis.math.segment_distance
:型
输入一起广播,
axis
应用于广播的形状,因此您不需要重复两次端点。最简单的测试版本是直接约束距离:
型
可以通过按线段长度缩放来说明Angular 。100倍长的线段可以偏离另一线段的直线100倍,但仍被视为共线。在这种情况下,将
distance_threshold
定义为一个 unit 向量与另一个向量的直线之间的最远距离。该数字必须小于1才有意义:型
这个版本预先假定了我们在两个版本的计算中对
dists
所施加的形状,因为scale
的元素数与dists
的列数一样多。也考虑线段之间的距离的更复杂的方案也是可能的。这种对邻近性的定义留给读者作为练习。
2nc8po8w3#
您的方法的问题在于叉积值取决于测量尺度。
也许共线性的最直观的度量是线段之间的Angular 。让我们计算一下:
个字符
我使用了安德森Oliveira的answer。
nbysray54#
如果您想以有效的方式查看两个向量是否几乎处于同一方向,您还可以尝试以下使用numpy
is_close
进行接近检查的方法,这允许您进一步配置要使用的公差类型以及它的紧密程度。字符串