Fade2D Documentation pages v2.03
Delaunay Features
Triangle2.h
Go to the documentation of this file.
1 // Copyright (C) Geom Software e.U, Bernhard Kornberger, Graz/Austria
2 //
3 // This file is part of the Fade2D library. The student license is free
4 // of charge and covers personal non-commercial research. Licensees
5 // holding a commercial license may use this file in accordance with
6 // the Commercial License Agreement.
7 //
8 // This software is provided AS IS with NO WARRANTY OF ANY KIND,
9 // INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS
10 // FOR A PARTICULAR PURPOSE.
11 //
12 // Please contact the author if any conditions of this licensing are
13 // not clear to you.
14 //
15 // Author: Bernhard Kornberger, bkorn (at) geom.at
16 // http://www.geom.at
17 
19 #pragma once
20 #include "Point2.h"
21 
22 
23 
24 #include "common.h"
25 #if GEOM_PSEUDO3D==GEOM_TRUE
26  namespace GEOM_FADE25D {
27 #elif GEOM_PSEUDO3D==GEOM_FALSE
28  namespace GEOM_FADE2D {
29 #else
30  #error GEOM_PSEUDO3D is not defined
31 #endif
32 
36 {
41 };
42 
59 class CLASS_DECLSPEC Triangle2
60 {
61 public:
66  {
67  aVertexPointer[0]=NULL;
68  aVertexPointer[1]=NULL;
69  aVertexPointer[2]=NULL;
70  aOppTriangles[0]=NULL;
71  aOppTriangles[1]=NULL;
72  aOppTriangles[2]=NULL;
73 
74  } // Never used!
75 
78  void getCorners(Point2*& p0,Point2*& p1,Point2*& p2) const;
79 
80 
90  Point2* getCorner(const int ith) const;
91 
93 /* Get the dual Voronoi vertex - DEPRECATED, but kept for
94  * backwards compatibility - see the new method getCircumcenter()
95 *
96 * @return a std::pair<Point2,bool>, where the first component is the
97 * circumcenter of the triangle (i.e., the dual Voronoi vertex) and
98 * the second component is a boolean value which is normally true to
99 * indicate the computation is reliable.
100 *
101 * @param bForceExact can be used to enforce exact computation with
102 * multiple-precision arithmetic. By default the computationally
103 * more expensive multiple-precision arithmetic is only used for
104 * bad-shaped triangles.
105 *
106 *
107 * \if SECTION_FADE25D
108 * @note The z-coordinate of the returned point is always 0 but you
109 * can use Fade_2D::getHeight(..) to determine the height.
110 * \endif
111 *
112 * @attention Attention: The circumcenter of a nearly collinear triangle
113 * can have coordinates beyond the bounds of floating point arithmetic.
114 * Fade could compute the circumcenter with multiple-precision artihmetic
115 * but it could not represent the result as a point with floatingpoint
116 * coordinates. Thus the involved coordinates are DBL_MAX in such a case
117 * and the boolean return value is then false.
118 *
119 * @note Such extreme numeric cases can easily be avoided by insertion
120 * of four dummy vertices around the triangulation, e.g., at coordinates
121 * 10 times larger than the domain of the data points. This will
122 * automatically restrict the Voronoi diagram of the data points to
123 * this range.
124 */
125 std::pair<Point2,bool> getDual(bool bForceExact=false) const; // DEPRECATED, see getCircumcenter()
126 
154 Point2 getCircumcenter(CircumcenterQuality& ccq,bool bForceExact=false) const;
155 
156 
157 
163 
164 
165 #if GEOM_PSEUDO3D==GEOM_TRUE
170  Vector2 getNormalVector() const;
171 
172 
173 
174 #endif
175 
188 double getInteriorAngle2D(int ith) const;
189 
190 #if GEOM_PSEUDO3D==GEOM_TRUE
195 double getInteriorAngle25D(int ith) const;
196 #endif
197 
198 
199 
212  double getArea2D() const;
213 
214 
215 
216 
217 #if GEOM_PSEUDO3D==GEOM_TRUE
225  double getArea25D() const;
226 #endif
227 
228 
242  Triangle2* getOppositeTriangle(const int ith) const;
243 
244 
256  int getIntraTriangleIndex(const Point2* p) const;
269  int getIntraTriangleIndex(const Triangle2* pTriangle) const;
270 
276  int getIntraTriangleIndex(const Point2* p0,const Point2* p1) const;
277 
278 
280  //*
281  //*
282  //* Internal use
283 //*/
284  //bool getState() const;
285 
293  double getSquaredEdgeLength2D(int ith) const;
294 
297  double getSquaredEdgeLength(int ith) const; // Deprecated, use getSquaredEdgeLength2D()
298 
299 #if GEOM_PSEUDO3D==GEOM_TRUE
304  double getSquaredEdgeLength25D(int ith) const;
305 #endif
306 //** \brief Method for internal use
307  //*
308  //* Internal use
309 //*/
310  //void setState(bool bState_);
320  void setOppTriangle(const int ith, Triangle2* pTriangle);
323  void setProperties( Point2* pI, Point2* pJ, Point2* pK);
324 
327  void clearProperties();
328 
331  void setPropertiesAndOppT(Point2* pI, Point2* pJ, Point2* pK,Triangle2* pNeig0,Triangle2* pNeig1,Triangle2* pNeig2);
332 
335  void setVertexPointer(const int ith, Point2* pp);
336 
341  bool hasVertex(const Point2* pVtx) const;
342 
347  bool hasVertex(const Point2& vtx) const;
348 
353  bool hasOnEdge(int i,const Point2& q) const;
354 
357  int getMaxIndex() const;
358 
361  int getMinIndex() const;
362 
365  double getMaxSqEdgeLen2D() const;
367  void getCommonOffset(double& x,double& y) const;
368 
369 
370  CLASS_DECLSPEC
371  friend std::ostream &operator<<(std::ostream &stream, const Triangle2& c);
373  friend inline void registerTriangles(Triangle2* fromTriangle,int ith,Triangle2* toTriangle,int jth);
374 
375 protected:
376  double computeArea(double l0,double l1,double l2) const;
377  bool getCC_inexact(double avgOffX,double avgOffY,Point2& cc) const;
378 
379 
380  Point2* aVertexPointer[3];
381  Triangle2* aOppTriangles[3];
382  //bool bState;
383 };
384 
385 namespace{
386 inline bool checkRange(int ith)
387 {
388  return (ith==0 || ith==1 || ith==2); // true if ith={0,1,2}
389 }
390 
391 }
392 inline Triangle2* Triangle2::getOppositeTriangle(const int ith) const
393 {
394  assert(checkRange(ith));
395  return aOppTriangles[ith];
396 }
397 
398 inline void Triangle2::setOppTriangle(const int ith, Triangle2* pNeig)
399 {
400  assert(checkRange(ith));
401  aOppTriangles[ith]=pNeig;
402 }
403 
404 
405 inline int Triangle2::getIntraTriangleIndex(const Point2* p0,const Point2* p1) const
406 {
407  for(int i=0;i<3;++i)
408  {
409  int ici1((i+1)%3);
410  int ici2((i+2)%3);
411 
412  if( aVertexPointer[ici1]==p0 && aVertexPointer[ici2]==p1) return i;
413  if( aVertexPointer[ici1]==p1 && aVertexPointer[ici2]==p0) return i;
414  }
415 
416  std::cout<<"BUG: Triangle2::getIntraTriangleIndex failed for"<<std::endl;// COUTOK
417  std::cout<<*p0<<std::endl;// COUTOK
418  std::cout<<*p1<<std::endl;// COUTOK
419  std::cout<<*this<<std::endl;// COUTOK
420  assert(false);
421  return -1;
422 }
423 
424 inline int Triangle2::getIntraTriangleIndex(const Point2* pVtx) const
425 {
426 #ifndef NDEBUG
427  // Just debug code
428  for(int i=0;i<3;++i)
429  {
430  if(aVertexPointer[i]==pVtx)
431  {
432  return i;
433  }
434  }
435  assert(false);
436 #endif
437  return ( (aVertexPointer[1]==pVtx) + 2*(aVertexPointer[2]==pVtx));
438 }
439 
440 
441 inline int Triangle2::getIntraTriangleIndex(const Triangle2* pTriangle) const
442 {
443 #ifndef NDEBUG
444  // Just debug code
445  for(int i=0;i<3;++i)
446  {
447  if(aOppTriangles[i]==pTriangle)
448  {
449  return i;
450  }
451  }
452  assert(false);
453 #endif
454  return ( (aOppTriangles[1]==pTriangle) + 2*(aOppTriangles[2]==pTriangle));
455 }
456 
457 
458 
459 inline Point2* Triangle2::getCorner(const int ith) const
460 {
461  assert(checkRange(ith));
462  return aVertexPointer[ith];
463 }
464 
465 inline void Triangle2::getCorners(Point2*& p0,Point2*& p1,Point2*& p2) const
466 {
467  p0=aVertexPointer[0];
468  p1=aVertexPointer[1];
469  p2=aVertexPointer[2];
470 }
471 
472 inline void Triangle2::setVertexPointer(const int ith, Point2* pp)
473 {
474  aVertexPointer[ith]=pp;
475 }
476 
477 inline void Triangle2::setProperties( Point2* pI, Point2* pJ, Point2* pK)
478 {
479  assert((pI!=NULL && pJ!=NULL && pK!=NULL));
480  aVertexPointer[0]=pI;
481  aVertexPointer[1]=pJ;
482  aVertexPointer[2]=pK;
483  pI->setIncidentTriangle(this);
484  pJ->setIncidentTriangle(this);
485  pK->setIncidentTriangle(this);
486  aOppTriangles[0]=NULL;
487  aOppTriangles[1]=NULL;
488  aOppTriangles[2]=NULL;
489 }
490 
491 inline void Triangle2::clearProperties()
492 {
493  for(int i=0;i<3;++i)
494  {
495  aVertexPointer[i]=NULL;
496  aOppTriangles[i]=NULL;
497  }
498 }
499 
500 inline void Triangle2::setPropertiesAndOppT(
501  Point2* pI, Point2* pJ, Point2* pK,
502  Triangle2* pNeig0,Triangle2* pNeig1,Triangle2* pNeig2
503  )
504 {
505  assert((pI!=NULL && pJ!=NULL && pK!=NULL));
506  aVertexPointer[0]=pI;
507  aVertexPointer[1]=pJ;
508  aVertexPointer[2]=pK;
509  pI->setIncidentTriangle(this);
510  pJ->setIncidentTriangle(this);
511  pK->setIncidentTriangle(this);
512  aOppTriangles[0]=pNeig0;
513  aOppTriangles[1]=pNeig1;
514  aOppTriangles[2]=pNeig2;
515 }
516 
518 inline void registerTriangles(Triangle2* pFromT,int ith,Triangle2* pToT,int jth)
519 {
520  assert(checkRange(ith));
521  assert(checkRange(jth));
522 
523  pFromT->aOppTriangles[ith]=pToT;
524  pToT->aOppTriangles[jth]=pFromT;
525 
526 }
527 
528 
529 
530 
531 } // (namespace)
std::ostream & operator<<(std::ostream &stream, const Bbox2 &pC)
Print the box.
Definition: Bbox2.h:492
CircumcenterQuality
CircumcenterQuality.
Definition: Triangle2.h:36
@ CCQ_INEXACT
Double precision computation, the result is accurate enough.
Definition: Triangle2.h:38
@ CCQ_OUT_OF_BOUNDS
Computation with multiple-precision arithmetic, but the result is not representable with double preci...
Definition: Triangle2.h:40
@ CCQ_INIT
Init value.
Definition: Triangle2.h:37
@ CCQ_EXACT
Computation with multiple-precision arithmetic, the result is exact (apart from tiny quantization err...
Definition: Triangle2.h:39
Point.
Definition: Point2.h:43
void setIncidentTriangle(Triangle2 *pT)
Associate a triangle with the point.
Definition: Point2.h:484
Triangle.
Definition: Triangle2.h:60
Point2 getCircumcenter(CircumcenterQuality &ccq, bool bForceExact=false) const
Get the circumcenter of the triangle.
double getSquaredEdgeLength2D(int ith) const
‍**
bool hasVertex(const Point2 *pVtx) const
Has vertex.
bool hasVertex(const Point2 &vtx) const
Has vertex.
double getInteriorAngle2D(int ith) const
Get interior 2D angle.
double getArea2D() const
Get 2D Area.
int getMinIndex() const
Get the index of the smallest edge.
Triangle2()
Constructor.
Definition: Triangle2.h:65
int getMaxIndex() const
Get the index of the largest edge.
Point2 getBarycenter() const
Get the barycenter of a triangle.
bool hasOnEdge(int i, const Point2 &q) const
Has point on edge.
double getMaxSqEdgeLen2D() const
Get the maximum squared 2D edge length.
Vector.
Definition: Vector2.h:38