DGtal 1.4.0
Loading...
Searching...
No Matches
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
49namespace 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.
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.
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.
static Self zero
Static const for zero PointVector.
static const Dimension dimension
static constants to store the dimension.
Definition SpaceND.h:132
Aim: Represent a triangle drawn onto a sphere of radius 1.
SphericalTriangle< Space > Self
RealVector::Component Scalar
BOOST_STATIC_ASSERT((Space::dimension==3))
RealVector myC
The point C of the triangle ABC, of unit length.
SphericalTriangle & operator=(const SphericalTriangle &other)=default
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 & C() const
const RealVector & B() const
const RealVector & A() 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