Fade2D Documentation pages v1.96
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 
75 
76 
77 
87  Point2* getCorner(const int ith) const;
88 
90 /* Get the dual Voronoi vertex - DEPRECATED, but kept for
91  * backwards compatibility - see the new method getCircumcenter()
92 *
93 * @return a std::pair<Point2,bool>, where the first component is the
94 * circumcenter of the triangle (i.e., the dual Voronoi vertex) and
95 * the second component is a boolean value which is normally true to
96 * indicate the computation is reliable.
97 *
98 * @param bForceExact can be used to enforce exact computation with
99 * multiple-precision arithmetic. By default the computationally
100 * more expensive multiple-precision arithmetic is only used for
101 * bad-shaped triangles.
102 *
103 *
104 * \if SECTION_FADE25D
105 * @note The z-coordinate of the returned point is always 0 but you
106 * can use Fade_2D::getHeight(..) to determine the height.
107 * \endif
108 *
109 * @attention Attention: The circumcenter of a nearly collinear triangle
110 * can have coordinates beyond the bounds of floating point arithmetic.
111 * Fade could compute the circumcenter with multiple-precision artihmetic
112 * but it could not represent the result as a point with floatingpoint
113 * coordinates. Thus the involved coordinates are DBL_MAX in such a case
114 * and the boolean return value is then false.
115 *
116 * @note Such extreme numeric cases can easily be avoided by insertion
117 * of four dummy vertices around the triangulation, e.g., at coordinates
118 * 10 times larger than the domain of the data points. This will
119 * automatically restrict the Voronoi diagram of the data points to
120 * this range.
121 */
122 std::pair<Point2,bool> getDual(bool bForceExact=false) const; // DEPRECATED, see getCircumcenter()
123 
151 Point2 getCircumcenter(CircumcenterQuality& ccq,bool bForceExact=false) const;
152 
153 
154 
160 
161 
162 #if GEOM_PSEUDO3D==GEOM_TRUE
167  Vector2 getNormalVector() const;
168 
169 
170 
171 #endif
172 
185 double getInteriorAngle2D(int ith) const;
186 
187 #if GEOM_PSEUDO3D==GEOM_TRUE
192 double getInteriorAngle25D(int ith) const;
193 #endif
194 
195 
196 
209  double getArea2D() const;
210 
211 
212 
213 
214 #if GEOM_PSEUDO3D==GEOM_TRUE
222  double getArea25D() const;
223 #endif
224 
225 
239  Triangle2* getOppositeTriangle(const int ith) const;
240 
241 
253  int getIntraTriangleIndex(const Point2* p) const;
266  int getIntraTriangleIndex(const Triangle2* pTriangle) const;
267 
273  int getIntraTriangleIndex(const Point2* p0,const Point2* p1) const;
274 
275 
277  //*
278  //*
279  //* Internal use
280 //*/
281  //bool getState() const;
282 
290  double getSquaredEdgeLength2D(int ith) const;
291 
294  double getSquaredEdgeLength(int ith) const; // Deprecated, use getSquaredEdgeLength2D()
295 
296 #if GEOM_PSEUDO3D==GEOM_TRUE
301  double getSquaredEdgeLength25D(int ith) const;
302 #endif
303 //** \brief Method for internal use
304  //*
305  //* Internal use
306 //*/
307  //void setState(bool bState_);
317  void setOppTriangle(const int ith, Triangle2* pTriangle);
320  void setProperties( Point2* pI, Point2* pJ, Point2* pK);
321 
324  void clearProperties();
325 
328  void setPropertiesAndOppT(Point2* pI, Point2* pJ, Point2* pK,Triangle2* pNeig0,Triangle2* pNeig1,Triangle2* pNeig2);
329 
332  void setVertexPointer(const int ith, Point2* pp);
333 
338  bool hasVertex(Point2* pVtx) const;
339 
344  bool hasVertex(const Point2& vtx) const;
345 
350  bool hasOnEdge(int i,const Point2& q) const;
351 
354  int getMaxIndex() const;
355 
358  int getMinIndex() const;
359 
362  double getMaxSqEdgeLen2D() const;
364  void getCommonOffset(double& x,double& y) const;
365 
366 
367  CLASS_DECLSPEC
368  friend std::ostream &operator<<(std::ostream &stream, const Triangle2& c);
370  friend inline void registerTriangles(Triangle2* fromTriangle,int ith,Triangle2* toTriangle,int jth);
371 
372 protected:
373  double computeArea(double l0,double l1,double l2) const;
374  bool getCC_inexact(double avgOffX,double avgOffY,Point2& cc) const;
375 
376 
377  Point2* aVertexPointer[3];
378  Triangle2* aOppTriangles[3];
379  //bool bState;
380 };
381 
382 namespace{
383 inline bool checkRange(int ith)
384 {
385  return (ith==0 || ith==1 || ith==2); // true if ith={0,1,2}
386 }
387 
388 }
389 inline Triangle2* Triangle2::getOppositeTriangle(const int ith) const
390 {
391  assert(checkRange(ith));
392  return aOppTriangles[ith];
393 }
394 
395 inline void Triangle2::setOppTriangle(const int ith, Triangle2* pNeig)
396 {
397  //if(!checkRange(ith))
398  //{
399  //std::cout<<"ith="<<ith<<std::endl;
400  //int* a(NULL);
401  //*a+=1;
402  //}
403 
404  assert(checkRange(ith));
405  aOppTriangles[ith]=pNeig;
406 }
407 
408 
409 inline int Triangle2::getIntraTriangleIndex(const Point2* p0,const Point2* p1) const
410 {
411  for(int i=0;i<3;++i)
412  {
413  int ici1((i+1)%3);
414  int ici2((i+2)%3);
415 
416  if( aVertexPointer[ici1]==p0 && aVertexPointer[ici2]==p1) return i;
417  if( aVertexPointer[ici1]==p1 && aVertexPointer[ici2]==p0) return i;
418  }
419 
420  std::cout<<"BUG: Triangle2::getIntraTriangleIndex failed for"<<std::endl;// COUTOK
421  std::cout<<*p0<<std::endl;// COUTOK
422  std::cout<<*p1<<std::endl;// COUTOK
423  std::cout<<*this<<std::endl;// COUTOK
424  assert(false);
425  return -1;
426 }
427 
428 inline int Triangle2::getIntraTriangleIndex(const Point2* pVtx) const
429 {
430 #ifndef NDEBUG
431  // Just debug code
432  for(int i=0;i<3;++i)
433  {
434  if(aVertexPointer[i]==pVtx)
435  {
436  return i;
437  }
438  }
439  assert(false);
440 #endif
441  return ( (aVertexPointer[1]==pVtx) + 2*(aVertexPointer[2]==pVtx));
442 }
443 
444 
445 inline int Triangle2::getIntraTriangleIndex(const Triangle2* pTriangle) const
446 {
447 #ifndef NDEBUG
448  // Just debug code
449  for(int i=0;i<3;++i)
450  {
451  if(aOppTriangles[i]==pTriangle)
452  {
453  return i;
454  }
455  }
456  assert(false);
457 #endif
458  return ( (aOppTriangles[1]==pTriangle) + 2*(aOppTriangles[2]==pTriangle));
459 }
460 
461 //inline int Triangle2::getIntraTriangleIndex(const Triangle2* pTriangle) const
462 //{
463 
464  //if(getOppositeTriangle(0)==pTriangle) return 0;
465  //if(getOppositeTriangle(1)==pTriangle) return 1;
466 
467 //#ifndef NDEBUG
468  //if(getOppositeTriangle(2)!=pTriangle)
469  //{
470  //std::cout<<"Triangle2::getIntraTriangleIndex, pTriangle is not a neighbor of the current triangle"<<std::endl;// COUTOK
471  //std::cout<<"Current triangle: "<<*this<<std::endl;// COUTOK
472  //std::cout<<"pTriangle: "<<*pTriangle<<std::endl;// COUTOK
473 
474 
475  //assert(false);
476  //}
477 //#endif
478  //return 2;
479 //}
480 
481 inline Point2* Triangle2::getCorner(const int ith) const
482 {
483  assert(checkRange(ith));
484  return aVertexPointer[ith];
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 
506 inline void Triangle2::clearProperties()
507 {
508  for(int i=0;i<3;++i)
509  {
510  aVertexPointer[i]=NULL;
511  aOppTriangles[i]=NULL;
512  }
513 }
514 
515 inline void Triangle2::setPropertiesAndOppT(
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 } // (namespace)
std::ostream & operator<<(std::ostream &stream, const Bbox2 &pC)
Print the box.
Definition: Bbox2.h:450
CircumcenterQuality
CircumcenterQuality.
Definition: Triangle2.h:35
@ 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
@ CCQ_EXACT
Computation with multiple-precision arithmetic, the result is exact (apart from tiny quantization err...
Definition: Triangle2.h:38
Point.
Definition: Point2.h:43
void setIncidentTriangle(Triangle2 *pT)
Associate a triangle with the point.
Definition: Point2.h:484
Triangle.
Definition: Triangle2.h:59
Point2 getCircumcenter(CircumcenterQuality &ccq, bool bForceExact=false) const
Get the circumcenter of the triangle.
double getSquaredEdgeLength2D(int ith) const
‍**
bool hasVertex(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:64
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