在给定一组折线的情况下,我发现角度类型的检测存在问题(无论是内部还是外部是否是轴的原点)。 我发现了几十个非常相似的问题,但是没有一个问题解决了我的问题,所以我把它放在这里希望能有一些问题出现。
我所拥有的是一组折线。我需要找到角度(给定的公差接近矩形),并将它们分类为内部或外部。
对于每条折线,我将顶点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个邻居之间的线路。但我需要尽可能地优化它
答案 0 :(得分:4)
简短版本:
将来自中心点的两个角度向量描述为a
和b
。并将中心点到原点的矢量描述为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。向量a
和b
是否指向原点的相对侧?
如果他们的交叉积指向相反的方向,则a
和b
指向原点的相对侧。
`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 *(p1,q1)+ s *(p2,q2)=(p ,q)。如果我们用代数求解r和s,我们得到r =(pq2-p2q)/(p1q2-q1p2)和s =(p1q-pq1)/(p1q2-q1p2)。如果r和s都是正数,则abc是内部的。
答案 2 :(得分:0)
就个人而言,我只会使用点积。具体来说(如果a
代表从你的顶点到的向量,b
和c
是你的边缘向量指向的顶点),如果a dot b
和a dot c
均为正,则角度为外。否则就是内心。
但我对你对'内在'和'外在'的真正定义感到有点困惑......