找到两个角度范围/段之间的交叉点

时间:2018-02-26 08:43:38

标签: geometry

我们有两个角度范围,(aStart,aSweep)和(bStart,bSweep),其中起点是角度段开始位置[0,2π],扫描的大小是段,在(0,2π]范围内。

我们希望找到这两个角度范围重叠的所有角度范围(如果有的话)。

我们需要一种至少涵盖三种情况的解决方案:

there can be a few kinds of cases

但是当我们面对存在于角度= 0的魔鬼线的现实时,情况的数量会增加,这会在任何一个角度范围交叉时弄乱所有的不等式。

1 个答案:

答案 0 :(得分:0)

此解决方案通过将角度归一化到所述魔鬼线来工作,因此其中一个角度(我们称之为原点角度)始终从那里开始。事实证明,这使得程序的其余部分非常简单。

const float TPI = 2*M_PI;
//aStart and bStart must be in [0, 2PI)
//aSweep and bSweep must be in (0, 2PI]
//forInterval(float start, float sweep) gets called on each intersection found. It is possible for there to be zero, one, or two, you see, so it's not obvious how we would want to return an answer. We leave it abstract.
//only reports overlaps, not contacts (IE, it shouldn't report any overlaps of zero span)
template<typename F>
void overlappingSectors(float aStart, float aSweep, float bStart, float bSweep, F forInterval){
    //we find the lower angle and work relative to it
    float greaterAngle;
    float greaterSweep;
    float originAngle;
    float originSweep;
    if(aStart < bStart){
        originAngle = aStart;
        originSweep = aSweep;
        greaterSweep = bSweep;
        greaterAngle = bStart;
    }else{
        originAngle = bStart;
        originSweep = bSweep;
        greaterSweep = aSweep;
        greaterAngle = aStart;
    }
    float greaterAngleRel = greaterAngle - originAngle;
    if(greaterAngleRel < originSweep){
        forInterval(greaterAngle, min(greaterSweep, originSweep - greaterAngleRel));
    }
    float rouno = greaterAngleRel + greaterSweep;
    if(rouno > TPI){
        forInterval(originAngle, min(rouno - TPI, originSweep));
    }
}