void AngleInterval::setUnion(const AngleInterval& i1, const AngleInterval& i2) { if(i1.isEmpty()) { c=i2.c; d=i2.d; } else if(i2.isEmpty()) { c=i1.c; d=i1.d; } else if(i1.contains(i2.c)) { c = i1.c; d = Max(i1.d,i2.d+AngleCCWDiff(i2.c,i1.c)); } else if(i2.contains(i1.c)) { c = i2.c; d = Max(i2.d,i1.d+AngleCCWDiff(i1.c,i2.c)); } else { //we have 2 choices, pick the smaller interval Real d12 = AngleCCWDiff(i1.c+i1.d,i2.c); Real d21 = AngleCCWDiff(i2.c+i2.d,i1.c); if(d12 < d21) { c = i2.c; d = d12; } else { c = i1.c; d = d21; } } }
void SawtoothAngleEnvelope::setInterval(const AngleInterval& i) { Assert(!i.isEmpty()); Vector2 amax,amin; amin.set(i.c+Half*i.d,-Half*i.d); amax.set(amin.x+Pi,amin.y+Pi); amin.x = AngleNormalize(amin.x); amax.x = AngleNormalize(amax.x); v.resize(4); if(amin.x < amax.x) { //hi lo hi lo v[0].x=0; v[0].y = amin.y+amin.x; v[1] = amin; v[2] = amax; v[3].x=TwoPi; v[3].y = amax.y+amax.x-TwoPi; Assert(FuzzyEquals(v[3].y,v[0].y)); } else { //lo hi lo hi v[0].x=0; v[0].y = amax.y-amax.x; v[1] = amax; v[2] = amin; v[3].x=TwoPi; v[3].y = amin.y+TwoPi-amin.x; Assert(FuzzyEquals(v[3].y,v[0].y)); } if(v[2].x == v[3].x) v.erase(v.begin()+3); if(v[0].x == v[1].x) v.erase(v.begin()); Assert(isValid()); }
void AngleSet::Intersect(const AngleInterval& r) { AngleSet newIntervals; AngleInterval temp; for(size_t i=0; i<size(); i++) { temp.setIntersection(operator[](i),r); if(!temp.isEmpty()) newIntervals.push_back(temp); } ::swap(*this,newIntervals); }
bool AngleInterval::contains(const AngleInterval& i) const { if(i.isEmpty()) return true; if(isFull()) return true; if(isEmpty()) return false; if(i.d > d) return false; //tricky at pi if(i.d == Pi && d == Pi) return c==i.c; Real delta1 = AngleCCWDiff(i.c,c); Real delta2 = AngleCCWDiff(AngleNormalize(i.c+i.d),c); return delta1 <= d+Epsilon && delta2 <=d+Epsilon; }
void AngleSet::Intersect(const vector<AngleInterval>& s) { AngleSet newIntervals; AngleInterval temp; for(size_t i=0; i<size(); i++) { for(size_t j=0;j<s.size();j++) { temp.setIntersection(operator[](i),s[j]); if(!temp.isEmpty()) newIntervals.push_back(temp); } } ::swap(*this,newIntervals); }