34#include "constants.hpp"
45#define semilatrect( a, e ) \
46 ( e == 0.0 ? a : ( e == 1.0 ? 2. * a : ( e < 1. ? a * ( 1 - e * e ) : a * ( e * e - 1 ) ) ) )
52#define focus( a, e ) \
53 ( e == 0.0 ? 1e34 : ( e == 1.0 ? 2. * a : ( e < 1. ? a * ( 1 - e * e ) / e : a * ( e * e - 1 ) / e ) ) )
60#define semimaj( p, e ) ( e == 1.0 ? 1e34 : ( e < 1 ? p * e / ( 1 - e * e ) : p * e / ( e * e - 1 ) ) )
67#define eccent( a, p ) \
70 : ( p > 0 ? ( -p / ( 2 * a ) + 0.5 * std::sqrt( p * p / ( a * a ) + 4 ) ) \
71 : ( p / ( 2 * a ) + 0.5 * std::sqrt( p * p / ( a * a ) + 4 ) ) ) ) )
84template <
typename degrad,
typename realT>
90template <
typename _realT>
94 static constexpr realT scale =
96 static constexpr realT degrees = 1;
97 static constexpr realT radians =
pi<realT>() /
static_cast<realT
>( 180 );
98 static constexpr realT full =
static_cast<realT
>( 360.0 );
99 static constexpr realT half =
static_cast<realT
>( 180.0 );
102template <
typename realT>
108template <
typename _realT>
111 typedef _realT realT;
112 static constexpr realT scale = 1;
113 static constexpr realT degrees =
static_cast<realT
>( 180 ) /
pi<realT>();
114 static constexpr realT radians = 1;
116 static constexpr realT half =
pi<realT>();
119template <
typename realT>
132template <
typename realT>
147template <
typename realT>
163template <
class angleT>
164typename angleT::realT
angleMod(
typename angleT::realT q )
166 static_assert( std::is_floating_point<typename angleT::realT>::value,
167 "angleMod: angleT::realT must be floating point" );
169 q = fmod( q, angleT::full );
190template <
class angleT>
191typename angleT::realT
angleDiff(
typename angleT::realT q1,
192 typename angleT::realT q2
195 static_assert( std::is_floating_point<typename angleT::realT>::value,
"angleDiff: realT must be floating point" );
197 typename angleT::realT dq = q2 - q1;
199 if( std::abs( dq ) > angleT::half )
203 dq = dq +
static_cast<typename angleT::realT
>( 2 ) * angleT::half;
207 dq = dq -
static_cast<typename angleT::realT
>( 2 ) * angleT::half;
224template <
class angleT>
225typename angleT::realT
226angleMean(
const std::vector<typename angleT::realT> &q )
228 static_assert( std::is_floating_point<typename angleT::realT>::value,
"angleMean: realT must be floating point" );
230 typename angleT::realT s = 0;
231 typename angleT::realT c = 0;
233 for(
int i = 0; i < q.size(); ++i )
235 s += sin( q[i] / angleT::scale );
236 c += cos( q[i] / angleT::scale );
242 return atan2( s, c ) * angleT::scale;
254template <
int degrad = 0,
typename realT>
256 realT threshold = 0.75
265 full =
static_cast<realT
>( 360 );
271 if( fabs( angles[1] - angles[0] ) > threshold )
273 if( angles[1] > angles[0] )
281 if( angles.size() == 2 )
284 for(
int i = 2; i < angles.size(); ++i )
288 if( fabs( angles[i] - angles[i - 1] ) > threshold )
290 if( angles[i] > angles[i - 1] )
309template <
typename realT>
318 realT cq = cos( angle );
319 realT sq = sin( angle );
321 x1 = x0 * cq - y0 * sq;
322 y1 = x0 * sq + y0 * cq;
constexpr T pi()
Get the value of pi.
constexpr T two_pi()
Get the value of 2pi.
int continueAngles(std::vector< realT > &angles, realT threshold=0.75)
Make a vector of angles continuous, fixing the 0/360 crossing.
angleT::realT angleDiff(typename angleT::realT q1, typename angleT::realT q2)
Calculate the difference between two angles, correctly across 0/360.
angleT::realT angleMod(typename angleT::realT q)
Calculate the angle modulo full-circle, normalizing to a positive value.
realT rtod(realT q)
Convert from radians to degrees.
angleT::realT angleMean(const std::vector< typename angleT::realT > &q)
Calculate the mean of a set of angles, correctly across 0/360.
realT dtor(realT q)
Convert from degrees to radians.
void rotatePoint(realT &x0, realT &y0, realT angle)
Rotate a point about the origin.
Type holding constants related to angle calculations in degrees.