检查由3个点定义的角度是内部还是外部

时间:2012-09-12 23:45:56

标签: c++ math geometry convex concave

在给定一组折线的情况下,我发现角度类型的检测存在问题(无论是内部还是外部是否是轴的原点)。 我发现了几十个非常相似的问题,但是没有一个问题解决了我的问题,所以我把它放在这里希望能有一些问题出现。

classification of angles

我所拥有的是一组折线。我需要找到角度(给定的公差接近矩形),并将它们分类为内部外部

对于每条折线,我将顶点3乘3,我能够识别中心点是否是角度,并将其值测量为0到180度之间的数字。

现在我需要给这个角度一个方向(让我们说一个符号,如果急性瞄准远离原点则为负,如果它朝向中心则为正),我想我会用其中一个实现它。以下2种方法,但没有一种方法有效。

1)只是'2d交叉产品的标志'(我知道这不是数学上正确的术语):

//given 3 contiguous vertices a,b,c
//check if b is a inner (+1) or outer (-1) vertex (0 in other cases)

double cross = ((b.x - a.x)*(c.y - a.y)) - ((b.y - a.y)*(c.x - a.x));

if(cross > 0){
  return 1;
} else if (cross < 0) {
  return -1;
}
return 0;

但它似乎只能在左下象限中起作用,在右上方完全以相反的方式起作用,而它在其他方面起作用,我无法理解为什么。

2)比较顶点的范数

if b.norm() < a.norm() && b.norm() < c.norm 
then return +1
else return -1

这仅适用于基本情况,并且整体上没有穿过轴的折线(包含原点)。我可以查看所有案例,但我宁愿避免这种情况。

显然,有更安全的方法,例如检查顶点是否位于原点的同一侧,而不是位于2个向量上的2个邻居之间的线路。但我需要尽可能地优化它

3 个答案:

答案 0 :(得分:4)

简短版本:

将来自中心点的两个角度向量描述为ab。并将中心点到原点的矢量描述为center

如果出现以下情况,角度将被描述为“内部”:

dot( a + b, center ) > 0.0 && dot( cross( a, center ), cross( b, center ) ) < 0.0

解释:

这可以通过同时使用交叉产品点积来解决。 (幸运的是,没有任何角度。这可以通过添加,乘法和比较完全解决。)

在这里,分两步解决。

<强> 1。角度指向更多朝向原点而不是远离

如果通过对两个角度向量求和来定义“角度指向的方向”,则角度指向指向而不是

请注意,如果 a b 的各个长度不同,则可能会出现一些不正确的边缘情况广角。规范化 a b 将解决此问题。

`dot( a + b, center ) > 0.0`

<强> 2。向量ab是否指向原点的相对侧?

如果他们的交叉积指向相反的方向,则ab指向原点的相对侧。

`dot( cross( a, center ), cross( b, center ) ) < 0.0`

当且仅当这两者都为真时,你的角度被定义为“内在”。

答案 1 :(得分:3)

要检测角度abc是否在内部,您必须检查向量b0(从b到原点)是否是向量ba和bc的凸组合。

如果向量px + qy是向量p1x + q1y和p2x + q2y的凸组合,则存在正常数r和s,使得r *(p​​1,q1)+ s *(p2,q2)=(p ,q)。如果我们用代数求解r和s,我们得到r =(pq2-p2q)/(p1q2-q1p2)和s =(p1q-pq1)/(p1q2-q1p2)。如果r和s都是正数,则abc是内部的。

答案 2 :(得分:0)

就个人而言,我只会使用点积。具体来说(如果a代表你的顶点的向量bc是你的边缘向量指向的顶点),如果a dot ba dot c均为正,则角度为外。否则就是内心。

但我对你对'内在'和'外在'的真正定义感到有点困惑......