我写了一个算法,灵感来自StackOverflow上的一些答案:它检测到距离无限线很远的点。该算法如下所示。
但是,我在项目中不使用无限行,而是使用段。根据我的说法,问题在于,如果一个点的纵坐标与段的末端相同,则不会被视为“远离该段”。
我如何修改此算法以使其与段一起使用,而不是无限行呢?
List<Cupple> returned = new ArrayList<>(points_to_test);
for(Cupple c : points_to_test) {
/*if(c == segment_first_point || c == segment_last_point) {
continue;
}*/
if(Math.abs(Math.abs(
(segment_last_point.getNumber(0) - segment_first_point.getNumber(0))
*
(segment_first_point.getNumber(1) - c.getNumber(1))
-
(segment_first_point.getNumber(0) - c.getNumber(0))
*
(segment_last_point.getNumber(1) - segment_first_point.getNumber(1))
)
/
Math.sqrt(
Math.pow((segment_last_point.getNumber(0) - segment_first_point.getNumber(0)), 2)
+
Math.pow((segment_last_point.getNumber(1) - segment_first_point.getNumber(1)), 2)
)
) > maximal_allowed_distance) {
returned.remove(c);
}
}
return returned;
确定你理解:
returned
是包含在段上或段附近的点的列表(以及确定点是否在段之外的“不精确”/最大距离是变量:{ {1}})
maximal_allowed_distance
是我的图表中存在的所有点:我的段+段中真正的点+几乎在段上的点(&lt; = { {1}})+远离细分的点(&gt; points_to_test
)。 我的小算法的想法是我删除所有后者。
maximal_allowed_distance
是两段的极端
maximal_allowed_distance
是segment_[first|last]_point
的当前点,我想知道它是远离段还是(根据c
)
points_to_test
返回该点的X坐标,maximal_allowed_distance
返回Y值。
getNumber(0)
如您所见,对于Segment:(1; 2; 0) - (1; 0; 0),点(1; 1; 0)被认为距离它太远。但是,它必须被视为该细分市场的一部分。
答案 0 :(得分:2)
该线上的任何点都可以用等式表示:
v = a + k (b - a)
将您的点投影到该线上并确定k
的值。然后,您可以根据k
(k < 0
中的k
,[0, 1]
和k > 1
中的x
的值以及一些几何来设置一些基本逻辑来计算距离来自细分市场。
修改:要进一步展开,因为我发现它有点简洁
我将用单个字母表示矢量变量,因为我不想将其展开。将代表点积。
您有一个点p
,您希望在该行上查看其投影p = ((x - a).(b - a))/((b - a).(b - a)) (b - a) + a
,然后通过上面的公式表示:
k
从这个公式中,我们可以看到k = ((x - a).(b - a))/((b - a).(b - a))
的值将是这里的系数:
k < 0
现在,如果||x - a||
,您需要k
,如果[0, 1]
||x - p||
,那么您将需要k > 1
如果距离是||x - b||
,则需要k
编辑2:
为了澄清,虽然我使用单个字母作为我的矢量变量,但我也使用单个字母表示p
,但它应该被认为是一个标量。请注意,它只是由点积产生的,所以只能采用标量值。例如,如果我们想将(p_x, p_y)
分解为组件 p_x = k * (b_x - a_x) + a_x
p_y = k * (b_y - a_y) + a_y
np.array([
[23, 12, 4, 103, 87, 0.6],
[32, 18, 3, 120, 70, 0.6],
[43, 12, 8, 109, 89, 0.4],
[20, 13, 7, 111, 77, 0.8]
])
答案 1 :(得分:2)
1)计算您正在测试的点p
的无限线(a,b)
上的点t
。
2)计算p
距离您正在测试的点t
的距离,如果距离太远则丢弃它。
3)如果(a,b)
的x坐标不相等,则检查p
的x坐标是否在a
的x坐标范围内{ {1}}。如果是这样,请保持重点。如果没有,请从b
到t
和a
进行距离检查,如果两者都不在最大允许距离范围内,则将其丢弃。
4)如果b
的x坐标相等,除了比较y坐标外,与步骤3相同。