DGtal  1.5.beta
SphericalTriangle.h
1 
17 #pragma once
18 
31 #if defined(SphericalTriangle_RECURSES)
32 #error Recursive header files inclusion detected in SphericalTriangle.h
33 #else // defined(SphericalTriangle_RECURSES)
35 #define SphericalTriangle_RECURSES
36 
37 #if !defined SphericalTriangle_h
39 #define SphericalTriangle_h
40 
42 // Inclusions
43 #include <iostream>
44 #include <map>
45 #include "DGtal/base/Common.h"
46 
48 
49 namespace DGtal
50 {
51 
53  // class SphericalTriangle
60  template <typename TSpace>
62  {
64  typedef TSpace Space;
66  typedef typename Space::RealPoint RealPoint;
67  typedef typename Space::RealVector RealVector;
68  typedef typename RealVector::Component Scalar;
69 
70  // Checks that dimension is 3.
71  BOOST_STATIC_ASSERT(( Space::dimension == 3 ));
72 
73  // ----------------------- Standard services ------------------------------
74  public:
75 
80 
82  SphericalTriangle( const RealVector& va, const RealVector& vb, const RealVector& vc,
83  bool normalize = true )
84  {
85  setA( va, normalize );
86  setB( vb, normalize );
87  setC( vc, normalize );
88  }
89 
94  SphericalTriangle ( const SphericalTriangle & other ) = default;
95 
101  SphericalTriangle & operator= ( const SphericalTriangle & other ) = default;
102 
104  const RealVector& A() const { return myA; }
106  const RealVector& B() const { return myB; }
108  const RealVector& C() const { return myC; }
109 
115  void setA( const RealVector& va, bool normalize = true )
116  {
117  myA = va;
118  if ( normalize )
119  {
120  Scalar n = myA.norm();
121  if ( fabs( n ) > 1e-8 ) myA /= n;
122  else myA = RealVector::zero;
123  }
124  }
125 
131  void setB( const RealVector& vb, bool normalize = true )
132  {
133  myB = vb;
134  if ( normalize )
135  {
136  Scalar n = myB.norm();
137  if ( fabs( n ) > 1e-8 ) myB /= n;
138  else myB = RealVector::zero;
139  }
140  }
146  void setC( const RealVector& vc, bool normalize = true )
147  {
148  myC = vc;
149  if ( normalize )
150  {
151  Scalar n = myC.norm();
152  if ( fabs( n ) > 1e-8 ) myC /= n;
153  else myC = RealVector::zero;
154  }
155  }
156 
158  bool isDegenerate() const
159  {
160  Scalar d[ 3 ] = { ( myA - myB ).norm(),
161  ( myA - myC ).norm(),
162  ( myB - myC ).norm() };
163  // Checks that the spherical triangle is small or thin.
164  if ( ( d[ 0 ] < 1e-8 ) || ( d[ 1 ] < 1e-8 ) || ( d[ 2 ] < 1e-8 ) )
165  return true;
166  // Checks that the spherical triangle is flat.
167  Dimension m = 0;
168  if ( d[ 1 ] > d[ m ] ) m = 1;
169  if ( d[ 2 ] > d[ m ] ) m = 2;
170  return ( fabs( d[ m ] - d[ (m+1)%3 ] - d[ (m+2)%3 ] ) < 1e-8 );
171  }
172 
175  {
176  auto Ap = myB.crossProduct(myC);
177  auto Bp = myC.crossProduct(myA);
178  auto Cp = myA.crossProduct(myB);
179  // Reorient points.
180  if ( Ap.dot( myA ) < 0.0 ) Ap = -Ap;
181  if ( Bp.dot( myB ) < 0.0 ) Bp = -Bp;
182  if ( Cp.dot( myC ) < 0.0 ) Cp = -Cp;
183  return Self( Ap, Bp, Cp, true );
184  }
185 
190  void interiorAngles( Scalar& alpha, Scalar& beta, Scalar& gamma ) const
191  {
192  Self T = polarTriangle();
193  if ( T.A() == RealVector::zero || T.B() == RealVector::zero || T.C() == RealVector::zero )
194  alpha = beta = gamma = 0.0;
195  else
196  {
197  Scalar ca = std::max( -1.0, std::min( 1.0, T.B().dot( T.C() ) ) );
198  Scalar cb = std::max( -1.0, std::min( 1.0, T.C().dot( T.A() ) ) );
199  Scalar cc = std::max( -1.0, std::min( 1.0, T.A().dot( T.B() ) ) );
200  alpha = acos( ca );
201  beta = acos( cb );
202  gamma = acos( cc );
203  }
204  }
205 
207  Scalar area() const
208  {
209  Scalar alpha, beta, gamma;
210  if ( isDegenerate() ) return 0.0;
211  interiorAngles( alpha, beta, gamma );
212  return ( (alpha == 0.0) || (beta == 0.0) || (gamma == 0.0) )
213  ? 0.0 : 2.0*M_PI - alpha - beta - gamma;
214  }
215 
218  {
219  Scalar S = area();
220  RealVector M = myA + myB + myC;
221  RealVector X = ( myB - myA ).crossProduct( myC - myA );
222  if ( M.norm1() <= 1e-8 || X.norm1() <= 1e-8 ) return 0.0;
223  return M.dot( X ) < 0.0 ? -S : S;
224  }
225 
226  // ------------------------- Private Datas --------------------------------
227  private:
228  // ------------------------- Hidden services ------------------------------
229  protected:
236 
237  // ------------------------- Internals ------------------------------------
238  private:
239 
240  }; // end of class SphericalTriangle
241 
242 
243 } // namespace DGtal
244 
245 
247 // Includes inline functions.
248 
249 // //
251 
252 #endif // !defined SphericalTriangle_h
253 
254 #undef SphericalTriangle_RECURSES
255 #endif // else defined(SphericalTriangle_RECURSES)
Aim: Implements basic operations that will be used in Point and Vector classes.
Definition: PointVector.h:593
UnsignedComponent norm1() const
auto dot(const PointVector< dim, OtherComponent, OtherStorage > &v) const -> decltype(DGtal::dotProduct(*this, v))
Dot product with a PointVector.
double norm(const NormType type=L_2) const
auto crossProduct(const PointVector< dim, OtherComponent, OtherStorage > &v) const -> decltype(DGtal::crossProduct(*this, v))
Cross product with a PointVector.
TEuclideanRing Component
Type for Vector elements.
Definition: PointVector.h:614
static Self zero
Static const for zero PointVector.
Definition: PointVector.h:1595
Aim: Represent a triangle drawn onto a sphere of radius 1.
const RealVector & A() const
SphericalTriangle< Space > Self
RealVector::Component Scalar
SphericalTriangle & operator=(const SphericalTriangle &other)=default
BOOST_STATIC_ASSERT((Space::dimension==3))
Space::RealPoint RealPoint
RealVector myC
The point C of the triangle ABC, of unit length.
void setC(const RealVector &vc, bool normalize=true)
SphericalTriangle(const RealVector &va, const RealVector &vb, const RealVector &vc, bool normalize=true)
Default constructor. The object is invalid.
void interiorAngles(Scalar &alpha, Scalar &beta, Scalar &gamma) const
Space::RealVector RealVector
RealVector myA
The point A of the triangle ABC, of unit length.
const RealVector & B() const
const RealVector & C() const
BOOST_CONCEPT_ASSERT((concepts::CSpace< TSpace >))
void setB(const RealVector &vb, bool normalize=true)
SphericalTriangle(const SphericalTriangle &other)=default
RealVector myB
The point B of the triangle ABC, of unit length.
void setA(const RealVector &va, bool normalize=true)
DGtal is the top-level namespace which contains all DGtal functions and types.
auto crossProduct(PointVector< 3, LeftEuclideanRing, LeftContainer > const &lhs, PointVector< 3, RightEuclideanRing, RightContainer > const &rhs) -> decltype(DGtal::constructFromArithmeticConversion(lhs, rhs))
Cross product of two 3D Points/Vectors.
DGtal::uint32_t Dimension
Definition: Common.h:136
Aim: Defines the concept describing a digital space, ie a cartesian product of integer lines.
Definition: CSpace.h:106
int max(int a, int b)