我有两段AB 和 CD(红色)。这两个部分彼此面对。它们并不完全平行,但也永远不会相互垂直。
由此,我需要找到这些段的两条法线(蓝色),它们彼此相对(即两条法线在 ABCD 之外)。我知道如何计算线段的法线,但显然每个线段都有两个法线,我无法弄清楚如何以编程方式选择我需要的法线。有什么建议吗?
我认为有两种情况需要考虑:
情况 1:线之间的交点发生在任一线段的端点之外。
在这种情况下,@Michael J. Barber 建议的中点方法肯定会起作用。所以在段的中点之间形成一个向量,用这个中点向量计算你的法线向量的点积并检查符号。
如果您正在计算 的法线lineA
,则法线与向量的点积midB -> midA
应该是+ve
。
情况 2:线之间的交点发生在一个线段的端点内。
在这种情况下,在不包围交点的线段的任一端点与交点本身之间形成一个向量。
包含交点的线段的法线与这个新向量的点积应该是+ve
。
您可以通过要求两条法线之间的点积为-ve
(仅在垂直线段的情况下才模棱两可)来找到另一段的向外法线。
我假设这些段不是共线或实际相交的。
希望这可以帮助。
计算两个线段中点之间的向量 v,从 AB 指向 CD。现在,所需法线到 AB 到 v 上的投影必须是负的,而所需法线到 CD 到 v 上的投影必须是正的。因此,只需计算法线,检查 v,并在需要时取反法线以使其满足条件。
这是在Python中:
# use complex numbers to define minimal 2d vector datatype
def vec2d(x,y): return complex(x,y)
def rot90(v): return 1j * v
def inner_prod(u, v): return (u * v.conjugate()).real
def outward_normals(a, b, c, d):
n1 = rot90(b - a)
n2 = rot90(d - c)
mid = (c + d - a - b) / 2
if inner_prod(n1, mid) > 0:
n1 = -n1
if inner_prod(n2, mid) < 0:
n2 = -n2
return n1, n2
请注意,我假设端点定义了满足问题条件的线。当线条具有相同的中点时,我也不检查边缘情况;“外部”的概念不适用于这种情况。
您可以减少符号的四种组合,如下所示:
计算法线的点积,负号表示都显示在外面或里面。
正如我假设您的法线具有单位长度一样,如果点积的量级为 1,您可以检测到平行度。正值表示两个方向相同,负值表示两个方向不同。
如果法线不平行:将线参数化为x(t) = x0 + t * n
法线n
并计算t
两者相交的线。负数t
表示两者都显示在外面。如果您对其中一条法线执行此操作就足够了,因为您在步骤 1 中将组合从 4 减少到 2。
如果两条法线都是平行的:计算法线到达t
两段之间的中点的时间。如果您对其中一条法线执行此操作,如 2. 中所述就足够了,因为您在步骤 1 中将组合从 4 减少到 2。