PrimitivePositioning.cpp
Go to the documentation of this file.
1 /*
2  This file is part of the VRender library.
3  Copyright (C) 2005 Cyril Soler (Cyril.Soler@imag.fr)
4  Version 1.0.0, released on June 27, 2005.
5 
6  http://artis.imag.fr/Members/Cyril.Soler/VRender
7 
8  VRender is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 2 of the License, or
11  (at your option) any later version.
12 
13  VRender is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with VRender; if not, write to the Free Software Foundation, Inc.,
20  51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22 
23 /****************************************************************************
24 
25  Copyright (C) 2002-2014 Gilles Debunne. All rights reserved.
26 
27  This file is part of the QGLViewer library version 2.6.3.
28 
29  http://www.libqglviewer.com - contact@libqglviewer.com
30 
31  This file may be used under the terms of the GNU General Public License
32  versions 2.0 or 3.0 as published by the Free Software Foundation and
33  appearing in the LICENSE file included in the packaging of this file.
34  In addition, as a special exception, Gilles Debunne gives you certain
35  additional rights, described in the file GPL_EXCEPTION in this package.
36 
37  libQGLViewer uses dual licensing. Commercial/proprietary software must
38  purchase a libQGLViewer Commercial License.
39 
40  This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
41  WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
42 
43 *****************************************************************************/
44 
45 #include "Primitive.h"
46 #include "AxisAlignedBox.h"
47 #include "PrimitivePositioning.h"
48 #include "math.h"
49 #include <algorithm>
50 #include "Vector2.h"
51 
52 #include <algorithm>
53 
54 using namespace vrender ;
55 using namespace std ;
56 
57 #define DEBUG_TS
58 
59 double PrimitivePositioning::_EPS = 0.00001 ;
60 
61 // Computes relative position of the second primitive toward the first.
62 // As a general rule, the smaller the Z of a primitive, the Upper the primitive.
63 
65 {
66  AxisAlignedBox_xyz bb1(p1->bbox()) ;
67  AxisAlignedBox_xyz bb2(p2->bbox()) ;
68 
69  // 1 - check if bounding boxes are disjoint. In such a case, a rapid answer is possible.
70 
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 ;
73 
74  // 2 - call specific tests for each case.
75 
76  if(p1->nbVertices() >= 3)
77  if(p2->nbVertices() >= 3)
78  return computeRelativePosition( dynamic_cast<const Polygone *>(p1),dynamic_cast<const Polygone *>(p2)) ;
79  else if(p2->nbVertices() == 2) // Case of a segment versus a polygon
80  return computeRelativePosition( dynamic_cast<const Polygone *>(p1),dynamic_cast<const Segment *>(p2)) ;
81  else
82  return computeRelativePosition( dynamic_cast<const Polygone *>(p1),dynamic_cast<const Point *>(p2)) ;
83  else if(p1->nbVertices() == 2)
84  if(p2->nbVertices() >= 3)
85  return inverseRP(computeRelativePosition( dynamic_cast<const Polygone *>(p2),dynamic_cast<const Segment *>(p1))) ;
86  else if(p2->nbVertices() == 2)
87  return computeRelativePosition( dynamic_cast<const Segment *>(p1),dynamic_cast<const Segment *>(p2)) ;
88  else
89  return Independent ; // segment vs point => independent
90  else
91  if(p2->nbVertices() >= 3)
92  return inverseRP(computeRelativePosition( dynamic_cast<const Polygone *>(p2),dynamic_cast<const Point *>(p1))) ;
93  else if(p2->nbVertices() == 2)
94  return Independent ; // point vs segment => independent
95  else
96  return Independent ; // point vs point => independent
97 }
98 
99 // Computes the relative position of the point toward a *convex* polygon.
100 
102 {
103  if(pointOutOfPolygon_XY(P->vertex(0),Q,(double)_EPS)) // On met un eps > 0, pour que les
104  return Independent ; // points du bords soient inclus dans le polygone.
105 
106  // now compute the relative position of the point toward the polygon
107 
108  if(Q->equation(P->vertex(0)) >= 0)
109  return Upper ;
110  else
111  return Lower ;
112 }
113 
114 // Computes the relative position of the segment toward a *convex* polygon.
115 
117 {
118  // Computes the intersection of the segment and the polygon in 2D, then
119  // project the extremities of the intersection onto the segment, and compare
120  // the points to the polygon.
121 
122  // 1 - 2D-intersection of segment and polygon
123 
124  vector<double> intersections ;
125 
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);
128 
129  double t1,t2 ;
130 
131  for(size_t i=0;i<P->nbVertices();++i)
132  if(intersectSegments_XY(Vector2(S->vertex(0)),Vector2(S->vertex(1)),Vector2(P->vertex(i)),Vector2(P->vertex(i+1)),_EPS,t1,t2))
133  intersections.push_back(t1) ;
134 
135  // 2 - Checks wether the intersection segment is reduced to a point. In this case,
136  // both primitives are independent.
137 
138  double tmin = FLT_MAX ;
139  double tmax = -FLT_MAX ;
140 
141  for(unsigned int j=0;j<intersections.size();++j)
142  {
143  tmin = std::min(tmin,intersections[j]) ;
144  tmax = std::max(tmax,intersections[j]) ;
145  }
146 
147  if(tmax - tmin < 2*_EPS)
148  return Independent ;
149 
150  // 3 - The intersection segment is not reduced to a point. Compares 3D
151  // projections of the intersections with the plane of the polygon.
152 
153  int res = Independent ;
154 
155  for(unsigned int k=0;k<intersections.size();++k)
156  {
157  Vector3 v( (1-intersections[k])*S->vertex(0) + intersections[k]*S->vertex(1) ) ;
158 
159  if(P->equation(v) < -_EPS) res |= Lower ;
160  if(P->equation(v) > _EPS) res |= Upper ;
161  }
162 
163  if(intersections.size() > 1 && res == Independent) // case of segments tangent to the polygon
164  res = Upper ;
165 
166  return res ;
167 }
168 
169 // Computes the relative position of a polygon toward a convex polygon.
170 
172 {
173  // 1 - use gpc to conservatively check for intersection. This works fine because
174  // gpc produces a null intersection for polygons sharing an edge, which
175  // is exactly what we need.
176 
177  gpc_polygon gpc_int ;
178 
179  try
180  {
181  gpc_polygon gpc_p1 = createGPCPolygon_XY(P1) ;
182  gpc_polygon gpc_p2 = createGPCPolygon_XY(P2) ;
183 
184  gpc_polygon_clip(GPC_INT,&gpc_p1,&gpc_p2,&gpc_int) ;
185 
186  gpc_free_polygon(&gpc_p1) ;
187  gpc_free_polygon(&gpc_p2) ;
188  }
189  catch(exception&)
190  {
191  return Independent ; // no free, because we don't really now what happenned.
192  }
193 
194  int res = Independent ;
195 
196  if (gpc_int.num_contours != 1) // There is some numerical error in gpc. Let's skip.
197  {
198  gpc_free_polygon(&gpc_int) ;
199  return res ;
200  // throw runtime_error("Intersection with more than 1 contour ! Non convex polygons ?") ;
201  }
202 
203  // 2 - polygons are not independent. Compute their relative position.
204  // For this, we project the vertices of the 2D intersection onto the
205  // support plane of each polygon. The epsilon-signs of each point toward
206  // both planes give the relative position of the polygons.
207 
208  for(long i=0;i<gpc_int.contour[0].num_vertices && (res < (Upper | Lower));++i)
209  {
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 !") ;
212 
213  // project point onto support planes
214 
215  double f1 = P1->normal().x() * gpc_int.contour[0].vertex[i].x + P1->normal().y() * gpc_int.contour[0].vertex[i].y - P1->c() ;
216  double f2 = P2->normal().x() * gpc_int.contour[0].vertex[i].x + P2->normal().y() * gpc_int.contour[0].vertex[i].y - P2->c() ;
217 
218  Vector3 v1(gpc_int.contour[0].vertex[i].x,gpc_int.contour[0].vertex[i].y, -f1/P1->normal().z()) ;
219  Vector3 v2(gpc_int.contour[0].vertex[i].x,gpc_int.contour[0].vertex[i].y, -f2/P2->normal().z()) ;
220 
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 ;
225  }
226  gpc_free_polygon(&gpc_int) ;
227  return res ;
228 }
229 
230 // Computes the relative position of a segment toward another segment.
231 
233 {
234  double t1,t2 ;
235 
236  if(!intersectSegments_XY( Vector2(S1->vertex(0)),Vector2(S1->vertex(1)),
237  Vector2(S2->vertex(0)),Vector2(S2->vertex(1)),
238  -(double)_EPS,t1,t2 ))
239  return Independent ;
240  else
241  {
242  double z1 = (1.0 - t1)*S1->vertex(0).z() + t1*S1->vertex(1).z() ;
243  double z2 = (1.0 - t2)*S2->vertex(0).z() + t2*S2->vertex(1).z() ;
244 
245  if(z1 <= z2)
246  return Lower ;
247  else
248  return Upper ;
249  }
250 }
251 
252 
253 // Teste si le point est exterieur au polygone (convexe). Plus I_EPS est grand
254 // plus il faut etre loin pour que ca soit vrai. EPS=0 correspond au polygone
255 // lui-meme bords inclus. Pour EPS<0, des points interieurs pres de la frontiere sont
256 // declares exterieurs. Plus I_EPS est grand, plus l'ensemble des points
257 // consideres comme interieur est dilate.
258 
259 bool PrimitivePositioning::pointOutOfPolygon_XY(const Vector3& P,const Polygone *Q,double I_EPS)
260 {
261  size_t nq = Q->nbVertices() ;
262  Vector2 p = Vector2(P) ;
263 
264  FLOAT MaxZ = -FLT_MAX ;
265  FLOAT MinZ = FLT_MAX ;
266 
267  for(size_t j=0;j<nq;j++) // Regarde si P.(x,y) est a l'interieur
268  { // ou a l'exterieur du polygone.
269  Vector2 q1 = Vector2(Q->vertex(j)) ;
270  Vector2 q2 = Vector2(Q->vertex(j+1)) ;
271 
272  double Z = (q1-p)^(q2-p) ;
273 
274  MinZ = std::min(Z,MinZ) ;
275  MaxZ = std::max(Z,MaxZ) ;
276  }
277 
278  if((MaxZ <= -I_EPS*I_EPS)||(MinZ >= I_EPS*I_EPS)) // the point is inside the polygon
279  return false ;
280  else
281  return true ;
282 }
283 
285 {
286  // Basically switch bits of Lower and Upper
287 
288  switch(pos)
289  {
290  case Independent: return Independent ;
291  case Lower: return Upper ;
292  case Upper: return Lower ;
293  case Upper | Lower: return Upper | Lower ;
294  default:
295  throw runtime_error("Unexpected value.") ;
296  return pos ;
297  }
298 }
299 
300 // Calcule l'intersection des segments [P1,Q1] et [P2,Q2]
301 // En retour, (1-t1,t1) et (1-t2,t2) sont les coordonnees
302 // barycentriques de l'intersection dans chaque segment.
303 
305  const Vector2& P2,const Vector2& Q2,
306  double I_EPS,
307  double & t1,double & t2)
308 {
309  double P1x(P1.x()) ;
310  double P1y(P1.y()) ;
311  double P2x(P2.x()) ;
312  double P2y(P2.y()) ;
313  double Q1x(Q1.x()) ;
314  double Q1y(Q1.y()) ;
315  double Q2x(Q2.x()) ;
316  double Q2y(Q2.y()) ;
317 
318  double a2 = -(Q2y - P2y) ;
319  double b2 = (Q2x - P2x) ;
320  double c2 = P2x*a2+P2y*b2 ;
321 
322  double a1 = -(Q1y - P1y) ;
323  double b1 = (Q1x - P1x) ;
324  double c1 = P1x*a1+P1y*b1 ;
325 
326  double d2 = a2*(Q1x-P1x)+b2*(Q1y-P1y) ;
327  double d1 = a1*(Q2x-P2x)+b1*(Q2y-P2y) ;
328 
329  if((fabs(d2) <= fabs(I_EPS))||(fabs(d1) <= fabs(I_EPS))) // les segments sont paralleles
330  {
331  if(fabs(a2*P1x + b2*P1y - c2) >= I_EPS)
332  return false ;
333 
334  double tP1,tQ1 ;
335 
336  if(P1x != Q1x)
337  {
338  tP1 = (P2x-P1x)/(Q1x-P1x) ;
339  tQ1 = (Q2x-P1x)/(Q1x-P1x) ;
340  }
341  else if(P1y != Q1y)
342  {
343  tP1 = (P2y-P1y)/(Q1y-P1y) ;
344  tQ1 = (Q2y-P1y)/(Q1y-P1y) ;
345  }
346  else
347  {
348 #ifdef DEBUG_TS
349  printf("IntersectSegments2D:: Error ! One segment has length 0\n") ;
350  printf("This special case is not treated yet.\n") ;
351 #endif
352  return false ;
353  }
354 
355  double tPQM = std::max(tP1,tQ1) ;
356  double tPQm = std::min(tP1,tQ1) ;
357 
358  if(( tPQM < -I_EPS) || (tPQm > 1.0+I_EPS))
359  return false ;
360 
361  if(tPQm > 0.0)
362  {
363  t1 = tPQm ;
364  t2 = 0.0 ;
365  }
366  else
367  {
368  t1 = 0.0 ;
369  if(P2x != Q2x)
370  t2 = (P1x-P2x)/(Q2x-P2x) ;
371  else if(P2y != Q2y)
372  t2 = (P1y-P2y)/(Q2y-P2y) ;
373  else
374  {
375 #ifdef DEBUG_TS
376  printf("IntersectSegments2D:: Error ! One segment has length 0\n") ;
377  printf("This special case is not treated yet.\n") ;
378 #endif
379  return false ;
380  }
381  }
382 
383  return true ;
384  }
385  else
386  {
387  t2 = (c1 - a1*P2x - b1*P2y)/d1 ;
388  t1 = (c2 - a2*P1x - b2*P1y)/d2 ;
389 
390  if((t2 > 1+I_EPS)||(t2 < -I_EPS)||(t1 > 1+I_EPS)||(t1 < -I_EPS))
391  return false ;
392 
393  return true ;
394  }
395 }
396 
398 {
399  gpc_polygon p ;
400 
401  p.num_contours = 0 ;
402  p.hole = NULL ;
403  p.contour = NULL ;
404 
405  gpc_vertex_list *gpc_p_verts = new gpc_vertex_list ;
406 
407  gpc_p_verts->num_vertices = P->nbVertices() ;
408  gpc_p_verts->vertex = new gpc_vertex[P->nbVertices()] ;
409 
410  for(size_t i=0;i<P->nbVertices();++i)
411  {
412  gpc_p_verts->vertex[i].x = P->vertex(i).x() ;
413  gpc_p_verts->vertex[i].y = P->vertex(i).y() ;
414  }
415 
416  gpc_add_contour(&p,gpc_p_verts,false) ;
417 
418  return p ;
419 }
420 
421 void PrimitivePositioning::getsigns(const Primitive *P,const NVector3& v,double C,
422  vector<int>& signs,vector<double>& zvals,int& Smin,int& Smax,double I_EPS)
423 {
424  if(P == NULL)
425  throw runtime_error("Null primitive in getsigns !") ;
426 
427  size_t n = P->nbVertices() ;
428 
429  Smin = 1 ;
430  Smax = -1 ;
431 
432  // On classe les sommets en fonction de leur signe
433 
434  double zmax = -FLT_MAX ;
435  double zmin = FLT_MAX ;
436  zvals.resize(n) ;
437 
438  for(size_t i=0;i<n;i++)
439  {
440  double Z = P->vertex(i) * v - C ;
441 
442  if(Z > zmax) zmax = Z ;
443  if(Z < zmin) zmin = Z ;
444 
445  zvals[i] = Z ;
446  }
447 
448  signs.resize(n) ;
449 
450  for(size_t j=0;j<n;j++)
451  {
452  if(zvals[j] < -I_EPS)
453  signs[j] = -1 ;
454  else if(zvals[j] > I_EPS)
455  signs[j] = 1 ;
456  else
457  signs[j] = 0 ;
458 
459  if(Smin > signs[j]) Smin = signs[j] ;
460  if(Smax < signs[j]) Smax = signs[j] ;
461  }
462 }
463 
464 void PrimitivePositioning::split(Polygone *P,const NVector3& v,double C,Primitive *& P_plus,Primitive *& P_moins)
465 {
466  vector<int> Signs ;
467  vector<double> Zvals ;
468 
469  P_plus = NULL ;
470  P_moins = NULL ;
471 
472  int Smin = 1 ;
473  int Smax = -1 ;
474 
475  getsigns(P,v,C,Signs,Zvals,Smin,Smax,_EPS) ;
476 
477  size_t n = P->nbVertices() ;
478 
479  if((Smin == 0)&&(Smax == 0)){ P_moins = P ; P_plus = NULL ; return ; } // Polygone inclus dans le plan
480  if(Smin == 1) { P_plus = P ; P_moins = NULL ; return ; } // Polygone tout positif
481  if(Smax == -1) { P_plus = NULL ; P_moins = P ; return ; } // Polygone tout negatif
482 
483  if((Smin == -1)&&(Smax == 0)) { P_plus = NULL ; P_moins = P ; return ; } // Polygone tout negatif ou null
484  if((Smin == 0)&&(Smax == 1)) { P_plus = P ; P_moins = NULL ; return ; } // Polygone tout positif ou null
485 
486  // Reste le cas Smin = -1 et Smax = 1. Il faut couper
487 
488  vector<Feedback3DColor> Ps ;
489  vector<Feedback3DColor> Ms ;
490 
491  // On teste la coherence des signes.
492 
493  int nZero = 0 ;
494  int nconsZero = 0 ;
495 
496  for(size_t i=0;i<n;i++)
497  {
498  if(Signs[i] == 0)
499  {
500  nZero++ ;
501 
502  if(Signs[(i+1)%n] == 0)
503  nconsZero++ ;
504  }
505  }
506 
507  // Ils y a des imprecisions numeriques dues au fait que le poly estpres du plan.
508  if((nZero > 2)||(nconsZero > 0)) { P_moins = P ; P_plus = NULL ; return ; }
509 
510  int dep=0 ; while(Signs[dep] == 0) dep++ ;
511  int prev_sign = Signs[dep] ;
512 
513  for(size_t j=1;j<=n;j++)
514  {
515  int sign = Signs[(j+dep)%n] ;
516 
517  if(sign == prev_sign)
518  {
519  if(sign == 1) Ps.push_back(P->sommet3DColor(j+dep)) ;
520  if(sign == -1) Ms.push_back(P->sommet3DColor(j+dep)) ;
521  }
522  else if(sign == -prev_sign)
523  {
524  // Il faut effectuer le calcul en utilisant les memes valeurs que pour le calcul des signes,
525  // sinon on risque des incoherences dues aux imprecisions numeriques.
526 
527  double Z1 = Zvals[(j+dep-1)%n] ;
528  double Z2 = Zvals[(j+dep)%n] ;
529 
530  double t = fabs(Z1/(Z2 - Z1)) ;
531 
532  if((t < 0.0)||(t > 1.0))
533  {
534  if(t > 1.0) t = 1.0 ;
535  if(t < 0.0) t = 0.0 ;
536  }
537  Feedback3DColor newVertex((1-t)*P->sommet3DColor(j+dep-1) + t*P->sommet3DColor(j+dep)) ;
538 
539  Ps.push_back(newVertex) ;
540  Ms.push_back(newVertex) ;
541 
542  if(sign == 1)
543  Ps.push_back(P->sommet3DColor(j+dep)) ;
544 
545  if(sign == -1)
546  Ms.push_back(P->sommet3DColor(j+dep)) ;
547 
548  prev_sign = sign ;
549  } // prev_sign != 0 donc necessairement sign = 0. Le sommet tombe dans le plan
550  else
551  {
552  Feedback3DColor newVertex = P->sommet3DColor(j+dep) ;
553 
554  Ps.push_back(newVertex) ;
555  Ms.push_back(newVertex) ;
556 
557  prev_sign = -prev_sign ;
558  }
559  }
560 
561  if(Ps.size() > 100 || Ms.size() > 100 )
562  printf("Primitive::split: Error. nPs = %d, nMs = %d.\n",int(Ps.size()),int(Ms.size())) ;
563 
564  // on suppose pour l'instant que les polygones sont convexes
565 
566  if(Ps.size() == 1)
567  P_plus = new Point(Ps[0]) ;
568  else if(Ps.size() == 2)
569  P_plus = new Segment(Ps[0],Ps[1]) ;
570  else
571  P_plus = new Polygone(Ps) ;
572 
573  if(Ms.size() == 1)
574  P_moins = new Point(Ms[0]) ;
575  else if(Ms.size() == 2)
576  P_moins = new Segment(Ms[0],Ms[1]) ;
577  else
578  P_moins = new Polygone(Ms) ;
579 }
580 
581 void PrimitivePositioning::split(Point *P,const NVector3& v,double C,Primitive * & P_plus,Primitive * & P_moins)
582 {
583  if(v*P->vertex(0)-C > -_EPS)
584  {
585  P_plus = P ;
586  P_moins = NULL ;
587  }
588  else
589  {
590  P_moins = P ;
591  P_plus = NULL ;
592  }
593 }
594 
595 void PrimitivePositioning::split(Segment *S,const NVector3& v,double C,Primitive * & P_plus,Primitive * & P_moins)
596 {
597  vector<int> Signs ;
598  vector<double> Zvals ;
599 
600  P_plus = NULL ;
601  P_moins = NULL ;
602 
603  int Smin = 1 ;
604  int Smax = -1 ;
605 
606  getsigns(S,v,C,Signs,Zvals,Smin,Smax,_EPS) ;
607 
608  size_t n = S->nbVertices() ;
609 
610  if((Smin == 0)&&(Smax == 0)) { P_moins = S ; P_plus = NULL ; return ; } // Polygone inclus dans le plan
611  if(Smin == 1) { P_plus = S ; P_moins = NULL ; return ; } // Polygone tout positif
612  if(Smax == -1) { P_plus = NULL ; P_moins = S ; return ; } // Polygone tout negatif
613 
614  if((Smin == -1)&&(Smax == 0)) { P_plus = NULL ; P_moins = S ; return ; } // Polygone tout negatif ou null
615  if((Smin == 0)&&(Smax == 1)) { P_plus = S ; P_moins = NULL ; return ; } // Polygone tout positif ou null
616 
617  // Reste le cas Smin = -1 et Smax = 1. Il faut couper
618  // On teste la coherence des signes.
619 
620  int nZero = 0 ;
621  int nconsZero = 0 ;
622 
623  for(size_t i=0;i<n;i++)
624  {
625  if(Signs[i] == 0)
626  {
627  nZero++ ;
628 
629  if(Signs[(i+1)%n] == 0)
630  nconsZero++ ;
631  }
632  }
633 
634  // Ils y a des imprecisions numeriques dues au fait que le poly estpres du plan.
635  if((nZero > 2)||(nconsZero > 0)) { P_moins = S ; P_plus = NULL ; return ; }
636 
637  double Z1 = Zvals[0] ;
638  double Z2 = Zvals[1] ;
639 
640  double t = fabs(Z1/(Z2 - Z1)) ;
641 
642  if((t < 0.0)||(t > 1.0))
643  {
644  if(t > 1.0) t = 1.0 ;
645  if(t < 0.0) t = 0.0 ;
646  }
647 
648  Feedback3DColor newVertex = S->sommet3DColor(0) * (1-t) + S->sommet3DColor(1) * t ;
649 
650  if(Signs[0] < 0)
651  {
652  P_plus = new Segment(newVertex,S->sommet3DColor(1)) ;
653  P_moins = new Segment(S->sommet3DColor(0),newVertex) ;
654  }
655  else
656  {
657  P_plus = new Segment(S->sommet3DColor(0),newVertex) ;
658  P_moins = new Segment(newVertex,S->sommet3DColor(1)) ;
659  }
660 }
661 
662 // splits primitive P by plane of equation v.X=c. The upper part is setup in a new primitive called prim_up and
663 // the lower part is in prim_lo.
664 
665 void PrimitivePositioning::splitPrimitive(Primitive *P,const NVector3& v,double c, Primitive *& prim_up,Primitive *& prim_lo)
666 {
667  Polygone *p1 = dynamic_cast<Polygone *>(P) ; if(p1 != NULL) PrimitivePositioning::split(p1,v,c,prim_up,prim_lo) ;
668  Segment *p2 = dynamic_cast<Segment *>(P) ; if(p2 != NULL) PrimitivePositioning::split(p2,v,c,prim_up,prim_lo) ;
669  Point *p3 = dynamic_cast<Point *>(P) ; if(p3 != NULL) PrimitivePositioning::split(p3,v,c,prim_up,prim_lo) ;
670 }
671 
double y
Definition: gpc.h:114
#define FLT_MAX
Definition: Vector3.h:51
virtual const Vector3 & vertex(size_t) const
Definition: Primitive.cpp:79
double y() const
Definition: NVector3.h:68
static gpc_polygon createGPCPolygon_XY(const Polygone *P)
long num_vertices
Definition: gpc.h:119
static void splitPrimitive(Primitive *P, const NVector3 &v, double c, Primitive *&prim_up, Primitive *&prim_lo)
double y() const
Definition: Vector2.h:78
gpc_vertex_list * contour
Definition: gpc.h:127
Definition: gpc.h:106
void gpc_polygon_clip(gpc_op op, gpc_polygon *subj, gpc_polygon *clip, gpc_polygon *result)
Definition: gpc.cpp:1189
virtual size_t nbVertices() const =0
virtual const Vector3 & vertex(size_t) const =0
unsigned long num_contours
Definition: gpc.h:125
double z() const
Definition: Vector3.h:83
double equation(const Vector3 &p) const
Definition: Primitive.cpp:117
virtual AxisAlignedBox_xyz bbox() const =0
static int computeRelativePosition(const Primitive *p1, const Primitive *p2)
double x() const
Definition: Vector3.h:81
double c() const
Definition: Primitive.h:200
virtual const Vector3 & vertex(size_t) const
Definition: Primitive.cpp:59
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
Definition: Primitive.cpp:92
virtual size_t nbVertices() const
Definition: Primitive.h:170
virtual size_t nbVertices() const
Definition: Primitive.h:196
static bool pointOutOfPolygon_XY(const Vector3 &P, const Polygone *Q, double I_EPS)
const NVector3 & normal() const
Definition: Primitive.h:199
double z() const
Definition: NVector3.h:69
gpc_vertex * vertex
Definition: gpc.h:120
double y() const
Definition: Vector3.h:82
int * hole
Definition: gpc.h:126
void gpc_free_polygon(gpc_polygon *p)
Definition: gpc.cpp:1093
double FLOAT
Definition: Types.h:60
void gpc_add_contour(gpc_polygon *p, gpc_vertex_list *new_contour, int hole)
Definition: gpc.cpp:1148
static bool intersectSegments_XY(const Vector2 &P1, const Vector2 &Q1, const Vector2 &P2, const Vector2 &Q2, double I_EPS, double &t1, double &t2)
double x() const
Definition: Vector2.h:77
double x
Definition: gpc.h:113
double x() const
Definition: NVector3.h:67
virtual const Feedback3DColor & sommet3DColor(size_t i) const
Definition: Primitive.cpp:69
virtual const Vector3 & vertex(size_t) const
Definition: Primitive.cpp:97


octovis
Author(s): Kai M. Wurm , Armin Hornung
autogenerated on Wed Jun 5 2019 19:26:39