Updating the changelog in the VERSION file, and version_sync.
[shapes.git] / source / specialunits.cc
blobd40a412e2733da7ae73d5db8a7702a1527176d60
1 /* This file is part of Shapes.
3 * Shapes is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * any later version.
8 * Shapes is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with Shapes. If not, see <http://www.gnu.org/licenses/>.
16 * Copyright 2008 Henrik Tidefelt
19 #include <cmath>
21 #include "specialunits.h"
22 #include "consts.h"
23 #include "isnan.h"
25 #include <iostream> /* I get size_t from here... */
26 #include <limits>
28 using namespace Shapes;
30 double
31 Computation::specialUnitCircleHandle( double a0 )
33 /* a0 is half the angle of the circular arc segment.
35 double t = a0 / Computation::RREL_TH_STEP;
36 size_t i = static_cast< size_t >( t );
37 t -= static_cast< double >( i );
38 return ( 1 - t ) * Computation::RREL_TABLE[ i ] + t * Computation::RREL_TABLE[ i + 1 ];
41 double
42 Computation::specialUnitCorrection( double a0, double a1 )
44 const double k2 = -2.0729490168751576;
45 const double k3 = -1.381966011250105;
46 const double wInv = 0.7821424388422419;
48 if( a0 == a1 )
50 return 1;
53 double aRel = wInv * ( a1 - a0 ) / a0 ;
54 double x = 2 * exp( aRel ) / ( 1 + exp( aRel ) ) - 1;
55 if( IS_NAN( x ) )
57 if( a1 > 0 )
59 x = 1;
61 else
63 x = -1;
67 double xSquare = x * x;
68 if( aRel < 0 )
70 return 1 + k2 * xSquare + k3 * x * xSquare;
72 return 1 + 3 * xSquare - 2 * x * xSquare;
75 double
76 Computation::specialUnitNoInflexion( double a0, double a1 )
79 /* tmp is the opposite handles angle. It will be in the range [ -\pi, 2\pi ], so the
80 * handle rays will intersect iff tmp \in [ 0, \pi - a0 ]
82 double tmp = a0 + a1;
83 if( tmp < 0 ||
84 tmp > M_PI - a0 )
86 return HUGE_VAL;
89 return sin( a0 + a1 ) / sin( a0 + a0 + a1 );