1 /*
2   This code is based on code from the Geometric Tools library,
3   which is licensed under a boost license.
4   Such usage is permitted by the boost license; for details,
5   please see the boost license below.
6 */
7 
8 // Geometric Tools, LLC
9 // Copyright (c) 1998-2014
10 // Distributed under the Boost Software License, Version 1.0.
11 // http://www.boost.org/LICENSE_1_0.txt
12 // http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
13 
14 /*************************************************************************
15  *                                                                       *
16  * We release our improvements to the wildMagic code under our standard  *
17  * Vega FEM license, as follows:                                         *
18  *                                                                       *
19  * Vega FEM Simulation Library Version 3.1                               *
20  *                                                                       *
21  * "improvements to the wildMagic library" , Copyright (C) 2016 USC      *
22  * All rights reserved.                                                  *
23  *                                                                       *
24  * Code author: Yijing Li                                                *
25  * http://www.jernejbarbic.com/code                                      *
26  *                                                                       *
27  * Funding: National Science Foundation                                  *
28  *                                                                       *
29  * This library is free software; you can redistribute it and/or         *
30  * modify it under the terms of the BSD-style license that is            *
31  * included with this library in the file LICENSE.txt                    *
32  *                                                                       *
33  * This library is distributed in the hope that it will be useful,       *
34  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
35  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the file     *
36  * LICENSE.TXT for more details.                                         *
37  *                                                                       *
38  *************************************************************************/
39 
40 
41 #ifndef RVECTOR_H
42 #define RVECTOR_H
43 
44 #include "rational.h"
45 #include <cassert>
46 
47 template <int VSIZE, int ISIZE>
48 class RVector
49 {
50 public:
51   // Construction.
52   RVector ();
53   RVector (const RVector& vec);
54 
55   // Coordinate access.
56   inline operator const Rational<ISIZE>* () const;
57   inline operator Rational<ISIZE>* ();
58   inline const Rational<ISIZE>& operator[] (int i) const;
59   inline Rational<ISIZE>& operator[] (int i);
60 
61   // Assignment.
62   RVector& operator= (const RVector& vec);
63 
64   // Comparison.
65   bool operator== (const RVector& vec) const;
66   bool operator!= (const RVector& vec) const;
67   bool operator<  (const RVector& vec) const;
68   bool operator<= (const RVector& vec) const;
69   bool operator>  (const RVector& vec) const;
70   bool operator>= (const RVector& vec) const;
71 
72   // Arithmetic operations.
73   RVector operator+ (const RVector& vec) const;
74   RVector operator- (const RVector& vec) const;
75   RVector operator* (const Rational<ISIZE>& scalar) const;
76   RVector operator/ (const Rational<ISIZE>& scalar) const;
77   RVector operator- () const;
78 
79   // Arithmetic updates.
80   RVector& operator+= (const RVector& vec);
81   RVector& operator-= (const RVector& vec);
82   RVector& operator*= (const Rational<ISIZE>& scalar);
83   RVector& operator/= (const Rational<ISIZE>& scalar);
84 
85   // Vector operations.
86   Rational<ISIZE> squaredLength () const;
87   Rational<ISIZE> dot (const RVector& vec) const;
88 
89 protected:
90   // Support for comparisons.
91   int compareArrays (const RVector& vec) const;
92 
93   Rational<ISIZE> tuple[VSIZE];
94 };
95 
96 template <int VSIZE, int ISIZE>
97 RVector<VSIZE,ISIZE> operator* (const Rational<ISIZE>& scalar,
98     const RVector<VSIZE,ISIZE>& vec);
99 
100 
101 template <int ISIZE>
102 class RVector3 : public RVector<3,ISIZE>
103 {
104 public:
105   // Construction.
106   RVector3 ();
107   RVector3 (const RVector3& vec);
108   RVector3 (const RVector<3,ISIZE>& vec);
109   RVector3 (const Rational<ISIZE>& x, const Rational<ISIZE>& y, const Rational<ISIZE>& z);
110 
111   // Member access.
112   inline Rational<ISIZE> X () const;
113   inline Rational<ISIZE>& X ();
114   inline Rational<ISIZE> Y () const;
115   inline Rational<ISIZE>& Y ();
116   inline Rational<ISIZE> Z () const;
117   inline Rational<ISIZE>& Z ();
118 
119   // Assignment.
120   RVector3& operator= (const RVector3& vec);
121   RVector3& operator= (const RVector<3,ISIZE>& vec);
122 
123   // Returns dot(this,V).
124   Rational<ISIZE> dot (const RVector3& vec) const;
125 
126   // Returns cross(this,V).
127   RVector3 cross (const RVector3& vec) const;
128 
129   // Returns dot(this,cross(U,V)).
130   Rational<ISIZE> tripleScalar (const RVector3& U, const RVector3& V) const;
131 
132 protected:
133   using RVector<3,ISIZE>::tuple;
134 };
135 
136 
137 
138 
139 //----------------------------------------------------------------------------
140 template <int VSIZE, int ISIZE>
RVector()141 RVector<VSIZE,ISIZE>::RVector ()
142 {
143   // For efficiency in construction of large arrays of vectors, the
144   // default constructor does not initialize the vector.
145 }
146 //----------------------------------------------------------------------------
147 template <int VSIZE, int ISIZE>
RVector(const RVector & vec)148 RVector<VSIZE,ISIZE>::RVector (const RVector& vec)
149 {
150   for(int i = 0; i < VSIZE; ++i)
151   {
152     tuple[i] = vec.tuple[i];
153   }
154 }
155 //----------------------------------------------------------------------------
156 template <int VSIZE, int ISIZE>
157 inline RVector<VSIZE,ISIZE>::operator const Rational<ISIZE>* () const
158 {
159   return tuple;
160 }
161 //----------------------------------------------------------------------------
162 template <int VSIZE, int ISIZE>
163 inline RVector<VSIZE,ISIZE>::operator Rational<ISIZE>* ()
164 {
165   return tuple;
166 }
167 //----------------------------------------------------------------------------
168 template <int VSIZE, int ISIZE>
169 inline const Rational<ISIZE>& RVector<VSIZE,ISIZE>::operator[] (int i) const
170 {
171   assert(0 <= i && i < VSIZE);
172   return tuple[i];
173 }
174 //----------------------------------------------------------------------------
175 template <int VSIZE, int ISIZE>
176 inline Rational<ISIZE>& RVector<VSIZE,ISIZE>::operator[] (int i)
177 {
178   assert(0 <= i && i < VSIZE);
179   return tuple[i];
180 }
181 //----------------------------------------------------------------------------
182 template <int VSIZE, int ISIZE>
183 RVector<VSIZE,ISIZE>& RVector<VSIZE,ISIZE>::operator= (const RVector& vec)
184 {
185   for(int i = 0; i < VSIZE; ++i)
186   {
187     tuple[i] = vec.tuple[i];
188   }
189   return *this;
190 }
191 //----------------------------------------------------------------------------
192 template <int VSIZE, int ISIZE>
193 bool RVector<VSIZE,ISIZE>::operator== (const RVector& vec) const
194 {
195   for(int i = 0; i < VSIZE; ++i)
196   {
197     if (tuple[i] != vec.tuple[i])
198     {
199       return false;
200     }
201   }
202   return true;
203 }
204 //----------------------------------------------------------------------------
205 template <int VSIZE, int ISIZE>
206 bool RVector<VSIZE,ISIZE>::operator!= (const RVector& vec) const
207 {
208   return !operator==(vec);
209 }
210 //----------------------------------------------------------------------------
211 template <int VSIZE, int ISIZE>
compareArrays(const RVector & vec)212 int RVector<VSIZE,ISIZE>::compareArrays (const RVector& vec) const
213 {
214   for(int i = 0; i < VSIZE; ++i)
215   {
216     if (tuple[i] < vec.tuple[i])
217     {
218       return -1;
219     }
220     if (tuple[i] > vec.tuple[i])
221     {
222       return +1;
223     }
224   }
225   return 0;
226 }
227 //----------------------------------------------------------------------------
228 template <int VSIZE, int ISIZE>
229 bool RVector<VSIZE,ISIZE>::operator< (const RVector& vec) const
230 {
231   return compareArrays(vec) < 0;
232 }
233 //----------------------------------------------------------------------------
234 template <int VSIZE, int ISIZE>
235 bool RVector<VSIZE,ISIZE>::operator<= (const RVector& vec) const
236 {
237   return compareArrays(vec) <= 0;
238 }
239 //----------------------------------------------------------------------------
240 template <int VSIZE, int ISIZE>
241 bool RVector<VSIZE,ISIZE>::operator> (const RVector& vec) const
242 {
243   return compareArrays(vec) > 0;
244 }
245 //----------------------------------------------------------------------------
246 template <int VSIZE, int ISIZE>
247 bool RVector<VSIZE,ISIZE>::operator>= (const RVector& vec) const
248 {
249   return compareArrays(vec) >= 0;
250 }
251 //----------------------------------------------------------------------------
252 template <int VSIZE, int ISIZE>
253 RVector<VSIZE,ISIZE> RVector<VSIZE,ISIZE>::operator+ (const RVector& vec)
254 const
255 {
256   RVector<VSIZE,ISIZE> sum;
257   for(int i = 0; i < VSIZE; ++i)
258   {
259     sum.tuple[i] = tuple[i] + vec.tuple[i];
260   }
261   return sum;
262 }
263 //----------------------------------------------------------------------------
264 template <int VSIZE, int ISIZE>
265 RVector<VSIZE,ISIZE> RVector<VSIZE,ISIZE>::operator- (const RVector& vec)
266 const
267 {
268   RVector<VSIZE,ISIZE> diff;
269   for(int i = 0; i < VSIZE; ++i)
270   {
271     diff.tuple[i] = tuple[i] - vec.tuple[i];
272   }
273   return diff;
274 }
275 //----------------------------------------------------------------------------
276 template <int VSIZE, int ISIZE>
277 RVector<VSIZE,ISIZE> RVector<VSIZE,ISIZE>::operator*
278 (const Rational<ISIZE>& scalar) const
279 {
280   RVector<VSIZE,ISIZE> prod;
281   for(int i = 0; i < VSIZE; ++i)
282   {
283     prod.tuple[i] = scalar*tuple[i];
284   }
285   return prod;
286 }
287 //----------------------------------------------------------------------------
288 template <int VSIZE, int ISIZE>
289 RVector<VSIZE,ISIZE> RVector<VSIZE,ISIZE>::operator/
290 (const Rational<ISIZE>& scalar) const
291 {
292   assertion(scalar != 0, "Division by zero\n");
293 
294   RVector<VSIZE,ISIZE> div;
295   for(int i = 0; i < VSIZE; ++i)
296   {
297     div.tuple[i] = tuple[i]/scalar;
298   }
299 
300   return div;
301 }
302 //----------------------------------------------------------------------------
303 template <int VSIZE, int ISIZE>
304 RVector<VSIZE,ISIZE> RVector<VSIZE,ISIZE>::operator- () const
305 {
306   RVector<VSIZE,ISIZE> neg;
307   for(int i = 0; i < VSIZE; ++i)
308   {
309     neg.tuple[i] = -tuple[i];
310   }
311   return neg;
312 }
313 //----------------------------------------------------------------------------
314 template <int VSIZE, int ISIZE>
315 RVector<VSIZE,ISIZE> operator* (const Rational<ISIZE>& scalar,
316     const RVector<VSIZE,ISIZE>& vec)
317     {
318   RVector<VSIZE,ISIZE> prod;
319   for(int i = 0; i < VSIZE; ++i)
320   {
321     prod[i] = scalar*vec[i];
322   }
323   return prod;
324     }
325 //----------------------------------------------------------------------------
326 template <int VSIZE, int ISIZE>
327 RVector<VSIZE,ISIZE>& RVector<VSIZE,ISIZE>::operator+= (const RVector& vec)
328 {
329   for(int i = 0; i < VSIZE; ++i)
330   {
331     tuple[i] += vec.tuple[i];
332   }
333   return *this;
334 }
335 //----------------------------------------------------------------------------
336 template <int VSIZE, int ISIZE>
337 RVector<VSIZE,ISIZE>& RVector<VSIZE,ISIZE>::operator-= (const RVector& vec)
338 {
339   for(int i = 0; i < VSIZE; ++i)
340   {
341     tuple[i] -= vec.tuple[i];
342   }
343   return *this;
344 }
345 //----------------------------------------------------------------------------
346 template <int VSIZE, int ISIZE>
347 RVector<VSIZE,ISIZE>& RVector<VSIZE,ISIZE>::operator*=
348     (const Rational<ISIZE>& scalar)
349     {
350   for(int i = 0; i < VSIZE; ++i)
351   {
352     tuple[i] *= scalar;
353   }
354   return *this;
355     }
356 //----------------------------------------------------------------------------
357 template <int VSIZE, int ISIZE>
358 RVector<VSIZE,ISIZE>& RVector<VSIZE,ISIZE>::operator/=
359     (const Rational<ISIZE>& scalar)
360     {
361   //assertion(scalar != 0, "Division by zero\n");
362 
363   for(int i = 0; i < VSIZE; ++i)
364   {
365     tuple[i] /= scalar;
366   }
367   return *this;
368     }
369 //----------------------------------------------------------------------------
370 template <int VSIZE, int ISIZE>
squaredLength()371 Rational<ISIZE> RVector<VSIZE,ISIZE>::squaredLength () const
372 {
373   Rational<ISIZE> sqrLen = 0;
374   for(int i = 0; i < VSIZE; ++i)
375   {
376     sqrLen += tuple[i]*tuple[i];
377   }
378   return sqrLen;
379 }
380 //----------------------------------------------------------------------------
381 template <int VSIZE, int ISIZE>
dot(const RVector & vec)382 Rational<ISIZE> RVector<VSIZE,ISIZE>::dot (const RVector& vec) const
383 {
384   Rational<ISIZE> dot = 0;
385   for(int i = 0; i < VSIZE; ++i)
386   {
387     dot += tuple[i]*vec.tuple[i];
388   }
389   return dot;
390 }
391 //----------------------------------------------------------------------------
392 
393 
394 //----------------------------------------------------------------------------
395 template <int ISIZE>
RVector3()396 RVector3<ISIZE>::RVector3 ()
397 {
398   // the vector is uninitialized
399 }
400 //----------------------------------------------------------------------------
401 template <int ISIZE>
RVector3(const RVector3 & vec)402 RVector3<ISIZE>::RVector3 (const RVector3& vec)
403 {
404   tuple[0] = vec.tuple[0];
405   tuple[1] = vec.tuple[1];
406   tuple[2] = vec.tuple[2];
407 }
408 //----------------------------------------------------------------------------
409 template <int ISIZE>
RVector3(const RVector<3,ISIZE> & vec)410 RVector3<ISIZE>::RVector3 (const RVector<3,ISIZE>& vec)
411 {
412   tuple[0] = vec[0];
413   tuple[1] = vec[1];
414   tuple[2] = vec[2];
415 }
416 //----------------------------------------------------------------------------
417 template <int ISIZE>
RVector3(const Rational<ISIZE> & x,const Rational<ISIZE> & y,const Rational<ISIZE> & z)418 RVector3<ISIZE>::RVector3 (const Rational<ISIZE>& x, const Rational<ISIZE>& y, const Rational<ISIZE>& z)
419 {
420   tuple[0] = x;
421   tuple[1] = y;
422   tuple[2] = z;
423 }
424 //----------------------------------------------------------------------------
425 template <int ISIZE>
426 RVector3<ISIZE>& RVector3<ISIZE>::operator= (const RVector3& vec)
427 {
428   tuple[0] = vec.tuple[0];
429   tuple[1] = vec.tuple[1];
430   tuple[2] = vec.tuple[2];
431   return *this;
432 }
433 //----------------------------------------------------------------------------
434 template <int ISIZE>
435 RVector3<ISIZE>& RVector3<ISIZE>::operator= (const RVector<3,ISIZE>& vec)
436 {
437   tuple[0] = vec[0];
438   tuple[1] = vec[1];
439   tuple[2] = vec[2];
440   return *this;
441 }
442 //----------------------------------------------------------------------------
443 template <int ISIZE>
X()444 inline Rational<ISIZE> RVector3<ISIZE>::X () const
445 {
446   return tuple[0];
447 }
448 //----------------------------------------------------------------------------
449 template <int ISIZE>
X()450 inline Rational<ISIZE>& RVector3<ISIZE>::X ()
451 {
452   return tuple[0];
453 }
454 //----------------------------------------------------------------------------
455 template <int ISIZE>
Y()456 inline Rational<ISIZE> RVector3<ISIZE>::Y () const
457 {
458   return tuple[1];
459 }
460 //----------------------------------------------------------------------------
461 template <int ISIZE>
Y()462 inline Rational<ISIZE>& RVector3<ISIZE>::Y ()
463 {
464   return tuple[1];
465 }
466 //----------------------------------------------------------------------------
467 template <int ISIZE>
Z()468 inline Rational<ISIZE> RVector3<ISIZE>::Z () const
469 {
470   return tuple[2];
471 }
472 //----------------------------------------------------------------------------
473 template <int ISIZE>
Z()474 inline Rational<ISIZE>& RVector3<ISIZE>::Z ()
475 {
476   return tuple[2];
477 }
478 //----------------------------------------------------------------------------
479 template <int ISIZE>
dot(const RVector3 & vec)480 Rational<ISIZE> RVector3<ISIZE>::dot (const RVector3& vec) const
481 {
482   return tuple[0]*vec.tuple[0] + tuple[1]*vec.tuple[1] +
483       tuple[2]*vec.tuple[2];
484 }
485 //----------------------------------------------------------------------------
486 template <int ISIZE>
cross(const RVector3 & vec)487 RVector3<ISIZE> RVector3<ISIZE>::cross (const RVector3& vec) const
488 {
489   return RVector3<ISIZE>(
490       tuple[1]*vec.tuple[2] - tuple[2]*vec.tuple[1],
491       tuple[2]*vec.tuple[0] - tuple[0]*vec.tuple[2],
492       tuple[0]*vec.tuple[1] - tuple[1]*vec.tuple[0]);
493 }
494 //----------------------------------------------------------------------------
495 template <int ISIZE>
tripleScalar(const RVector3 & U,const RVector3 & V)496 Rational<ISIZE> RVector3<ISIZE>::tripleScalar (const RVector3& U, const RVector3& V) const
497 {
498   return dot(U.cross(V));
499 }
500 //----------------------------------------------------------------------------
501 #endif /* RVECTOR_H_ */
502