src/gsim/se_lct.cpp
// if a refinement is needed, it will return the blocking edge, otherwise null
if a refinement is needed, it will return the blocking edge, otherwise null
if a refinement is needed it will return the blocking edge otherwise null
SeDcdtSymEdge* SeLct::_needs_refinement ( SeDcdtSymEdge* s, RefinementType type, SeDcdtSymEdge*& disturb )
 {
   SeDcdtSymEdge * sn = s->nxt();
   SeDcdtSymEdge * sp = sn->nxt();
   if ( s->vtx()->border || sn->vtx()->border || sp->vtx()->border ) return 0;
   if ( type==LocalClearanceRef || type==LocalClearanceMidRef )
    { const GsPnt2& c = s->vtx()->p;
      const GsPnt2& a = sn->vtx()->p;
      const GsPnt2& b = sp->vtx()->p;
      if ( CONSTR(sn) || CONSTR(sp) ) return 0; 
      float h = (float)gs_point_segment_dist ( b.x, b.y, a.x, a.y, c.x, c.y );
      GsPnt2 vec = (a-c).ortho(); vec.len(h);
      GsPnt2 ra = a + vec;
      GsPnt2 rc = c + vec;
      double d2ab=dist2(a,b);
      double d2bc=dist2(b,c);
      double l2=GS_MIN(d2ab,d2bc);
      float delta = dist(a,c) - ( 2.0f * (float) sqrt(l2-(h*h)) );
      vec = d2ab<d2bc? c-a : a-c;
      vec.len ( delta );
      GsPnt2 p = b + vec; 
      if ( !_sector_clear ( s, l2, b, c, a, &p ) )
       {
         double clear2 = _secblockd2;
         SeDcdtVertex* v;
         SeDcdtSymEdge* ei = s;
         SeDcdtSymEdge* e;
         for ( e=ei->rot()->rot(); e!=ei; e=e->rot() ) 
          { v = e->nvtx();
            if ( CONSTR(e) ) break;
            if ( ccw(v->p,rc,c)<=0 ) break; 
            if ( isdisturbance ( this, v, s, sn, sp, clear2, _secblockse, true ) )
             { disturb = e->nxt(); return _secblockse;
             }
          }
         ei = s->sym();
         for ( e=sp->rot()->nxt(); e!=ei; e=e->ret() ) 
          { v = e->nvtx();
            if ( CONSTR(e) ) break;
            if ( ccw(v->p,a,ra)<=0 ) break; 
            if ( isdisturbance ( this, v, s, sn, sp, clear2, _secblockse, false ) )
             { disturb = e->nxt(); return _secblockse;
             }
          }
       }
      return 0;
    }
   else if ( type==CorridorRef )
    {
      if ( !CONSTR(s) || CONSTR(sn) || CONSTR(sp) ) return 0; 
      const GsPnt2& a = s->vtx()->p;
      const GsPnt2& b = sn->vtx()->p;
      const GsPnt2& c = sp->vtx()->p;
      float ang = angle(a-c,b-c);
      if ( ang>gspidiv2 )
       { disturb = sp;
         return s;
       }
      return 0;
    }
   else if ( type==JunctionRef )
    { 
      if ( CONSTR(s) || CONSTR(sn) || CONSTR(sp) ) return 0; 
      const GsPnt2& a = s->vtx()->p;
      const GsPnt2& b = sn->vtx()->p;
      const GsPnt2& c = sp->vtx()->p;
      double ang = angle(a-c,b-c);
      if ( ang<gspidiv2 ) return 0; 
      float d2ca=dist2(c,a);
      float d2cb=dist2(c,b);
      float d2=GS_MIN(d2ca,d2cb);
      if ( _sector_clear ( s, d2, c, a, b ) ) return 0;
      disturb = sp;
      return _secblockse;
    }
   return 0;
 }
SeDcdtSymEdge * SeLct :: _needs_refinement ( SeDcdtSymEdge * s , RefinementType type , SeDcdtSymEdge * & disturb ) { SeDcdtSymEdge * sn = s -> nxt ( ) ; SeDcdtSymEdge * sp = sn -> nxt ( ) ; if ( s -> vtx ( ) -> border || sn -> vtx ( ) -> border || sp -> vtx ( ) -> border ) return 0 ; if ( type == LocalClearanceRef || type == LocalClearanceMidRef ) { const GsPnt2 & c = s -> vtx ( ) -> p ; const GsPnt2 & a = sn -> vtx ( ) -> p ; const GsPnt2 & b = sp -> vtx ( ) -> p ; if ( CONSTR ( sn ) || CONSTR ( sp ) ) return 0 ; float h = ( float ) gs_point_segment_dist ( b . x , b . y , a . x , a . y , c . x , c . y ) ; GsPnt2 vec = ( a - c ) . ortho ( ) ; vec . len ( h ) ; GsPnt2 ra = a + vec ; GsPnt2 rc = c + vec ; double d2ab = dist2 ( a , b ) ; double d2bc = dist2 ( b , c ) ; double l2 = GS_MIN ( d2ab , d2bc ) ; float delta = dist ( a , c ) - ( 2.0f * ( float ) sqrt ( l2 - ( h * h ) ) ) ; vec = d2ab < d2bc ? c - a : a - c ; vec . len ( delta ) ; GsPnt2 p = b + vec ; if ( ! _sector_clear ( s , l2 , b , c , a , & p ) ) { double clear2 = _secblockd2 ; SeDcdtVertex * v ; SeDcdtSymEdge * ei = s ; SeDcdtSymEdge * e ; for ( e = ei -> rot ( ) -> rot ( ) ; e != ei ; e = e -> rot ( ) ) { v = e -> nvtx ( ) ; if ( CONSTR ( e ) ) break ; if ( ccw ( v -> p , rc , c ) <= 0 ) break ; if ( isdisturbance ( this , v , s , sn , sp , clear2 , _secblockse , true ) ) { disturb = e -> nxt ( ) ; return _secblockse ; } } ei = s -> sym ( ) ; for ( e = sp -> rot ( ) -> nxt ( ) ; e != ei ; e = e -> ret ( ) ) { v = e -> nvtx ( ) ; if ( CONSTR ( e ) ) break ; if ( ccw ( v -> p , a , ra ) <= 0 ) break ; if ( isdisturbance ( this , v , s , sn , sp , clear2 , _secblockse , false ) ) { disturb = e -> nxt ( ) ; return _secblockse ; } } } return 0 ; } else if ( type == CorridorRef ) { if ( ! CONSTR ( s ) || CONSTR ( sn ) || CONSTR ( sp ) ) return 0 ; const GsPnt2 & a = s -> vtx ( ) -> p ; const GsPnt2 & b = sn -> vtx ( ) -> p ; const GsPnt2 & c = sp -> vtx ( ) -> p ; float ang = angle ( a - c , b - c ) ; if ( ang > gspidiv2 ) { disturb = sp ; return s ; } return 0 ; } else if ( type == JunctionRef ) { if ( CONSTR ( s ) || CONSTR ( sn ) || CONSTR ( sp ) ) return 0 ; const GsPnt2 & a = s -> vtx ( ) -> p ; const GsPnt2 & b = sn -> vtx ( ) -> p ; const GsPnt2 & c = sp -> vtx ( ) -> p ; double ang = angle ( a - c , b - c ) ; if ( ang < gspidiv2 ) return 0 ; float d2ca = dist2 ( c , a ) ; float d2cb = dist2 ( c , b ) ; float d2 = GS_MIN ( d2ca , d2cb ) ; if ( _sector_clear ( s , d2 , c , a , b ) ) return 0 ; disturb = sp ; return _secblockse ; } return 0 ; }
if a refinement is needed, it will return the blocking edge, otherwise null
if a refinement is needed it will return the blocking edge otherwise null
// not a valid traversal // second corner at right // right side // left side // s has to be the only constraint of a corridor triangle // not a junction // prunes a little with MIN but a lot (half) with MAX