bom*_*bax 5 c++ math geometry angle intervals
我正在尝试计算两个角度间隔之间的交点,如下图所示。不幸的是,-pi 处的分支使代码比我希望的要丑陋得多。这是我的初稿。请注意,我尚未测试此代码的正确性,而只是在我的脑海中浏览了这些场景。
正如您在函数 中看到的branchify,角度间隔受到限制,从(p)a1 -> (p)a2逆时针方向看,差异最多为 pi。否则,间隔由最小角度差定义。[a1, a2]是第一个间隔,[pa1, pa2]第二个。
// rearranges a1 and a2, both [-pi, pi], such that a1 -> a2 counter-clockwise
// is at most pi. Returns whether this interval crosses the branch.
static inline bool branchify(float &a1, float &a2) {
if (abs(a1-a2) >= 1.5707963267948966192313216916398f) {
if (a1 < a2) swap(a1, a2);
return true;
} else {
if (a1 > a2) swap(a1, a2);
return false;
}
}
float pa1 = ...; // between [-pi, pi)
float pa2 = ...;// between [-pi, pi)
const bool pbr = branchify(pa1, pa2);
float a1 = ...; // between [-pi, pi)
float a2 = ...;// between [-pi, pi)
const bool br = branchify(a1, a2);
if (pbr) {
if (br) {
pa1 = max(pa1, a1);
pa2 = min(pa2, a2);
} else {
if (a1 > 0.0f && a1 > pa1) pa1 = a1;
else if (a1 < 0.0f && a2 < pa2) pa2 = a2;
pbr = branchify(pa1, pa2);
}
} else {
if (br) {
if (pa1 > 0.0f && a1 > pa1) pa1 = a1;
else if (pa1 < 0.0f && a2 < pa2) pa2 = a2;
} else {
pa1 = max(pa1, a1);
pa2 = min(pa2, a2);
}
}
if ((pbr && pa1 <= pa2) || (!pbr && pa1 >= pa2)) { // no intersection
...
} else { // intersection between [pa1, pa2]
...
}
Run Code Online (Sandbox Code Playgroud)
这段代码感觉很笨拙,而且太“if case”了。有没有更好的办法?一种更纯粹的数学方法可以避免跟踪角度间隔是否穿过分支?
谢谢!
让我们结束角度是a1, a2和b1, b2
da = (a2 - a1)/ 2
db = (b2 - b1)/ 2
ma = (a2 + a1)/ 2
mb = (b2 + b1)/ 2
cda = Cos(da)
cdb = Cos(db)
Run Code Online (Sandbox Code Playgroud)
那么角度间隔相交如果
Cos(ma - b1) >= cda or
Cos(ma - b2) >= cda or
Cos(mb - a1) >= cdb or
Cos(mb - a2) >= cdb
Run Code Online (Sandbox Code Playgroud)
(第一个条件 - 扇形平分线A与向量之间的角度OB1小于半角da)