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


octovis
Author(s): Kai M. Wurm , Armin Hornung
autogenerated on Mon Jun 10 2019 14:00:25