Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
rational_rotation.h
Go to the documentation of this file.
1 // ======================================================================
2 //
3 // Copyright (c) 1999 The CGAL Consortium
4 
5 // This software and related documentation is part of the Computational
6 // Geometry Algorithms Library (CGAL).
7 // This software and documentation is provided "as-is" and without warranty
8 // of any kind. In no event shall the CGAL Consortium be liable for any
9 // damage of any kind.
10 //
11 // Every use of CGAL requires a license.
12 //
13 // Academic research and teaching license
14 // - For academic research and teaching purposes, permission to use and copy
15 // the software and its documentation is hereby granted free of charge,
16 // provided that it is not a component of a commercial product, and this
17 // notice appears in all copies of the software and related documentation.
18 //
19 // Commercial licenses
20 // - A commercial license is available through Algorithmic Solutions, who also
21 // markets LEDA (http://www.algorithmic-solutions.de).
22 // - Commercial users may apply for an evaluation license by writing to
23 // Algorithmic Solutions (contact@algorithmic-solutions.com).
24 //
25 // The CGAL Consortium consists of Utrecht University (The Netherlands),
26 // ETH Zurich (Switzerland), Free University of Berlin (Germany),
27 // INRIA Sophia-Antipolis (France), Martin-Luther-University Halle-Wittenberg
28 // (Germany), Max-Planck-Institute Saarbrucken (Germany), RISC Linz (Austria),
29 // and Tel-Aviv University (Israel).
30 //
31 // ----------------------------------------------------------------------
32 //
33 // release : CGAL-2.2
34 // release_date : 2000, September 30
35 //
36 // source : rational_rotation.fw
37 // file : include/CGAL/rational_rotation.h
38 // package : Kernel_basic (3.14)
39 // revision : 3.14
40 // revision_date : 15 Sep 2000
41 // author(s) : Stefan Schirra
42 //
43 //
44 // coordinator : MPI, Saarbruecken (<Stefan.Schirra>)
45 // email : contact@cgal.org
46 // www : http://www.cgal.org
47 //
48 // ======================================================================
49 
50 
51 #ifndef CGAL_RATIONAL_ROTATION_H
52 #define CGAL_RATIONAL_ROTATION_H
53 
54 #include <algorithm>
55 
57 
58 template < class NT >
59 void
60 rational_rotation_approximation( const NT & dirx, // dir.x()
61  const NT & diry, // dir.y()
62  NT & sin_num, // return
63  NT & cos_num, // return
64  NT & denom, // return
65  const NT & eps_num, // quality_bound
66  const NT & eps_den )
67 {
68 #ifndef CGAL_CFG_NO_NAMESPACE
69  using std::swap;
70 #endif // CGAL_CFG_NO_NAMESPACE
71 
72  const NT& n = eps_num;
73  const NT& d = eps_den;
74  const NT NT0 = NT(0) ;
75  const NT NT1 = NT(1) ;
76  CGAL_kernel_precondition( n > NT0 );
77  CGAL_kernel_precondition( d > NT0 );
78  NT & sin = sin_num;
79  NT & cos = cos_num;
80  NT & den = denom;
81  NT dx = CGAL_NTS abs(dirx);
82  NT dy = CGAL_NTS abs(diry);
83  NT sq_hypotenuse = dx*dx + dy*dy;
86  NT rhs;
87  bool lower_ok;
88  bool upper_ok;
89 
90  if (dy > dx)
91  {
92  swap (dx,dy);
93  }
94  // approximate sin = dy / sqrt(sq_hypotenuse)
95  // if ( dy / sqrt(sq_hypotenuse) < n/d )
96  if (dy * dy * d * d < sq_hypotenuse * n * n)
97  {
98  cos = NT1;
99  sin = NT0;
100  den = NT1;
101  }
102  else
103  {
104  NT p;
105  NT q;
106  NT p0 = NT0;
107  NT q0 = NT1;
108  NT p1 = NT1;
109  NT q1 = NT1;
110 
111  for(;;)
112  {
113  p = p0 + p1;
114  q = q0 + q1;
115  sin = NT(2)*p*q;
116  den = p*p + q*q;
117 
118  // sanity check for approximation
119  // sin/den < dy/sqrt(hypotenuse) + n/d
120  // && sin/den > dy/sqrt(hypotenuse) - n/d
121  // === sin/den - n/d < dy/sqrt(sq_hypotenuse)
122  // && sin/den + n/d > dy/sqrt(sq_hypotenuse)
123  // === (sin^2 d^2 + n^2 den^2)sq_hypotenuse - 2... < dy^2 d^2 den^2
124  // && (sin^2 d^2 + n^2 den^2)sq_hypotenuse + 2... > dy^2 d^2 den^2
125 
126  common_part = (sin*sin*d*d + n*n*den*den)*sq_hypotenuse;
127  diff_part = NT(2)*n*sin*d*den*sq_hypotenuse;
128  rhs = dy*dy*d*d*den*den;
129 
130  upper_ok = (common_part - diff_part < rhs);
131  lower_ok = (common_part + diff_part > rhs);
132 
133  if ( lower_ok && upper_ok )
134  {
135  // if ( (p*p)%2 + (q*q)%2 > NT1)
136  // {
137  // sin = p*q;
138  // cos = (q*q - p*p)/2; // exact division
139  // den = (p*p + q*q)/2; // exact division
140  // }
141  // else
142  // {
143  cos = q*q - p*p;
144  // }
145 
146  break;
147  }
148  else
149  {
150  // if ( dy/sqrt(sq_hypotenuse) < sin/den )
151  if ( dy*dy*den*den < sin*sin*sq_hypotenuse )
152  {
153  p1 = p;
154  q1 = q;
155  }
156  else
157  {
158  p0 = p;
159  q0 = q;
160  }
161  }
162  } // for(;;)
163  }
164  dx = dirx;
165  dy = diry;
166 
167 
168  if (dy > dx ) { swap (sin,cos); }
169 
170  if (dx < NT0) { cos = - cos; }
171 
172  if (dy < NT0) { sin = - sin; }
173 
174  sin_num = sin;
175  cos_num = cos;
176  denom = den;
177 }
178 
179 
180 template < class NT >
181 void
183  NT & sin_num, // return
184  NT & cos_num, // return
185  NT & denom, // return
186  const NT & eps_num, // quality_bound
187  const NT & eps_den )
188 {
189 #ifndef CGAL_CFG_NO_NAMESPACE
190  using std::swap;
191 #endif // CGAL_CFG_NO_NAMESPACE
192 
193  const NT& n = eps_num;
194  const NT& d = eps_den;
195  const NT NT0 = NT(0) ;
196  const NT NT1 = NT(1) ;
197  CGAL_kernel_precondition( n > NT0 );
198  CGAL_kernel_precondition( d > NT0 );
199  NT& isin = sin_num;
200  NT& icos = cos_num;
201  NT& iden = denom;
202  double dsin = sin(angle);
203  double dcos = cos(angle);
204  double dn = CGAL::to_double(n);
205  double dd = CGAL::to_double(d);
206  double eps = dn / dd;
207  dsin = CGAL_NTS abs( dsin);
208  dcos = CGAL_NTS abs( dcos);
209  NT common_part;
210  NT diff_part;
211  NT os;
212  bool lower_ok;
213  bool upper_ok;
214  bool swapped = false;
215 
216  if (dsin > dcos)
217  {
218  swapped = true;
219  swap (dsin,dcos);
220  }
221  if ( dsin < eps )
222  {
223  icos = NT1;
224  isin = NT0;
225  iden = NT1;
226  }
227  else
228  {
229  NT p;
230  NT q;
231  NT p0 = NT0;
232  NT q0 = NT1;
233  NT p1 = NT1;
234  NT q1 = NT1;
235 
236  for(;;)
237  {
238  p = p0 + p1;
239  q = q0 + q1;
240  isin = NT(2)*p*q;
241  iden = p*p + q*q;
242 
243  // XXX sanity check for approximation
244  // sin/den < dsin + n/d
245  // && sin/den > dsin - n/d
246  // sin < dsin * den + n/d * den
247  // && sin > dsin * den - n/d * den
248  os = CGAL::to_double(isin);
249  diff_part = eps * CGAL::to_double(iden);
250  common_part = dsin * CGAL::to_double(iden);
251 
252  upper_ok = (common_part - diff_part < os);
253  lower_ok = (os < common_part + diff_part);
254 
255  if ( lower_ok && upper_ok )
256  {
257  // if ( (p*p)%2 + (q*q)%2 > NT1)
258  // {
259  // isin = p*q;
260  // icos = (q*q - p*p)/2; // exact division
261  // iden = (p*p + q*q)/2; // exact division
262  // }
263  // else
264  // {
265  icos = q*q - p*p;
266  // }
267 
268  break;
269  }
270  else
271  {
272  // XXX if ( dsin < sin/den )
273  if ( dsin * CGAL::to_double(iden) < CGAL::to_double(isin) )
274  {
275  p1 = p;
276  q1 = q;
277  }
278  else
279  {
280  p0 = p;
281  q0 = q;
282  }
283  }
284  } // for(;;)
285  }
286 
287  if ( swapped ) { swap (isin,icos); }
288 
289  dsin = sin( angle);
290  dcos = cos( angle);
291  if (dcos < 0.0) { icos = - icos; }
292  if (dsin < 0.0) { isin = - isin; }
293 
294  sin_num = isin;
295  cos_num = icos;
296  denom = iden;
297 }
298 
299 
301 
302 
303 #endif // CGAL_RATIONAL_ROTATION_H
void swap(int &a, int &b)
Definition: buildface.cpp:88
CGAL_BEGIN_NAMESPACE double to_double(double d)
Definition: double.h:68
const NT & d
NT dx
NT rhs
NT q1
NT p1
NT & den
CGAL_BEGIN_NAMESPACE void const NT NT NT & cos_num
NT common_part
NT p0
NT q0
NT & sin
double angle(Vector_3< double > v1, Vector_3< double > v2)
Compute the angle between two vectors.
Definition: geometry.C:61
const NT NT0
void rational_rotation_approximation(const double &angle, NT &sin_num, NT &cos_num, NT &denom, const NT &eps_num, const NT &eps_den)
NT sq_hypotenuse
const NT & n
CGAL_BEGIN_NAMESPACE void const NT NT NT NT const NT const NT & eps_den
const NT NT1
bool lower_ok
NT dy
NT q
NT diff_part
CGAL_BEGIN_NAMESPACE void const NT NT & sin_num
NT abs(const NT &x)
Definition: number_utils.h:130
#define CGAL_BEGIN_NAMESPACE
Definition: kdtree_d.h:86
CGAL_BEGIN_NAMESPACE void const NT & diry
#define CGAL_NTS
CGAL_BEGIN_NAMESPACE void const NT NT NT NT & denom
#define CGAL_END_NAMESPACE
Definition: kdtree_d.h:87
#define CGAL_kernel_precondition(EX)
NT & cos
bool upper_ok
CGAL_BEGIN_NAMESPACE void const NT NT NT NT const NT & eps_num