2D多边形顶点法线面向内/外?

时间:2014-10-24 16:06:46

标签: algorithm 2d polygon segment

我想测试矢量(实际上是多边形顶点法线)是朝外还是内部。多边形缠绕CW,边缘从A(实心圆)到B(描边圆)。我有这些法线是初步计算的结果,现在我想测试他们的面孔。

enter image description here

喜欢这个。灰色法线应无效,而绿色法线应验证。可能我可以通过计算角度来做到,然后简单地比较它们,但我真的想在这里备用三角函数。

是否有任何便宜的方法只比较"斜率"不知何故? 像这样的http://bryceboe.com/2006/10/23/line-segment-intersection-algorithm/

中的Bryce Boe CCW算法

3 个答案:

答案 0 :(得分:1)

边矢量与法线矢量的叉积符号将告诉您法线矢量指向边的哪一侧。

计算(Xb - Xa).Ny - (Yb - Ya).Nx

这适用于凸多边形。

对于一般多边形,您必须将法线的支撑线与多边形轮廓相交;你会发现偶数个交叉点(有些可能是两倍);通过将它们连接成偶数,您将知道线的哪些部分在内部或外部。

enter image description here

答案 1 :(得分:1)

如果你将法线向量与由段的两个点形成的向量(从头到尾是顺时针方向)一起取得,那么要从段向量到正常,你必须逆时针移动。调用正常N和段向量S,逆时针检查变为:

if(cross(S, N) > 0)
   // Bad
else
   // Good

交叉产品以这种方式计算:

int cross(Vector p, Vector q)
{   return (p.x*q.y - p.y*q.x);
}

因此,如果法线是N =(0,1)并且S =(1,0),则叉积给出1 * 1-0 * 0 = 1> 0。 0,这告诉你正常指出。

答案 2 :(得分:0)

其他人建议的交叉产品标志测试是解决方案。

public static bool PointIsLeftOfSegment(Vector2 point, Vector2 a, Vector2 b)
{
    float crossProduct = (b.x - a.x) * (point.y - a.y) - (b.y - a.y) * (point.x - a.x);
    return (crossProduct > 0.0f);
}

对于原始问题,我为两个片段组成了测试(同时考虑锐角)。

bool acute = segmentA.IsPointLeft(segmentB.b);
bool leftA = segmentA.IsPointLeft(point);
bool leftB = segmentB.IsPointLeft(point);
bool outward = (acute) ? leftA && leftB : leftA || leftB;
bool inward = !outward;

Testbed就好了:https://vine.co/u/1137617915458592768