【发布时间】:2014-10-20 07:38:17
【问题描述】:
我试图计算图中两条边之间的角度,为此我将两条边都转移到原点,然后使用点积来计算角度。我的问题是,对于像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和Edgehere的实现。
我的输入是二维空间中 n Points 的集合 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() 函数,我该如何解决?这里还有其他以更有效的方式计算 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 是一个代码示例。 运行几次,你会看到错误。
【问题讨论】:
-
请给我们举个例子。
-
180 是干什么用的?一切都应该以弧度表示,所以只需将其保留为弧度即可。
-
我很确定问题出在您发布的代码之外。但是您的问题似乎是边的长度为零,这会导致除以零的问题。如果没有看到更多代码,很难确定这是为什么。
-
我会在整个计算过程中打印部分结果(或在调试器中逐步执行并查看结果)。最有可能的是,某些事情最终会以一种不符合您预期的方式进行计算。
-
检查您的点积是否在
<-1,+1>范围内...由于浮点舍入,它可以是例如 1.000002045,这将导致 acos 失败。所以添加两个 if 并限制在这个范围内。或使用更快的方法:acos(0.99999*dot),但这会降低所有角度的精度,如果 0.9999 常数太大,则错误仍然存在
标签: c++ visual-c++ math