mt
 All Classes Files Functions Enumerations Groups Pages
vector3.h
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2006 by Adolfo Rodriguez *
3  * adolfo.rodriguez@upc.edu *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the *
17  * Free Software Foundation, Inc., *
18  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19  ***************************************************************************/
20 
22 
23 // HEADER GUARD
24 #ifndef MT_VECTOR3_H
25 #define MT_VECTOR3_H
26 
27 // UNDEFINES min AND max MACROS IF THEY EXIST
28 #ifdef min
29  #undef min
30 #endif // min
31 
32 #ifdef max
33  #undef max
34 #endif // max
35 
36 // C++ STANDARD HEADERS
37 #include <iostream>
38 #include <stdexcept>
39 
40 // PROJECT HEADERS
41 #include <mt/util/assert/assert_template.h>
42 
43 // MT LIBRARY HEADERS
44 #include <mt/scalar.h>
45 
46 
48 
49 namespace mt
50 {
51 
52 
54 
57 
89 
90 class Vector3
91 {
92 public:
93 
94 // LIFECYCLE
95 
97  Vector3();
98 
100  Vector3(const Scalar& x,
101  const Scalar& y,
102  const Scalar& z);
103 
105  explicit Vector3(const Scalar* v);
106 
107  // Compiler generated copy constructor is being used
108 
109  virtual ~Vector3() {}
110 
111 
112 // OPERATORS
113 
114  // Compiler generated assignment operator is being used
115 
117  Scalar& operator[](size_t n);
118 
120  const Scalar& operator[](size_t n) const;
121 
122  Vector3& operator+=(const Vector3& v);
123  Vector3& operator-=(const Vector3& v);
124 
126  Vector3& operator*=(const Scalar& s);
127 
129  Vector3& operator*=(const Vector3& v);
130 
132  Vector3& operator/=(const Scalar& s);
133 
135  Vector3& operator/=(const Vector3& v);
136 
137 
140  bool operator==(const Vector3& v) const;
141 
142  bool operator!=(const Vector3& v) const;
143 
144 
145 // OPERATIONS
146 
148  Scalar sum() const;
149 
151  Scalar dot(const Vector3& v) const;
152 
154  Vector3 cross(const Vector3& v) const;
155 
157  Scalar length2() const;
158 
160  Scalar length() const;
161 
163  Vector3& normalize();
164 
166  Scalar distance2(const Vector3& v) const;
167 
169  Scalar distance(const Vector3& v) const;
170 
172  Scalar angleCos(const Vector3& v) const;
173 
175  Scalar angleSin(const Vector3& v) const;
176 
178  Scalar angle(const Vector3& v) const;
179 
181  size_t minAxis() const;
182 
184  size_t maxAxis() const;
185 
187  size_t furthestAxis() const;
188 
190  size_t closestAxis() const;
191 
193  Scalar min() const;
194 
196  Scalar max() const;
197 
198 
199 // ACCESS
200 
202  Scalar& at(size_t n);
203 
205  const Scalar& at(size_t n) const;
206 
208  void setValue(const Scalar& x,
209  const Scalar& y,
210  const Scalar& z);
211 
213  void setValue(const Scalar* v);
214 
215 
216 private:
217 
218 // MEMBERS
219 
220 Scalar m_co[3];
221 
222 
223 // FRIENDS
224 
225 friend class Quaternion;
226 
227 };
228 
229 
231 
232 // OPERATORS
233 
234 Vector3 operator+(const Vector3& v);
235 
236 Vector3 operator-(const Vector3& v);
237 
238 Vector3 operator+(const Vector3& v1,
239  const Vector3& v2);
240 
241 Vector3 operator-(const Vector3& v1,
242  const Vector3& v2);
243 
244 Vector3 operator*(const Vector3& v1,
245  const Vector3& v2);
246 
247 Vector3 operator/(const Vector3& v1,
248  const Vector3& v2);
249 
250 Vector3 operator*(const Scalar& s,
251  const Vector3& v);
252 
253 Vector3 operator*(const Vector3& v,
254  const Scalar& s);
255 
256 Vector3 operator/(const Vector3& v,
257  const Scalar& s);
258 
259 std::ostream& operator<<(std::ostream& os,
260  const Vector3& v);
261 
262 
263 // FUNCTIONS
264 
266 Scalar length2(const Vector3& v);
267 
269 Scalar length(const Vector3& v);
270 
272 Vector3 normalize(const Vector3& v);
273 
275 Scalar distance2(const Vector3& v1,
276  const Vector3& v2);
277 
279 Scalar distance(const Vector3& v1,
280  const Vector3& v2);
281 
283 Scalar angleCos(const Vector3& v1,
284  const Vector3& v2);
285 
287 Scalar angleSin(const Vector3& v1,
288  const Vector3& v2);
289 
291 Scalar angle(const Vector3& v1,
292  const Vector3& v2);
293 
295 Vector3 abs(const Vector3& v);
296 
298 Scalar dot(const Vector3& v1,
299  const Vector3& v2);
300 
302 Vector3 cross(const Vector3& v1,
303  const Vector3& v2);
304 
306 Scalar triple(const Vector3& v1,
307  const Vector3& v2,
308  const Vector3& v3);
309 
311 Vector3 lerp(const Vector3& v1,
312  const Vector3& v2,
313  const Scalar& s);
314 
315 
317 
318 // LIFECYCLE
319 
321 {
322  setValue(Scalar(0.0),
323  Scalar(0.0),
324  Scalar(0.0));
325 }
326 
327 
328 inline Vector3::Vector3(const Scalar& x,
329  const Scalar& y,
330  const Scalar& z)
331 {
332  setValue(x, y, z);
333 }
334 
335 
336 inline Vector3::Vector3(const Scalar* v)
337 {
338  setValue(v);
339 }
340 
341 
342 // OPERATORS
343 
344 inline Scalar& Vector3::operator[](size_t n)
345 {
346  return m_co[n];
347 }
348 
349 
350 inline const Scalar& Vector3::operator[](size_t n) const
351 {
352  return m_co[n];
353 }
354 
355 
356 inline Vector3& Vector3::operator+=(const Vector3& v)
357 {
358  m_co[0] += v[0];
359  m_co[1] += v[1];
360  m_co[2] += v[2];
361  return *this;
362 }
363 
364 
365 inline Vector3& Vector3::operator-=(const Vector3& v)
366 {
367  m_co[0] -= v[0];
368  m_co[1] -= v[1];
369  m_co[2] -= v[2];
370  return *this;
371 }
372 
373 
374 inline Vector3& Vector3::operator*=(const Scalar& s)
375 {
376  m_co[0] *= s;
377  m_co[1] *= s;
378  m_co[2] *= s;
379  return *this;
380 }
381 
382 
384 {
385  m_co[0] *= v[0];
386  m_co[1] *= v[1];
387  m_co[2] *= v[2];
388  return *this;
389 }
390 
391 
392 inline Vector3& Vector3::operator/=(const Scalar& s)
393 {
394  m_co[0] /= s;
395  m_co[1] /= s;
396  m_co[2] /= s;
397  return *this;
398 }
399 
400 
402 {
403  m_co[0] /= v[0];
404  m_co[1] /= v[1];
405  m_co[2] /= v[2];
406  return *this;
407 }
408 
409 
410 inline bool Vector3::operator==(const Vector3& v) const
411 {
412  if (this->length2() == Scalar(0.0) ||
413  v.length2() == Scalar(0.0))
414  {
415  return (distance(v) == Scalar(0.0));
416  }
417  else
418  {
419  return (distance(v) == Scalar(0.0)) && (angle(v) == Scalar(0.0));
420  }
421 }
422 
423 
424 inline bool Vector3::operator!=(const Vector3& v) const
425 {
426  return !(*this == v);
427 }
428 
429 
430 // OPERATIONS
431 
432 inline Scalar Vector3::sum() const
433 {
434  return (m_co[0] + m_co[1] + m_co[2]);
435 }
436 
437 
438 inline Scalar Vector3::dot(const Vector3& v) const
439 {
440  return (m_co[0] * v[0]) + (m_co[1] * v[1]) + (m_co[2] * v[2]);
441 }
442 
443 
444 inline Vector3 Vector3::cross(const Vector3& v) const
445 {
446  return Vector3(m_co[1] * v[2] - m_co[2] * v[1],
447  m_co[2] * v[0] - m_co[0] * v[2],
448  m_co[0] * v[1] - m_co[1] * v[0]);
449 }
450 
451 
452 inline Scalar Vector3::length2() const
453 {
454  return dot(*this);
455 }
456 
457 
458 inline Scalar Vector3::length() const
459 {
460  return sqrt(length2());
461 }
462 
463 
465 {
466  *this /= length();
467  return *this;
468 }
469 
470 
471 inline Scalar Vector3::distance2(const Vector3& v) const
472 {
473  Vector3 diff(*this);
474  diff -= v;
475  const Scalar d2 = diff.length2();
476  return d2;
477 }
478 
479 
480 inline Scalar Vector3::distance(const Vector3& v) const
481 {
482  Vector3 diff(*this);
483  diff -= v;
484  const Scalar d = diff.length();
485  return d;
486 }
487 
488 
489 inline Scalar Vector3::angleCos(const Vector3& v) const
490 {
491  const Scalar num(dot(v));
492  const Scalar den(sqrt(length2() * v.length2()));
493 
494  #ifdef MT_USE_BASIC_SCALAR
495  util::Assert((den != Scalar(0.0)),
496  Exception("Angles with respect to the null vector are undefined."));
497  #endif
498 
499  Scalar ang_cos(num / den);
500  return ang_cos;
501 }
502 
503 
504 inline Scalar Vector3::angleSin(const Vector3& v) const
505 {
506  const Vector3 cross(this->cross(v));
507  const Scalar num(cross.length());
508  const Scalar den(sqrt(length2() * v.length2()));
509 
510  Scalar ang_sin(num / den);
511  return ang_sin;
512 }
513 
514 
515 inline Scalar Vector3::angle(const Vector3& v) const
516 {
517  const Scalar ang_cos(angleCos(v));
518  return acos(ang_cos);
519 }
520 
521 
522 inline size_t Vector3::minAxis() const
523 {
524  return m_co[0] < m_co[1] ? (m_co[0] < m_co[2] ? 0 : 2)
525  : (m_co[1] < m_co[2] ? 1 : 2);
526 }
527 
528 
529 inline size_t Vector3::maxAxis() const
530 {
531  return m_co[0] < m_co[1] ? (m_co[1] < m_co[2] ? 2 : 1)
532  : (m_co[0] < m_co[2] ? 2 : 0);
533 }
534 
535 
536 inline size_t Vector3::furthestAxis() const
537 {
538  return abs(*this).minAxis();
539 }
540 
541 
542 inline size_t Vector3::closestAxis() const
543 {
544  return abs(*this).maxAxis();
545 }
546 
547 
548 inline Scalar Vector3::min() const
549 {
550  const size_t t = minAxis();
551  return m_co[t];
552 }
553 
554 
555 inline Scalar Vector3::max() const
556 {
557  const size_t t = maxAxis();
558  return m_co[t];
559 }
560 
561 
562 // ACCESS
563 
564 inline Scalar& Vector3::at(size_t n)
565 {
566  util::Assert(n < 3, std::range_error("Index out of range"));
567  return m_co[n];
568 }
569 
570 
571 inline const Scalar& Vector3::at(size_t n) const
572 {
573  util::Assert(n < 3, std::range_error("Index out of range"));
574  return m_co[n];
575 }
576 
577 
578 inline void Vector3::setValue(const Scalar& x,
579  const Scalar& y,
580  const Scalar& z)
581 {
582  m_co[0] = x;
583  m_co[1] = y;
584  m_co[2] = z;
585 }
586 
587 
588 inline void Vector3::setValue(const Scalar* v)
589 {
590  m_co[0] = v[0];
591  m_co[1] = v[1];
592  m_co[2] = v[2];
593 }
594 
595 
597 
598 // OPERATORS
599 
600 inline Vector3 operator+(const Vector3& v)
601 {
602  return v;
603 }
604 
605 
606 inline Vector3 operator-(const Vector3& v)
607 {
608  const Vector3 v1(-v[0],
609  -v[1],
610  -v[2]);
611  return v1;
612 }
613 
614 
615 inline Vector3 operator+(const Vector3& v1,
616  const Vector3& v2)
617 {
618  Vector3 v(v1);
619  return v+= v2;
620 }
621 
622 
623 inline Vector3 operator-(const Vector3& v1,
624  const Vector3& v2)
625 {
626  Vector3 v(v1);
627  return v-= v2;
628 }
629 
630 
631 inline Vector3 operator*(const Vector3& v1,
632  const Vector3& v2)
633 {
634  Vector3 v(v1);
635  return v*= v2;
636 }
637 
638 
639 inline Vector3 operator/(const Vector3& v1,
640  const Vector3& v2)
641 {
642  Vector3 v(v1);
643  return v/= v2;
644 }
645 
646 
647 inline Vector3 operator*(const Scalar& s,
648  const Vector3& v)
649 {
650  Vector3 v1(v);
651  return v1*= s;
652 }
653 
654 
655 inline Vector3 operator*(const Vector3& v,
656  const Scalar& s)
657 {
658  Vector3 v1(v);
659  return v1*= s;
660 }
661 
662 
663 inline Vector3 operator/(const Vector3& v,
664  const Scalar& s)
665 {
666  Vector3 v1(v);
667  return v1/= s;
668 }
669 
670 
671 inline std::ostream& operator<<(std::ostream& os,
672  const Vector3& v)
673 {
674  return os << '[' << v[0] << ' '
675  << v[1] << ' '
676  << v[2] << ']';
677 }
678 
679 
680 // FUNCTIONS
681 
682 inline Scalar length2(const Vector3& v)
683 {
684  return v.length2();
685 }
686 
687 
688 inline Scalar length(const Vector3& v)
689 {
690  return v.length();
691 }
692 
693 
694 inline Vector3 normalize(const Vector3& v)
695 {
696  Vector3 v_norm(v);
697  v_norm.normalize();
698  return v_norm;
699 }
700 
701 
702 inline Scalar distance2(const Vector3& v1,
703  const Vector3& v2)
704 {
705  return v1.distance2(v2);
706 }
707 
708 
709 inline Scalar distance(const Vector3& v1,
710  const Vector3& v2)
711 {
712  return v1.distance(v2);
713 }
714 
715 
716 inline Scalar angleCos(const Vector3& v1,
717  const Vector3& v2)
718 {
719  return v1.angleCos(v2);
720 }
721 
722 
723 inline Scalar angleSin(const Vector3& v1,
724  const Vector3& v2)
725 {
726  return v1.angleSin(v2);
727 }
728 
729 
730 inline Scalar angle(const Vector3& v1,
731  const Vector3& v2)
732 {
733  return v1.angle(v2);
734 }
735 
736 
737 inline Vector3 abs(const Vector3& v)
738 {
739  Vector3 v_abs(v);
740  v_abs[0] = abs(v_abs[0]);
741  v_abs[1] = abs(v_abs[1]);
742  v_abs[2] = abs(v_abs[2]);
743  return v_abs;
744 }
745 
746 
747 inline Scalar dot(const Vector3& v1,
748  const Vector3& v2)
749 {
750  return v1.dot(v2);
751 }
752 
753 
754 inline Vector3 cross(const Vector3& v1,
755  const Vector3& v2)
756 {
757  const Vector3 v_cross(v1.cross(v2));
758  return v_cross;
759 }
760 
761 
762 inline Scalar triple(const Vector3& v1,
763  const Vector3& v2,
764  const Vector3& v3)
765 {
766  return v1[0] * (v2[1] * v3[2] - v2[2] * v3[1]) +
767  v1[1] * (v2[2] * v3[0] - v2[0] * v3[2]) +
768  v1[2] * (v2[0] * v3[1] - v2[1] * v3[0]);
769 }
770 
771 
772 inline Vector3 lerp(const Vector3& v1,
773  const Vector3& v2,
774  const Scalar& s)
775 {
776  const Vector3 v_in(v1[0] + (v2[0] - v1[0]) * s,
777  v1[1] + (v2[1] - v1[1]) * s,
778  v1[2] + (v2[2] - v1[2]) * s);
779  return v_in;
780 }
781 
782 
783 } // mt
784 
785 #endif // MT_VECTOR3_H