Fade2.5D Documentation pages v2.12
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
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 
357  bool hasOnEdge(int i,const Point2& q) const;
358 
367  bool hasOn(const Point2& q) const;
368 
369 
372  int getMaxIndex() const;
373 
376  int getMinIndex() const;
377 
380  double getMaxSqEdgeLen2D() const;
382  void getCommonOffset(double& x,double& y) const;
383 
384 
385  CLASS_DECLSPEC
386  friend std::ostream &operator<<(std::ostream &stream, const Triangle2& c);
388  friend inline void registerTriangles(Triangle2* fromTriangle,int ith,Triangle2* toTriangle,int jth);
389 
390 protected:
391  double computeArea(double l0,double l1,double l2) const;
392  bool getCC_inexact(double avgOffX,double avgOffY,Point2& cc) const;
393 
394 
395  Point2* aVertexPointer[3];
396  Triangle2* aOppTriangles[3];
397  //bool bState;
398 };
399 
400 namespace{
401 inline bool checkRange(int ith)
402 {
403  return (ith==0 || ith==1 || ith==2); // true if ith={0,1,2}
404 }
405 
406 }
407 inline Triangle2* Triangle2::getOppositeTriangle(const int ith) const
408 {
409  assert(checkRange(ith));
410  return aOppTriangles[ith];
411 }
412 
413 inline void Triangle2::setOppTriangle(const int ith, Triangle2* pNeig)
414 {
415  assert(checkRange(ith));
416  aOppTriangles[ith]=pNeig;
417 }
418 
419 
420 inline int Triangle2::getIntraTriangleIndex(const Point2* p0,const Point2* p1) const
421 {
422  for(int i=0;i<3;++i)
423  {
424  int ici1((i+1)%3);
425  int ici2((i+2)%3);
426 
427  if( aVertexPointer[ici1]==p0 && aVertexPointer[ici2]==p1) return i;
428  if( aVertexPointer[ici1]==p1 && aVertexPointer[ici2]==p0) return i;
429  }
430 
431  std::cout<<"BUG: Triangle2::getIntraTriangleIndex failed for"<<std::endl;// COUTOK
432  std::cout<<*p0<<std::endl;// COUTOK
433  std::cout<<*p1<<std::endl;// COUTOK
434  std::cout<<*this<<std::endl;// COUTOK
435  assert(false);
436  return -1;
437 }
438 
439 inline int Triangle2::getIntraTriangleIndex(const Point2* pVtx) const
440 {
441 #ifndef NDEBUG
442  // Just debug code
443  for(int i=0;i<3;++i)
444  {
445  if(aVertexPointer[i]==pVtx)
446  {
447  return i;
448  }
449  }
450  assert(false);
451 #endif
452  return ( (aVertexPointer[1]==pVtx) + 2*(aVertexPointer[2]==pVtx));
453 }
454 
455 
456 inline int Triangle2::getIntraTriangleIndex(const Triangle2* pTriangle) const
457 {
458 #ifndef NDEBUG
459  // Just debug code
460  for(int i=0;i<3;++i)
461  {
462  if(aOppTriangles[i]==pTriangle)
463  {
464  return i;
465  }
466  }
467  assert(false);
468 #endif
469  return ( (aOppTriangles[1]==pTriangle) + 2*(aOppTriangles[2]==pTriangle));
470 }
471 
472 
473 
474 inline Point2* Triangle2::getCorner(const int ith) const
475 {
476  assert(checkRange(ith));
477  return aVertexPointer[ith];
478 }
479 
480 inline void Triangle2::getCorners(Point2*& p0,Point2*& p1,Point2*& p2) const
481 {
482  p0=aVertexPointer[0];
483  p1=aVertexPointer[1];
484  p2=aVertexPointer[2];
485 }
486 
487 inline void Triangle2::setVertexPointer(const int ith, Point2* pp)
488 {
489  aVertexPointer[ith]=pp;
490 }
491 
492 inline void Triangle2::setProperties( Point2* pI, Point2* pJ, Point2* pK)
493 {
494  assert((pI!=NULL && pJ!=NULL && pK!=NULL));
495  aVertexPointer[0]=pI;
496  aVertexPointer[1]=pJ;
497  aVertexPointer[2]=pK;
498  pI->setIncidentTriangle(this);
499  pJ->setIncidentTriangle(this);
500  pK->setIncidentTriangle(this);
501  aOppTriangles[0]=NULL;
502  aOppTriangles[1]=NULL;
503  aOppTriangles[2]=NULL;
504 }
505 
507 {
508  for(int i=0;i<3;++i)
509  {
510  aVertexPointer[i]=NULL;
511  aOppTriangles[i]=NULL;
512  }
513 }
514 
516  Point2* pI, Point2* pJ, Point2* pK,
517  Triangle2* pNeig0,Triangle2* pNeig1,Triangle2* pNeig2
518  )
519 {
520  assert((pI!=NULL && pJ!=NULL && pK!=NULL));
521  aVertexPointer[0]=pI;
522  aVertexPointer[1]=pJ;
523  aVertexPointer[2]=pK;
524  pI->setIncidentTriangle(this);
525  pJ->setIncidentTriangle(this);
526  pK->setIncidentTriangle(this);
527  aOppTriangles[0]=pNeig0;
528  aOppTriangles[1]=pNeig1;
529  aOppTriangles[2]=pNeig2;
530 }
531 
533 inline void registerTriangles(Triangle2* pFromT,int ith,Triangle2* pToT,int jth)
534 {
535  assert(checkRange(ith));
536  assert(checkRange(jth));
537 
538  pFromT->aOppTriangles[ith]=pToT;
539  pToT->aOppTriangles[jth]=pFromT;
540 
541 }
542 
543 
544 
545 
546 } // (namespace)
std::ostream & operator<<(std::ostream &stream, const Bbox2 &pC)
Print the box.
Definition: Bbox2.h:492
CircumcenterQuality
CircumcenterQuality.
Definition: Triangle2.h:36
@ CCQ_EXACT
Computation with multiple-precision arithmetic, the result is exact (apart from tiny quantization err...
Definition: Triangle2.h:39
@ 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
Point.
Definition: Point2.h:52
void setIncidentTriangle(Triangle2 *pT)
Associate a triangle with the point.
Definition: Point2.h:493
Triangle.
Definition: Triangle2.h:60
Triangle2()
Constructor.
Definition: Triangle2.h:65
Point2 getCircumcenter(CircumcenterQuality &ccq, bool bForceExact=false) const
Get the circumcenter of the triangle.
int getMinIndex() const
Get the index of the smallest edge.
void setPropertiesAndOppT(Point2 *pI, Point2 *pJ, Point2 *pK, Triangle2 *pNeig0, Triangle2 *pNeig1, Triangle2 *pNeig2)
Set all corners and neighbor triangles.
Definition: Triangle2.h:515
Vector2 getNormalVector() const
Get the normal vector of a triangle.
double getSquaredEdgeLength25D(int ith) const
Squared edge length.
int getIntraTriangleIndex(const Point2 *p) const
Get the index of p in the triangle.
Definition: Triangle2.h:439
int getMaxIndex() const
Get the index of the largest edge.
void setOppTriangle(const int ith, Triangle2 *pTriangle)
Set the i-th neighbor triangle.
Definition: Triangle2.h:413
double getArea25D() const
Get 2.5D Area.
void getCorners(Point2 *&p0, Point2 *&p1, Point2 *&p2) const
Get the 3 triangle corners.
Definition: Triangle2.h:480
void setVertexPointer(const int ith, Point2 *pp)
Set the i-th corner.
Definition: Triangle2.h:487
bool hasOnEdge(int i, const Point2 &q) const
Has point on edge.
bool hasOn(const Point2 &q) const
Has on (triangle)
Triangle2 * getOppositeTriangle(const int ith) const
Get the i-th neighbor triangle.
Definition: Triangle2.h:407
bool hasVertex(const Point2 &vtx) const
Has vertex.
double getInteriorAngle25D(int ith) const
Get interior 2.5D angle.
Point2 getBarycenter() const
Get the barycenter of a triangle.
double getArea2D() const
Get 2D Area.
void clearProperties()
Clear all corners and neighbor pointers.
Definition: Triangle2.h:506
double getInteriorAngle2D(int ith) const
Get interior 2D angle.
double getMaxSqEdgeLen2D() const
Get the maximum squared 2D edge length.
double getSquaredEdgeLength2D(int ith) const
‍**
bool hasVertex(const Point2 *pVtx) const
Has vertex.
void setProperties(Point2 *pI, Point2 *pJ, Point2 *pK)
Set all corners.
Definition: Triangle2.h:492
Vector.
Definition: Vector2.h:42