我试图计算图形中两条边之间的角度,为了做到这一点,我将两条边都转移到原点,然后使用点积来计算角度。我的问题是,对于某些边缘,例如e1
和e2
,angle(e1,e2)
的输出为-1.#INDOO
。
什么是这个输出?这是一个错误吗?
这是我的代码:
double angle(Edge e1, Edge e2){
Edge t1 = e1, t2 = e2;
Point tail1 = t1.getTail(), head1 = t1.getHead();
Point u(head1.getX() - tail1.getX(), head1.getY() - tail1.getY());
Point tail2 = t2.getTail(), head2 = t2.getHead();
Point v(head2.getX() - tail2.getX(), head2.getY() - tail2.getY());
double dotProduct = u.getX()*v.getX() + u.getY()*v.getY();
double cosAlpha = dotProduct / (e1.getLength()*e2.getLength());
return acos(cosAlpha);
}
Edge
是一个包含两个点的类,Point
是一个包含两个双数作为x和y的类。
我正在使用angle(e1,e2)
来计算b
等向量的正交投影长度,以及a
这样的向量:
double orthogonalProjectionLength(Edge b, Edge a){
return (b.getLength()*sin(angle(b, a) * (PI / 180)));
}
此功能有时也会给我-1.#INDOO
。您可以看到Point
和Edge
here的实施情况。
我的输入是2D空间中的n Point
s的集合S. Iv构造了p和q之间的所有边(p,q在S中),然后尝试像这样计算角度:
for (int i = 0; i < E.size(); i++)
for (int j = 0; j < E.size(); j++){
if (i == j)
cerr << fixed << angle(E[i], E[j]) << endl; //E : set of all edges
}
如果问题来自cos()
和sin()
函数,我该如何解决?在这里是其他图书馆以更有效的方式计算罪和cos?
查看this示例。
此示例中的输入是两个不同的点(如p和q),它们之间有两个边(pq
和qp
)。 angle(pq , qp)
不应该总是180?并且angle(pq,pq)
和angle(qp,qp)
应为0.我的程序显示两种不同的行为,有时是angle(qp,qp) == angle(pq,pq) ==0
和angle(pq , qp) == angle(pq , qp) == 180.0
,有时答案是-1.#INDOO
四个边缘。
Here是一个代码示例。 运行几次,你会看到错误。
答案 0 :(得分:3)
你想要投影,你通过所有这些触发?你只需要在a方向上用单位矢量点b。所以最后的答案是
(Xa.Xb + Ya.Yb) / square_root(Xa^2 + Ya^2)
您是否检查过cosAlpha是否达不到1.000000000000000000000001?这可以解释结果,并提供另一个理由,不要像这样四处走动。
答案 1 :(得分:2)
似乎除以零。确保您的向量始终具有0<
长度。
答案 2 :(得分:1)
计算角度的推荐方法是通过atan2
函数,取两个参数。它返回四个象限的角度。
您可以通过两种方式使用它:
分别计算u
和v
的角度并减去:atan2(Vy, Vx) - atan2(Uy, Ux)
。
计算交叉和点数产品:atan2(Ux.Vy - Uy.Vx, Ux.Uy + Vx.Vy)
。
唯一的失败案例是(0, 0)
。
答案 3 :(得分:1)
从我的评论中移出答案
检查点积是否在<-1,+1>
范围内......
acos
失败。if
并夹在此范围内。acos(0.99999*dot)
0.9999
常数太大,则错误仍然存在