71 if( bb1.maxi().x() < bb2.mini().x() || bb1.mini().x() > bb2.maxi().x())
return Independent ;
72 if( bb1.maxi().y() < bb2.mini().y() || bb1.mini().y() > bb2.maxi().y())
return Independent ;
78 return computeRelativePosition( dynamic_cast<const Polygone *>(p1),
dynamic_cast<const Polygone *
>(p2)) ;
80 return computeRelativePosition( dynamic_cast<const Polygone *>(p1),
dynamic_cast<const Segment *
>(p2)) ;
82 return computeRelativePosition( dynamic_cast<const Polygone *>(p1),dynamic_cast<const Point *>(p2)) ;
85 return inverseRP(computeRelativePosition( dynamic_cast<const Polygone *>(p2),dynamic_cast<const Segment *>(p1))) ;
87 return computeRelativePosition( dynamic_cast<const Segment *>(p1),
dynamic_cast<const Segment *
>(p2)) ;
92 return inverseRP(computeRelativePosition( dynamic_cast<const Polygone *>(p2),dynamic_cast<const Point *>(p1))) ;
103 if(pointOutOfPolygon_XY(P->
vertex(0),Q,(double)_EPS))
124 vector<double> intersections ;
126 if(!pointOutOfPolygon_XY(S->
vertex(0),P,_EPS)) intersections.push_back(0.0);
127 if(!pointOutOfPolygon_XY(S->
vertex(1),P,_EPS)) intersections.push_back(1.0);
133 intersections.push_back(t1) ;
141 for(
unsigned int j=0;j<intersections.size();++j)
143 tmin = std::min(tmin,intersections[j]) ;
144 tmax = std::max(tmax,intersections[j]) ;
147 if(tmax - tmin < 2*_EPS)
153 int res = Independent ;
155 for(
unsigned int k=0;k<intersections.size();++k)
159 if(P->
equation(v) < -_EPS) res |= Lower ;
160 if(P->
equation(v) > _EPS) res |= Upper ;
163 if(intersections.size() > 1 && res == Independent)
194 int res = Independent ;
210 if(P1->
normal().
z() == 0.0)
throw runtime_error(
"could not project point. Unexpected case !") ;
211 if(P2->
normal().
z() == 0.0)
throw runtime_error(
"could not project point. Unexpected case !") ;
221 if(P1->
equation(v2) < -_EPS) res |= Lower ;
222 if(P1->
equation(v2) > _EPS) res |= Upper ;
223 if(P2->
equation(v1) < -_EPS) res |= Upper ;
224 if(P2->
equation(v1) > _EPS) res |= Lower ;
238 -(
double)_EPS,t1,t2 ))
267 for(
size_t j=0;j<nq;j++)
272 double Z = (q1-p)^(q2-p) ;
274 MinZ = std::min(Z,MinZ) ;
275 MaxZ = std::max(Z,MaxZ) ;
278 if((MaxZ <= -I_EPS*I_EPS)||(MinZ >= I_EPS*I_EPS))
290 case Independent:
return Independent ;
291 case Lower:
return Upper ;
292 case Upper:
return Lower ;
293 case Upper | Lower:
return Upper | Lower ;
295 throw runtime_error(
"Unexpected value.") ;
307 double & t1,
double & t2)
318 double a2 = -(Q2y - P2y) ;
319 double b2 = (Q2x - P2x) ;
320 double c2 = P2x*a2+P2y*b2 ;
322 double a1 = -(Q1y - P1y) ;
323 double b1 = (Q1x - P1x) ;
324 double c1 = P1x*a1+P1y*b1 ;
326 double d2 = a2*(Q1x-P1x)+b2*(Q1y-P1y) ;
327 double d1 = a1*(Q2x-P2x)+b1*(Q2y-P2y) ;
329 if((fabs(d2) <= fabs(I_EPS))||(fabs(d1) <= fabs(I_EPS)))
331 if(fabs(a2*P1x + b2*P1y - c2) >= I_EPS)
338 tP1 = (P2x-P1x)/(Q1x-P1x) ;
339 tQ1 = (Q2x-P1x)/(Q1x-P1x) ;
343 tP1 = (P2y-P1y)/(Q1y-P1y) ;
344 tQ1 = (Q2y-P1y)/(Q1y-P1y) ;
349 printf(
"IntersectSegments2D:: Error ! One segment has length 0\n") ;
350 printf(
"This special case is not treated yet.\n") ;
355 double tPQM = std::max(tP1,tQ1) ;
356 double tPQm = std::min(tP1,tQ1) ;
358 if(( tPQM < -I_EPS) || (tPQm > 1.0+I_EPS))
370 t2 = (P1x-P2x)/(Q2x-P2x) ;
372 t2 = (P1y-P2y)/(Q2y-P2y) ;
376 printf(
"IntersectSegments2D:: Error ! One segment has length 0\n") ;
377 printf(
"This special case is not treated yet.\n") ;
387 t2 = (c1 - a1*P2x - b1*P2y)/d1 ;
388 t1 = (c2 - a2*P1x - b2*P1y)/d2 ;
390 if((t2 > 1+I_EPS)||(t2 < -I_EPS)||(t1 > 1+I_EPS)||(t1 < -I_EPS))
422 vector<int>& signs,vector<double>& zvals,
int& Smin,
int& Smax,
double I_EPS)
425 throw runtime_error(
"Null primitive in getsigns !") ;
438 for(
size_t i=0;i<n;i++)
440 double Z = P->
vertex(i) * v - C ;
442 if(Z > zmax) zmax = Z ;
443 if(Z < zmin) zmin = Z ;
450 for(
size_t j=0;j<n;j++)
452 if(zvals[j] < -I_EPS)
454 else if(zvals[j] > I_EPS)
459 if(Smin > signs[j]) Smin = signs[j] ;
460 if(Smax < signs[j]) Smax = signs[j] ;
467 vector<double> Zvals ;
475 getsigns(P,v,C,Signs,Zvals,Smin,Smax,_EPS) ;
479 if((Smin == 0)&&(Smax == 0)){ P_moins = P ; P_plus = NULL ; return ; }
480 if(Smin == 1) { P_plus = P ; P_moins = NULL ; return ; }
481 if(Smax == -1) { P_plus = NULL ; P_moins = P ; return ; }
483 if((Smin == -1)&&(Smax == 0)) { P_plus = NULL ; P_moins = P ; return ; }
484 if((Smin == 0)&&(Smax == 1)) { P_plus = P ; P_moins = NULL ; return ; }
488 vector<Feedback3DColor> Ps ;
489 vector<Feedback3DColor> Ms ;
496 for(
size_t i=0;i<n;i++)
502 if(Signs[(i+1)%n] == 0)
508 if((nZero > 2)||(nconsZero > 0)) { P_moins = P ; P_plus = NULL ; return ; }
510 int dep=0 ;
while(Signs[dep] == 0) dep++ ;
511 int prev_sign = Signs[dep] ;
513 for(
size_t j=1;j<=n;j++)
515 int sign = Signs[(j+dep)%n] ;
517 if(sign == prev_sign)
522 else if(sign == -prev_sign)
527 double Z1 = Zvals[(j+dep-1)%n] ;
528 double Z2 = Zvals[(j+dep)%n] ;
530 double t = fabs(Z1/(Z2 - Z1)) ;
532 if((t < 0.0)||(t > 1.0))
534 if(t > 1.0) t = 1.0 ;
535 if(t < 0.0) t = 0.0 ;
539 Ps.push_back(newVertex) ;
540 Ms.push_back(newVertex) ;
554 Ps.push_back(newVertex) ;
555 Ms.push_back(newVertex) ;
557 prev_sign = -prev_sign ;
561 if(Ps.size() > 100 || Ms.size() > 100 )
562 printf(
"Primitive::split: Error. nPs = %d, nMs = %d.\n",
int(Ps.size()),
int(Ms.size())) ;
567 P_plus =
new Point(Ps[0]) ;
568 else if(Ps.size() == 2)
569 P_plus =
new Segment(Ps[0],Ps[1]) ;
574 P_moins =
new Point(Ms[0]) ;
575 else if(Ms.size() == 2)
576 P_moins =
new Segment(Ms[0],Ms[1]) ;
583 if(v*P->
vertex(0)-C > -_EPS)
598 vector<double> Zvals ;
606 getsigns(S,v,C,Signs,Zvals,Smin,Smax,_EPS) ;
610 if((Smin == 0)&&(Smax == 0)) { P_moins = S ; P_plus = NULL ; return ; }
611 if(Smin == 1) { P_plus = S ; P_moins = NULL ; return ; }
612 if(Smax == -1) { P_plus = NULL ; P_moins = S ; return ; }
614 if((Smin == -1)&&(Smax == 0)) { P_plus = NULL ; P_moins = S ; return ; }
615 if((Smin == 0)&&(Smax == 1)) { P_plus = S ; P_moins = NULL ; return ; }
623 for(
size_t i=0;i<n;i++)
629 if(Signs[(i+1)%n] == 0)
635 if((nZero > 2)||(nconsZero > 0)) { P_moins = S ; P_plus = NULL ; return ; }
637 double Z1 = Zvals[0] ;
638 double Z2 = Zvals[1] ;
640 double t = fabs(Z1/(Z2 - Z1)) ;
642 if((t < 0.0)||(t > 1.0))
644 if(t > 1.0) t = 1.0 ;
645 if(t < 0.0) t = 0.0 ;
virtual const Vector3 & vertex(size_t) const
static gpc_polygon createGPCPolygon_XY(const Polygone *P)
static void splitPrimitive(Primitive *P, const NVector3 &v, double c, Primitive *&prim_up, Primitive *&prim_lo)
gpc_vertex_list * contour
void gpc_polygon_clip(gpc_op op, gpc_polygon *subj, gpc_polygon *clip, gpc_polygon *result)
virtual size_t nbVertices() const =0
virtual const Vector3 & vertex(size_t) const =0
unsigned long num_contours
double equation(const Vector3 &p) const
virtual AxisAlignedBox_xyz bbox() const =0
static int computeRelativePosition(const Primitive *p1, const Primitive *p2)
static int inverseRP(int)
virtual const Vector3 & vertex(size_t) const
static void getsigns(const Primitive *P, const NVector3 &v, double C, std::vector< int > &signs, std::vector< double > &zvals, int &Smin, int &Smax, double I_EPS)
static void split(Segment *S, const NVector3 &v, double C, Primitive *&P_plus, Primitive *&P_moins)
virtual const Feedback3DColor & sommet3DColor(size_t) const
virtual size_t nbVertices() const
virtual size_t nbVertices() const
static bool pointOutOfPolygon_XY(const Vector3 &P, const Polygone *Q, double I_EPS)
const NVector3 & normal() const
void gpc_free_polygon(gpc_polygon *p)
void gpc_add_contour(gpc_polygon *p, gpc_vertex_list *new_contour, int hole)
static bool intersectSegments_XY(const Vector2 &P1, const Vector2 &Q1, const Vector2 &P2, const Vector2 &Q2, double I_EPS, double &t1, double &t2)
virtual const Feedback3DColor & sommet3DColor(size_t i) const
virtual const Vector3 & vertex(size_t) const