2011-09-21 234 views
3

我有两个 AB和CD(红色)。这两个部分面对彼此。它们并不完全平行,但永远不会彼此垂直。从这个角度来看,我需要找到这两部分(蓝色)中相互对立的两个法线(即两个法线在ABCD之外)的两个法线如何找到两个相反的法线或两个线段?

)。我知道如何计算线段的法线,但显然每个线段都有两个法线,我无法弄清楚如何以编程方式选择我需要的线段。任何建议?

enter image description here

+0

当段形成一个钝角时,你想要做什么?因此,“外部”和“反对”是不一样的。 –

+0

@Michael J.Barber,它不会发生,因为线段之间的角度始终<90°。 –

回答

1

计算两个段的中点之间的向量v,指向远离AB到CD。现在,所需的法线到AB的投影必须是负的,并且所需的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 

请注意,我假设端点定义满足于问题的条件的线路。当线条具有相同的中点时,也不检查边缘情况;在这种情况下,“外部”的概念不适用。

+0

我不认为这将始终有效(尽管它适用于所有绘制的案例)。在一个段的端点位于另一个段的相对侧的情况下,中点实际上可能位于“错误”的一侧... –

+0

@Darren有趣的点,我假定不相交。但我还没有设法为我提出的方法构建一个反例,但只是在某些情况下,正确的选择不清楚。如果你有一个特定的案例,这将有助于如果你要提供端点。 –

+0

尝试'行1 =(0,0) - >(1,0.25)'和'行2 =(1.25,-0.25) - >(2,2)'。如果我正确理解你的方法,我认为这会给第1行错误的正常。 –

0

如下您可以减少为标志的四种组合:

  1. 计算法线的点积,负号表示,无论显示外部或内部。

    因为我认为你的法线具有单位长度,所以如果点积具有一个量级,则可以检测到并行性。正值表示两者显示方向相同,负值表示两者显示方向不同。

  2. 它的法线不平行:参数化行为x(t) = x0 + t * n为正常的n并且计算两者相交的t。负数t将表明两者都显示在外面。在步骤1中将组合从4减少到2就足够了。

  3. 如果两个法线都是parralel:计算法线到达的中点之间的时间为t您的细分。由于在第2是不够的,如果你这样做了法线的一个,当你从4步减少你的组合,以2 1

1

我认为有两种情况考虑:

情况1:线之间的交点发生在任一段的端点之外。

在这种情况下@Michael J. Barber建议的中点方法肯定会奏效。因此,在片段中点之间形成一个矢量,用这个中点矢量计算法线矢量的点积并检查符号。

如果计算lineA的正常值,则法线与矢量midB -> midA的点积应该是+ve

案例2:行之间的交点出现在一个段的端点内。

在这种情况下,在其中一个端点之间形成一个向量,其中不包括包围交点和交点本身。

做的段正常的点积包围交点,这个新的向量应该是+ve

您可以通过要求两个法线之间的点积为-ve(在垂直线段的情况下这只是不明确的)来找到另一个线段的向外法线。

我假定这些段不共线或实际相交。

希望这会有所帮助。