Fade2.5D Documentation pages v2.01
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 #include "common.h"
24 #if GEOM_PSEUDO3D==GEOM_TRUE
25  namespace GEOM_FADE25D {
26 #elif GEOM_PSEUDO3D==GEOM_FALSE
27  namespace GEOM_FADE2D {
28 #else
29  #error GEOM_PSEUDO3D is not defined
30 #endif
31 
35 {
40 };
41 
58 class CLASS_DECLSPEC Triangle2
59 {
60 public:
65  {
66  aVertexPointer[0]=NULL;
67  aVertexPointer[1]=NULL;
68  aVertexPointer[2]=NULL;
69  aOppTriangles[0]=NULL;
70  aOppTriangles[1]=NULL;
71  aOppTriangles[2]=NULL;
72 
73  } // Never used!
74 
77  void getCorners(Point2*& p0,Point2*& p1,Point2*& p2) const;
78 
79 
89  Point2* getCorner(const int ith) const;
90 
92 /* Get the dual Voronoi vertex - DEPRECATED, but kept for
93  * backwards compatibility - see the new method getCircumcenter()
94 *
95 * @return a std::pair<Point2,bool>, where the first component is the
96 * circumcenter of the triangle (i.e., the dual Voronoi vertex) and
97 * the second component is a boolean value which is normally true to
98 * indicate the computation is reliable.
99 *
100 * @param bForceExact can be used to enforce exact computation with
101 * multiple-precision arithmetic. By default the computationally
102 * more expensive multiple-precision arithmetic is only used for
103 * bad-shaped triangles.
104 *
105 *
106 * \if SECTION_FADE25D
107 * @note The z-coordinate of the returned point is always 0 but you
108 * can use Fade_2D::getHeight(..) to determine the height.
109 * \endif
110 *
111 * @attention Attention: The circumcenter of a nearly collinear triangle
112 * can have coordinates beyond the bounds of floating point arithmetic.
113 * Fade could compute the circumcenter with multiple-precision artihmetic
114 * but it could not represent the result as a point with floatingpoint
115 * coordinates. Thus the involved coordinates are DBL_MAX in such a case
116 * and the boolean return value is then false.
117 *
118 * @note Such extreme numeric cases can easily be avoided by insertion
119 * of four dummy vertices around the triangulation, e.g., at coordinates
120 * 10 times larger than the domain of the data points. This will
121 * automatically restrict the Voronoi diagram of the data points to
122 * this range.
123 */
124 std::pair<Point2,bool> getDual(bool bForceExact=false) const; // DEPRECATED, see getCircumcenter()
125 
153 Point2 getCircumcenter(CircumcenterQuality& ccq,bool bForceExact=false) const;
154 
155 
156 
162 
163 
164 #if GEOM_PSEUDO3D==GEOM_TRUE
170 
171 
172 
173 #endif
174 
187 double getInteriorAngle2D(int ith) const;
188 
189 #if GEOM_PSEUDO3D==GEOM_TRUE
194 double getInteriorAngle25D(int ith) const;
195 #endif
196 
197 
198 
211  double getArea2D() const;
212 
213 
214 
215 
216 #if GEOM_PSEUDO3D==GEOM_TRUE
224  double getArea25D() const;
225 #endif
226 
227 
241  Triangle2* getOppositeTriangle(const int ith) const;
242 
243 
255  int getIntraTriangleIndex(const Point2* p) const;
268  int getIntraTriangleIndex(const Triangle2* pTriangle) const;
269 
275  int getIntraTriangleIndex(const Point2* p0,const Point2* p1) const;
276 
277 
279  //*
280  //*
281  //* Internal use
282 //*/
283  //bool getState() const;
284 
292  double getSquaredEdgeLength2D(int ith) const;
293 
296  double getSquaredEdgeLength(int ith) const; // Deprecated, use getSquaredEdgeLength2D()
297 
298 #if GEOM_PSEUDO3D==GEOM_TRUE
303  double getSquaredEdgeLength25D(int ith) const;
304 #endif
305 //** \brief Method for internal use
306  //*
307  //* Internal use
308 //*/
309  //void setState(bool bState_);
319  void setOppTriangle(const int ith, Triangle2* pTriangle);
322  void setProperties( Point2* pI, Point2* pJ, Point2* pK);
323 
326  void clearProperties();
327 
330  void setPropertiesAndOppT(Point2* pI, Point2* pJ, Point2* pK,Triangle2* pNeig0,Triangle2* pNeig1,Triangle2* pNeig2);
331 
334  void setVertexPointer(const int ith, Point2* pp);
335 
340  bool hasVertex(Point2* pVtx) const;
341 
346  bool hasVertex(const Point2& vtx) const;
347 
352  bool hasOnEdge(int i,const Point2& q) const;
353 
356  int getMaxIndex() const;
357 
360  int getMinIndex() const;
361 
364  double getMaxSqEdgeLen2D() const;
366  void getCommonOffset(double& x,double& y) const;
367 
368 
369  CLASS_DECLSPEC
370  friend std::ostream &operator<<(std::ostream &stream, const Triangle2& c);
372  friend inline void registerTriangles(Triangle2* fromTriangle,int ith,Triangle2* toTriangle,int jth);
373 
374 protected:
375  double computeArea(double l0,double l1,double l2) const;
376  bool getCC_inexact(double avgOffX,double avgOffY,Point2& cc) const;
377 
378 
379  Point2* aVertexPointer[3];
380  Triangle2* aOppTriangles[3];
381  //bool bState;
382 };
383 
384 namespace{
385 inline bool checkRange(int ith)
386 {
387  return (ith==0 || ith==1 || ith==2); // true if ith={0,1,2}
388 }
389 
390 }
391 inline Triangle2* Triangle2::getOppositeTriangle(const int ith) const
392 {
393  assert(checkRange(ith));
394  return aOppTriangles[ith];
395 }
396 
397 inline void Triangle2::setOppTriangle(const int ith, Triangle2* pNeig)
398 {
399  //if(!checkRange(ith))
400  //{
401  //std::cout<<"ith="<<ith<<std::endl;
402  //int* a(NULL);
403  //*a+=1;
404  //}
405 
406  assert(checkRange(ith));
407  aOppTriangles[ith]=pNeig;
408 }
409 
410 
411 inline int Triangle2::getIntraTriangleIndex(const Point2* p0,const Point2* p1) const
412 {
413  for(int i=0;i<3;++i)
414  {
415  int ici1((i+1)%3);
416  int ici2((i+2)%3);
417 
418  if( aVertexPointer[ici1]==p0 && aVertexPointer[ici2]==p1) return i;
419  if( aVertexPointer[ici1]==p1 && aVertexPointer[ici2]==p0) return i;
420  }
421 
422  std::cout<<"BUG: Triangle2::getIntraTriangleIndex failed for"<<std::endl;// COUTOK
423  std::cout<<*p0<<std::endl;// COUTOK
424  std::cout<<*p1<<std::endl;// COUTOK
425  std::cout<<*this<<std::endl;// COUTOK
426  assert(false);
427  return -1;
428 }
429 
430 inline int Triangle2::getIntraTriangleIndex(const Point2* pVtx) const
431 {
432 #ifndef NDEBUG
433  // Just debug code
434  for(int i=0;i<3;++i)
435  {
436  if(aVertexPointer[i]==pVtx)
437  {
438  return i;
439  }
440  }
441  assert(false);
442 #endif
443  return ( (aVertexPointer[1]==pVtx) + 2*(aVertexPointer[2]==pVtx));
444 }
445 
446 
447 inline int Triangle2::getIntraTriangleIndex(const Triangle2* pTriangle) const
448 {
449 #ifndef NDEBUG
450  // Just debug code
451  for(int i=0;i<3;++i)
452  {
453  if(aOppTriangles[i]==pTriangle)
454  {
455  return i;
456  }
457  }
458  assert(false);
459 #endif
460  return ( (aOppTriangles[1]==pTriangle) + 2*(aOppTriangles[2]==pTriangle));
461 }
462 
463 
464 
465 inline Point2* Triangle2::getCorner(const int ith) const
466 {
467  assert(checkRange(ith));
468  return aVertexPointer[ith];
469 }
470 
471 inline void Triangle2::getCorners(Point2*& p0,Point2*& p1,Point2*& p2) const
472 {
473  p0=aVertexPointer[0];
474  p1=aVertexPointer[1];
475  p2=aVertexPointer[2];
476 }
477 
478 inline void Triangle2::setVertexPointer(const int ith, Point2* pp)
479 {
480  aVertexPointer[ith]=pp;
481 }
482 
483 inline void Triangle2::setProperties( Point2* pI, Point2* pJ, Point2* pK)
484 {
485  assert((pI!=NULL && pJ!=NULL && pK!=NULL));
486  aVertexPointer[0]=pI;
487  aVertexPointer[1]=pJ;
488  aVertexPointer[2]=pK;
489  pI->setIncidentTriangle(this);
490  pJ->setIncidentTriangle(this);
491  pK->setIncidentTriangle(this);
492  aOppTriangles[0]=NULL;
493  aOppTriangles[1]=NULL;
494  aOppTriangles[2]=NULL;
495 }
496 
498 {
499  for(int i=0;i<3;++i)
500  {
501  aVertexPointer[i]=NULL;
502  aOppTriangles[i]=NULL;
503  }
504 }
505 
507  Point2* pI, Point2* pJ, Point2* pK,
508  Triangle2* pNeig0,Triangle2* pNeig1,Triangle2* pNeig2
509  )
510 {
511  assert((pI!=NULL && pJ!=NULL && pK!=NULL));
512  aVertexPointer[0]=pI;
513  aVertexPointer[1]=pJ;
514  aVertexPointer[2]=pK;
515  pI->setIncidentTriangle(this);
516  pJ->setIncidentTriangle(this);
517  pK->setIncidentTriangle(this);
518  aOppTriangles[0]=pNeig0;
519  aOppTriangles[1]=pNeig1;
520  aOppTriangles[2]=pNeig2;
521 }
522 
524 inline void registerTriangles(Triangle2* pFromT,int ith,Triangle2* pToT,int jth)
525 {
526  assert(checkRange(ith));
527  assert(checkRange(jth));
528 
529  pFromT->aOppTriangles[ith]=pToT;
530  pToT->aOppTriangles[jth]=pFromT;
531 
532 }
533 
534 
535 
536 } // (namespace)
std::ostream & operator<<(std::ostream &stream, const Bbox2 &pC)
Print the box.
Definition: Bbox2.h:450
CircumcenterQuality
CircumcenterQuality.
Definition: Triangle2.h:35
@ CCQ_EXACT
Computation with multiple-precision arithmetic, the result is exact (apart from tiny quantization err...
Definition: Triangle2.h:38
@ CCQ_INEXACT
Double precision computation, the result is accurate enough.
Definition: Triangle2.h:37
@ CCQ_OUT_OF_BOUNDS
Computation with multiple-precision arithmetic, but the result is not representable with double preci...
Definition: Triangle2.h:39
@ CCQ_INIT
Init value.
Definition: Triangle2.h:36
Point.
Definition: Point2.h:43
void setIncidentTriangle(Triangle2 *pT)
Associate a triangle with the point.
Definition: Point2.h:484
Triangle.
Definition: Triangle2.h:59
Triangle2()
Constructor.
Definition: Triangle2.h:64
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:506
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:430
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:397
double getArea25D() const
Get 2.5D Area.
bool hasVertex(Point2 *pVtx) const
Has vertex.
void getCorners(Point2 *&p0, Point2 *&p1, Point2 *&p2) const
Get the 3 triangle corners.
Definition: Triangle2.h:471
void setVertexPointer(const int ith, Point2 *pp)
Set the i-th corner.
Definition: Triangle2.h:478
bool hasOnEdge(int i, const Point2 &q) const
Has point on edge.
Triangle2 * getOppositeTriangle(const int ith) const
Get the i-th neighbor triangle.
Definition: Triangle2.h:391
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:497
double getInteriorAngle2D(int ith) const
Get interior 2D angle.
double getMaxSqEdgeLen2D() const
Get the maximum squared 2D edge length.
double getSquaredEdgeLength2D(int ith) const
‍**
void setProperties(Point2 *pI, Point2 *pJ, Point2 *pK)
Set all corners.
Definition: Triangle2.h:483
Vector.
Definition: Vector2.h:38