Seg3D  2.4
Seg3D is a free volume segmentation and processing tool developed by the NIH Center for Integrative Biomedical Computing at the University of Utah Scientific Computing and Imaging (SCI) Institute.
v3x1p3x1.hxx
1 /*
2  For more information, please see: http://software.sci.utah.edu
3 
4  The MIT License
5 
6  Copyright (c) 2016 Scientific Computing and Imaging Institute,
7  University of Utah.
8 
9 
10  Permission is hereby granted, free of charge, to any person obtaining a
11  copy of this software and associated documentation files (the "Software"),
12  to deal in the Software without restriction, including without limitation
13  the rights to use, copy, modify, merge, publish, distribute, sublicense,
14  and/or sell copies of the Software, and to permit persons to whom the
15  Software is furnished to do so, subject to the following conditions:
16 
17  The above copyright notice and this permission notice shall be included
18  in all copies or substantial portions of the Software.
19 
20  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26  DEALINGS IN THE SOFTWARE.
27 */
28 
29 // File : v3x1p3x1.hxx
30 // Author : Pavel A. Koshevoy
31 // Created : Mon Jul 1 21:53:36 MDT 2002
32 // Copyright : (C) 2004-2008 University of Utah
33 // Description : 2D, 3D and 3D homogeneous points/vectors.
34 
35 #ifndef V3X1P3X1_HXX_
36 #define V3X1P3X1_HXX_
37 
38 // system includes:
39 #include <math.h>
40 #include <float.h>
41 #include <limits.h>
42 #include <stdlib.h>
43 #include <assert.h>
44 #include <iostream>
45 #include <iomanip>
46 
47 // namespace access:
48 using std::ostream;
49 using std::setw;
50 using std::endl;
51 using std::ios;
52 
53 // forward declarations:
54 class m4x4_t;
55 
56 // MSVC does not define M_PI by default, so I will:
57 #ifndef M_PI
58 #define M_PI 3.14159265358979323846
59 #endif
60 
61 //----------------------------------------------------------------
62 // THE_EPSILON
63 //
64 static const float
65 THE_EPSILON = 1e-6f;
66 
67 //----------------------------------------------------------------
68 // THE_NEAR_ZERO_VECTOR_LENGTH
69 //
70 static const float
71 THE_NEAR_ZERO_VECTOR_LENGTH = 1e+1f * FLT_MIN;
72 
73 
74 // shorthand, undefined at the end of the file:
75 #define X_ data_[0]
76 #define Y_ data_[1]
77 #define Z_ data_[2]
78 #define W_ data_[3]
79 
80 
81 // In order to avoid memory leaks the member functions of these classes
82 // will not allocate anything 'new' on the heap. All operations
83 // work from the stack:
84 
85 //----------------------------------------------------------------
86 // the_duplet_t
87 //
88 // base class for v2x1_t and p2x1_t:
89 //
90 template<class T>
92 {
93 public:
94  the_duplet_t() {}
95 
96  the_duplet_t(const T * data)
97  {
98  X_ = data[0];
99  Y_ = data[1];
100  }
101 
102  the_duplet_t(const T & x, const T & y)
103  {
104  X_ = x;
105  Y_ = y;
106  }
107 
108  // comparison operator:
109  inline bool operator == (const the_duplet_t<T> & d) const
110  { return equal(d); }
111 
112  inline bool operator < (const the_duplet_t<T> & d) const
113  {
114  return ((X_ < d.X_) ||
115  (X_ == d.X_ && Y_ < d.Y_));
116  }
117 
118  // compare this duplet to a given duplet for equality:
119  inline bool equal(const the_duplet_t<T> & d) const
120  {
121  return ((X_ == d.X_) &&
122  (Y_ == d.Y_));
123  }
124 
125  // assign to this duplet:
126  inline void assign(const T * data)
127  {
128  X_ = data[0];
129  Y_ = data[1];
130  }
131 
132  inline void assign(const T & x, const T & y)
133  {
134  X_ = x;
135  Y_ = y;
136  }
137 
138  // scale this duplet by a given factor:
139  inline void scale(const T & s)
140  { X_ *= s; Y_ *= s; }
141 
142  // add a given duplet to this duplet:
143  inline void increment(const the_duplet_t<T> & d)
144  { X_ += d.X_; Y_ += d.Y_; }
145 
146  // subtract a given duplet from this duplet:
147  inline void decrement(const the_duplet_t<T> & d)
148  { X_ -= d.X_; Y_ -= d.Y_; }
149 
150  // this is for debugging purposes:
151  inline void dump(ostream & stream, const char * type_name) const
152  {
153  stream << '(' << type_name << " *)(" << (void *)this << ") "
154  << setw(12) << X_ << ' '
155  << setw(12) << Y_;
156  }
157 
158  // const accessors:
159  inline const T & x() const { return X_; }
160  inline const T & y() const { return Y_; }
161 
162  // non-const accessors:
163  inline T & x() { return X_; }
164  inline T & y() { return Y_; }
165 
166  // array-like accessors:
167  inline const T & operator[] (const unsigned int & i) const
168  { return data_[i]; }
169 
170  inline T & operator[] (const unsigned int & i)
171  { return data_[i]; }
172 
173  // raw data accessors:
174  inline const T * data() const
175  { return data_; }
176 
177  inline T * data()
178  { return data_; }
179 
180 protected:
181  T data_[2];
182 };
183 
184 //----------------------------------------------------------------
185 // operator <<
186 //
187 template<class T>
188 inline ostream &
189 operator << (ostream & stream, const the_duplet_t<T> & p)
190 {
191  p.dump(stream, "the_duplet_t<T>");
192  return stream;
193 }
194 
195 
196 //----------------------------------------------------------------
197 // the_triplet_t
198 //
199 // base class for v3x1_t and p3x1_t:
200 //
201 template<class T>
203 {
204  friend class m4x4_t;
205 
206 public:
207  the_triplet_t() {}
208 
209  the_triplet_t(const T * data)
210  {
211  X_ = data[0];
212  Y_ = data[1];
213  Z_ = data[2];
214  }
215 
216  the_triplet_t(const T & x, const T & y, const T & z)
217  {
218  X_ = x;
219  Y_ = y;
220  Z_ = z;
221  }
222 
223  // comparison operator:
224  inline bool operator == (const the_duplet_t<T> & d) const
225  { return equal(d); }
226 
227  inline bool operator < (const the_duplet_t<T> & d) const
228  {
229  return ((X_ < d.X_) ||
230  (X_ == d.X_ && Y_ < d.Y_) ||
231  (X_ == d.X_ && Y_ == d.Y_ && Z_ < d.Z_));
232  }
233 
234  // compare this triplet to a given triplet for equality:
235  inline bool equal(const the_triplet_t<T> & d) const
236  {
237  return ((X_ == d.X_) &&
238  (Y_ == d.Y_) &&
239  (Z_ == d.Z_));
240  }
241 
242  // assign to this triplet:
243  inline void assign(const T * data)
244  {
245  X_ = data[0];
246  Y_ = data[1];
247  Z_ = data[2];
248  }
249 
250  inline void assign(const T & x, const T & y, const T & z)
251  {
252  X_ = x;
253  Y_ = y;
254  Z_ = z;
255  }
256 
257  // copy data from this triplet:
258  inline void get(T * data) const
259  { get(data[0], data[1], data[2]); }
260 
261  inline void get(T & x, T & y, T & z) const
262  { x = X_; y = Y_; z = Z_; }
263 
264  // scale this triplet by a given factor:
265  inline void scale(const T & s)
266  { X_ *= s; Y_ *= s; Z_ *= s; }
267 
268  // reverse the vector:
269  inline void negate()
270  { X_ = -X_; Y_ = -Y_; Z_ = -Z_; }
271 
272  // add a given triplet to this triplet:
273  inline void increment(const the_triplet_t<T> & d)
274  { X_ += d.X_; Y_ += d.Y_; Z_ += d.Z_; }
275 
276  // subtract a given triplet from this triplet:
277  inline void decrement(const the_triplet_t<T> & d)
278  { X_ -= d.X_; Y_ -= d.Y_; Z_ -= d.Z_; }
279 
280  // this is for debugging purposes:
281  inline void dump(ostream & stream, const char * type_name) const
282  {
283  stream << '(' << type_name << " *)(" << (void *)this << ") "
284  << setw(12) << X_ << ' '
285  << setw(12) << Y_ << ' '
286  << setw(12) << Z_;
287  }
288 
289  // const accessors:
290  inline const T & x() const { return X_; }
291  inline const T & y() const { return Y_; }
292  inline const T & z() const { return Z_; }
293 
294  // non-const accessors:
295  inline T & x() { return X_; }
296  inline T & y() { return Y_; }
297  inline T & z() { return Z_; }
298 
299  // array-like accessors:
300  inline const T & operator[] (const unsigned int & i) const
301  { return data_[i]; }
302 
303  inline T & operator[] (const unsigned int & i)
304  { return data_[i]; }
305 
306  // raw data accessors:
307  inline const T * data() const
308  { return data_; }
309 
310  inline T * data()
311  { return data_; }
312 
313 protected:
314  T data_[3];
315 };
316 
317 //----------------------------------------------------------------
318 // operator <<
319 //
320 template<class T>
321 inline ostream &
322 operator << (ostream & stream, const the_triplet_t<T> & p)
323 {
324  p.dump(stream, "the_triplet_t<T>");
325  return stream;
326 }
327 
328 
329 //----------------------------------------------------------------
330 // the_quadruplet_t
331 //
332 // base class for v4x1_t and p4x1_t:
333 //
334 template<class T>
336 {
337  friend class m4x4_t;
338 
339 public:
340  the_quadruplet_t() {}
341 
342  the_quadruplet_t(const T * data)
343  {
344  X_ = data[0];
345  Y_ = data[1];
346  Z_ = data[2];
347  W_ = data[3];
348  }
349 
350  the_quadruplet_t(const T & x, const T & y, const T & z, const T & w)
351  {
352  X_ = x;
353  Y_ = y;
354  Z_ = z;
355  W_ = w;
356  }
357 
358  // comparison operator:
359  inline bool operator == (const the_duplet_t<T> & d) const
360  { return equal(d); }
361 
362  inline bool operator < (const the_duplet_t<T> & d) const
363  {
364  return ((X_ < d.X_) ||
365  (X_ == d.X_ && Y_ < d.Y_) ||
366  (X_ == d.X_ && Y_ == d.Y_ && Z_ < d.Z_) ||
367  (X_ == d.X_ && Y_ == d.Y_ && Z_ == d.Z_ && W_ < d.W_));
368  }
369 
370  // compare this quadruplet to a given quadruplet for equality:
371  inline bool equal(const the_quadruplet_t<T> & d) const
372  {
373  return ((X_ == d.X_) &&
374  (Y_ == d.Y_) &&
375  (Z_ == d.Z_) &&
376  (W_ == d.W_));
377  }
378 
379  // assign to this quadruplet:
380  inline void assign(const T * data)
381  {
382  X_ = data[0];
383  Y_ = data[1];
384  Z_ = data[2];
385  W_ = data[3];
386  }
387 
388  inline void assign(const T & x, const T & y, const T & z, const T & w)
389  {
390  X_ = x;
391  Y_ = y;
392  Z_ = z;
393  W_ = w;
394  }
395 
396  // scale this quadruplet by a given factor:
397  inline void scale(const T & s)
398  { X_ *= s; Y_ *= s; Z_ *= s; W_ *= s; }
399 
400  // add a given quadruplet to this quadruplet:
401  inline void increment(const the_quadruplet_t<T> & d)
402  { X_ += d.X_; Y_ += d.Y_; Z_ += d.Z_; W_ += d.W_; }
403 
404  // subtract a given quadruplet from this quadruplet:
405  inline void decrement(const the_quadruplet_t<T> & d)
406  { X_ -= d.X_; Y_ -= d.Y_; Z_ -= d.Z_; W_ -= d.W_; }
407 
408  // this is for debugging purposes:
409  inline void dump(ostream & stream, const char * type_name) const
410  {
411  stream << '(' << type_name << " *)(" << (void *)this << ") "
412  << setw(12) << X_ << ' '
413  << setw(12) << Y_ << ' '
414  << setw(12) << Z_ << ' '
415  << setw(12) << W_;
416  }
417 
418  // const accessors:
419  inline const T & x() const { return X_; }
420  inline const T & y() const { return Y_; }
421  inline const T & z() const { return Z_; }
422  inline const T & w() const { return W_; }
423 
424  // non-const accessors:
425  inline T & x() { return X_; }
426  inline T & y() { return Y_; }
427  inline T & z() { return Z_; }
428  inline T & w() { return W_; }
429 
430  // array-like accessors:
431  inline const T & operator[] (const unsigned int & i) const
432  { return data_[i]; }
433 
434  inline T & operator[] (const unsigned int & i)
435  { return data_[i]; }
436 
437  // raw data accessors:
438  inline const T * data() const
439  { return data_; }
440 
441  inline T * data()
442  { return data_; }
443 
444 protected:
445  T data_[4];
446 };
447 
448 //----------------------------------------------------------------
449 // operator <<
450 //
451 template<class T>
452 inline ostream &
453 operator << (ostream & stream, const the_quadruplet_t<T> & p)
454 {
455  p.dump(stream, "the_quadruplet_t<T>");
456  return stream;
457 }
458 
459 
460 //----------------------------------------------------------------
461 // v2x1_t
462 //
463 class v2x1_t : public the_duplet_t<float>
464 {
465 public:
466  v2x1_t() {}
467 
468  v2x1_t(const float * data):
469  the_duplet_t<float>(data)
470  {}
471 
472  v2x1_t(const float & x, const float & y):
473  the_duplet_t<float>(x, y)
474  {}
475 
476  // equality/inequality test operators:
477  inline bool operator == (const v2x1_t & v) const { return equal(v); }
478  inline bool operator != (const v2x1_t & v) const { return !equal(v); }
479 
480  // scale this vector:
481  inline v2x1_t & operator *= (const float & s)
482  { scale(s); return *this; }
483 
484  inline v2x1_t & operator /= (const float & s)
485  { scale(1 / s); return *this; }
486 
487  // return a copy of this vector scaled by a given factor:
488  inline const v2x1_t operator * (const float & s) const
489  { v2x1_t r(*this); r *= s; return r; }
490 
491  inline const v2x1_t operator / (const float & s) const
492  { v2x1_t r(*this); r /= s; return r; }
493 
494  // increment/decrement this vector:
495  inline v2x1_t & operator += (const v2x1_t & v)
496  { increment(v); return *this; }
497 
498  inline v2x1_t & operator -= (const v2x1_t & v)
499  { decrement(v); return *this; }
500 
501  // return a copy of this vector plus/minus a given vector:
502  inline const v2x1_t operator + (const v2x1_t & v) const
503  { v2x1_t r(*this); r += v; return r; }
504 
505  inline const v2x1_t operator - (const v2x1_t & v) const
506  { v2x1_t r(*this); r -= v; return r; }
507 
508  // return the dot product between this vector and a given factor:
509  inline float operator * (const v2x1_t & v) const
510  { return (X_ * v.X_ + Y_ * v.Y_); }
511 
512  // norm operator (returns the magnitude/length/norm of this vector):
513  inline float operator ~ () const { return norm(); }
514 
515  // return a copy of this vector with norm 1.0, or 0.0 if it can not
516  // be normalized (divided by the norm):
517  inline const v2x1_t operator ! () const
518  { v2x1_t r(*this); r.normalize(); return r; }
519 
520  // this = this / |this|
521  inline bool normalize()
522  {
523  float n = norm();
524  if (n < THE_NEAR_ZERO_VECTOR_LENGTH)
525  {
526  scale(0);
527  return false;
528  }
529 
530  scale(1 / n);
531  return true;
532  }
533 
534  // this is necessary in order to allow sorting:
535  inline bool operator < (const v2x1_t & v) const
536  { return norm_sqrd() < v.norm_sqrd(); }
537 
538  // the squared length of this vector
539  inline float norm_sqrd() const
540  { return operator * (*this); }
541 
542  // return the norm (length, magnitude) of this vector:
543  inline float norm() const
544  { return sqrtf(norm_sqrd()); }
545 };
546 
547 //----------------------------------------------------------------
548 // operator -
549 //
550 inline const v2x1_t
551 operator - (const v2x1_t & v)
552 {
553  return (v * (-1.0));
554 }
555 
556 //----------------------------------------------------------------
557 // operator *
558 //
559 inline const v2x1_t
560 operator * (const float & s, const v2x1_t & v)
561 {
562  return v * s;
563 }
564 
565 //----------------------------------------------------------------
566 // operator <<
567 //
568 inline ostream &
569 operator << (ostream & stream, const v2x1_t & v)
570 {
571  v.dump(stream, "v2x1_t");
572  return stream;
573 }
574 
575 
576 //----------------------------------------------------------------
577 // v3x1_t
578 //
579 class v3x1_t : public the_triplet_t<float>
580 {
581 public:
582  v3x1_t() {}
583 
584  v3x1_t(const float * data):
586  {}
587 
588  v3x1_t(const float x, const float & y, const float & z):
589  the_triplet_t<float>(x, y, z)
590  {}
591 
592  v3x1_t(const v2x1_t & v, const float & z = 0.0):
593  the_triplet_t<float>(v.x(), v.y(), z)
594  {}
595 
596  // equality/inequality test operators:
597  inline bool operator == (const v3x1_t & v) const { return equal(v); }
598  inline bool operator != (const v3x1_t & v) const { return !equal(v); }
599 
600  // scale this vector:
601  inline v3x1_t & operator *= (const float & s)
602  { scale(s); return *this; }
603 
604  inline v3x1_t & operator /= (const float & s)
605  { scale(1 / s); return *this; }
606 
607  // return a copy of this vector scaled by a given factor:
608  inline const v3x1_t operator * (const float & s) const
609  { v3x1_t r(*this); r *= s; return r; }
610 
611  inline const v3x1_t operator / (const float & s) const
612  { v3x1_t r(*this); r /= s; return r; }
613 
614  // increment/decrement this vector:
615  inline v3x1_t & operator += (const v3x1_t & v)
616  { increment(v); return *this; }
617 
618  inline v3x1_t & operator -= (const v3x1_t & v)
619  { decrement(v); return *this; }
620 
621  // return a copy of this vector plus/minus a given vector:
622  inline const v3x1_t operator + (const v3x1_t & v) const
623  { v3x1_t r(*this); r += v; return r; }
624 
625  inline const v3x1_t operator - (const v3x1_t & v) const
626  { v3x1_t r(*this); r -= v; return r; }
627 
628  // return the dot product between this vector and a given vector:
629  inline float operator * (const v3x1_t & v) const
630  { return (X_ * v.X_ + Y_ * v.Y_ + Z_ * v.Z_); }
631 
632  // return the cross product between this vector and a given vector:
633  inline const v3x1_t operator % (const v3x1_t & v) const
634  {
635  return v3x1_t((Y_ * v.Z_) - (Z_ * v.Y_),
636  (Z_ * v.X_) - (X_ * v.Z_),
637  (X_ * v.Y_) - (v.X_ * Y_));
638  }
639 
640  // norm operator (returns the magnitude/length/norm of this vector):
641  inline float operator ~ () const { return norm(); }
642 
643  // return a copy of this vector with norm 1.0, or 0.0 if it can not
644  // be normalized (divided by the norm):
645  inline const v3x1_t operator ! () const
646  { v3x1_t r(*this); r.normalize(); return r; }
647 
648  // this = this / |this|
649  inline bool normalize()
650  {
651  float n = norm();
652  if (n < THE_NEAR_ZERO_VECTOR_LENGTH)
653  {
654  scale(0);
655  return false;
656  }
657 
658  scale(1 / n);
659  return true;
660  }
661 
662  // this is necessary in order to allow sorting:
663  inline bool operator < (const v3x1_t & v) const
664  { return norm_sqrd() < v.norm_sqrd(); }
665 
666  // the squared length of this vector
667  inline float norm_sqrd() const
668  { return operator * (*this); }
669 
670  // return the norm (length, magnitude) of this vector:
671  inline float norm() const
672  { return sqrtf(norm_sqrd()); }
673 
674  // return a vector normal to this vector:
675  inline const v3x1_t normal() const
676  {
677  static const v3x1_t xyz[] =
678  {
679  v3x1_t(1.0, 0.0, 0.0),
680  v3x1_t(0.0, 1.0, 0.0),
681  v3x1_t(0.0, 0.0, 1.0)
682  };
683 
684  v3x1_t unit_vec = !(*this);
685  for (unsigned int i = 0; i < 3; i++)
686  {
687  if (fabsf(unit_vec * xyz[i]) > 0.7) continue;
688  return !(unit_vec % xyz[i]);
689  }
690 
691  // this should never happen:
692  assert(false);
693  return v3x1_t(0.0, 0.0, 0.0);
694  }
695 
696  // conversion operator:
697  inline operator v2x1_t() const
698  { return v2x1_t(X_, Y_); }
699 };
700 
701 //----------------------------------------------------------------
702 // operator -
703 //
704 inline const v3x1_t
705 operator - (const v3x1_t & v)
706 {
707  return v3x1_t(-v.x(), -v.y(), -v.z());
708 }
709 
710 //----------------------------------------------------------------
711 // operator *
712 //
713 inline const v3x1_t
714 operator * (const float & s, const v3x1_t & v)
715 {
716  return v * s;
717 }
718 
719 //----------------------------------------------------------------
720 // operator <<
721 //
722 inline ostream &
723 operator << (ostream & stream, const v3x1_t & v)
724 {
725  v.dump(stream, "v3x1_t");
726  return stream;
727 }
728 
729 
730 //----------------------------------------------------------------
731 // p2x1_t
732 //
733 class p2x1_t : public the_duplet_t<float>
734 {
735 public:
736  p2x1_t() {}
737 
738  p2x1_t(const float * data):
739  the_duplet_t<float>(data)
740  {}
741 
742  p2x1_t(const float & x, const float & y):
743  the_duplet_t<float>(x, y)
744  {}
745 
746  // equality/inequality test operators:
747  inline bool operator == (const p2x1_t & p) const { return equal(p); }
748  inline bool operator != (const p2x1_t & p) const { return !equal(p); }
749 
750  // this is necessary in order to allow sorting:
751  inline bool operator < (const p2x1_t & p) const
752  {
753  p2x1_t zero(0.0, 0.0);
754  return (*this - zero) < (p - zero);
755  }
756 
757  // scale this point:
758  inline p2x1_t & operator *= (const float & s)
759  { scale(s); return *this; }
760 
761  inline p2x1_t & operator /= (const float & s)
762  { scale(1 / s); return *this; }
763 
764  // return a copy of this point scaled by a given factor:
765  inline const p2x1_t operator * (const float & s) const
766  { p2x1_t r(*this); r *= s; return r; }
767 
768  inline const p2x1_t operator / (const float & s) const
769  { p2x1_t r(*this); r /= s; return r; }
770 
771  // this is used for linear combinations (in combination with scale):
772  inline const p2x1_t operator + (const p2x1_t & p) const
773  { p2x1_t r(*this); r.increment(p); return r; }
774 
775  // translate this point by a vector:
776  inline p2x1_t & operator += (const v2x1_t & v)
777  { increment(v); return *this; }
778 
779  inline p2x1_t & operator -= (const v2x1_t & v)
780  { decrement(v); return *this; }
781 
782  // return a copy of this point translated by a given vector:
783  inline const p2x1_t operator + (const v2x1_t & v) const
784  { p2x1_t r(data_); r += v; return r; }
785 
786  inline const p2x1_t operator - (const v2x1_t & v) const
787  { p2x1_t r(data_); r -= v; return r; }
788 
789  // return the vector difference between this point a given point:
790  inline const v2x1_t operator - (const p2x1_t & p) const
791  { v2x1_t r(data_); r.decrement(p); return r; }
792 };
793 
794 //----------------------------------------------------------------
795 // operator +
796 //
797 inline const p2x1_t
798 operator + (const v2x1_t & v, const p2x1_t & p)
799 {
800  return p + v;
801 }
802 
803 //----------------------------------------------------------------
804 // operator *
805 //
806 inline const p2x1_t
807 operator * (const float & s, const p2x1_t & p)
808 {
809  return p * s;
810 }
811 
812 //----------------------------------------------------------------
813 // operator <<
814 //
815 inline ostream &
816 operator << (ostream & stream, const p2x1_t & p)
817 {
818  p.dump(stream, "p2x1_t");
819  return stream;
820 }
821 
822 
823 //----------------------------------------------------------------
824 // p3x1_t
825 //
826 class p3x1_t : public the_triplet_t<float>
827 {
828 public:
829  p3x1_t() {}
830 
831  p3x1_t(const float * data):
833  {}
834 
835  p3x1_t(const float & x, const float & y, const float & z):
836  the_triplet_t<float>(x, y, z)
837  {}
838 
839  p3x1_t(const p2x1_t & p, const float & z = 0.0):
840  the_triplet_t<float>(p.x(), p.y(), z)
841  {}
842 
843  // equality/inequality test operators:
844  inline bool operator == (const p3x1_t & p) const { return equal(p); }
845  inline bool operator != (const p3x1_t & p) const { return !equal(p); }
846 
847  // this is necessary in order to allow sorting:
848  inline bool operator < (const p3x1_t & p) const
849  {
850  p3x1_t zero(0.0, 0.0, 0.0);
851  return (*this - zero) < (p - zero);
852  }
853 
854  // scale this point:
855  inline p3x1_t & operator *= (const float & s)
856  { scale(s); return *this; }
857 
858  inline p3x1_t & operator /= (const float & s)
859  { scale(1 / s); return *this; }
860 
861  // return a copy of this point scaled by a given factor:
862  inline const p3x1_t operator * (const float & s) const
863  { p3x1_t r(*this); r *= s; return r; }
864 
865  inline const p3x1_t operator / (const float & s) const
866  { p3x1_t r(*this); r /= s; return r; }
867 
868  // this is used for linear combinations (in combination with scale):
869  inline const p3x1_t operator + (const p3x1_t & p) const
870  { p3x1_t r(*this); r.increment(p); return r; }
871 
872  // translate this point by a vector:
873  inline p3x1_t & operator += (const v3x1_t & v)
874  { increment(v); return *this; }
875 
876  inline p3x1_t & operator += (const p3x1_t & p)
877  { increment(p); return *this; }
878 
879  inline p3x1_t & operator -= (const v3x1_t & v)
880  { decrement(v); return *this; }
881 
882  // return a copy of this point translated by a given vector:
883  inline const p3x1_t operator + (const v3x1_t & v) const
884  { p3x1_t r(data_); r += v; return r; }
885 
886  inline const p3x1_t operator - (const v3x1_t & v) const
887  { p3x1_t r(data_); r -= v; return r; }
888 
889  // return the vector difference between this point a given point:
890  inline const v3x1_t operator - (const p3x1_t & p) const
891  { v3x1_t r(data_); r.decrement(p); return r; }
892 
893  // conversion operator:
894  inline operator p2x1_t() const
895  { return p2x1_t(X_, Y_); }
896 };
897 
898 //----------------------------------------------------------------
899 // operator +
900 //
901 inline const p3x1_t
902 operator + (const v3x1_t & v, const p3x1_t & p)
903 {
904  return p + v;
905 }
906 
907 //----------------------------------------------------------------
908 // operator *
909 //
910 inline const p3x1_t
911 operator * (const float & s, const p3x1_t & p)
912 {
913  return p * s;
914 }
915 
916 //----------------------------------------------------------------
917 // operator <<
918 //
919 inline ostream &
920 operator << (ostream & stream, const p3x1_t & p)
921 {
922  p.dump(stream, "p3x1_t");
923  return stream;
924 }
925 
926 
927 //----------------------------------------------------------------
928 // p4x1_t
929 //
930 class p4x1_t : public the_quadruplet_t<float>
931 {
932 public:
933  p4x1_t() {}
934 
935  p4x1_t(const float * data):
937  {}
938 
939  p4x1_t(const float & x,
940  const float & y,
941  const float & z,
942  const float & w):
943  the_quadruplet_t<float>(x, y, z, w)
944  {}
945 
946  p4x1_t(const p3x1_t & p, const float & w = 1.0):
947  the_quadruplet_t<float>(p.x(), p.y(), p.z(), w)
948  {}
949 
950  // homogenize this point (x = x/w, y = y/w, z = z/w, w = 1.0):
951  inline void homogenize()
952  { X_ = X_ / W_; Y_ = Y_ / W_; Z_ = Z_ / W_; W_ = 1.0; }
953 
954  // conversion operators:
955  inline operator p3x1_t() const
956  { return p3x1_t(X_ / W_, Y_ / W_, Z_ / W_); }
957 };
958 
959 //----------------------------------------------------------------
960 // operator <<
961 //
962 inline ostream &
963 operator << (ostream & stream, const p4x1_t & p)
964 {
965  p.dump(stream, "p4x1_t");
966  return stream;
967 }
968 
969 
970 // undefine the shorthand:
971 #undef X_
972 #undef Y_
973 #undef Z_
974 #undef W_
975 
976 
977 #endif // V3X1P3X1_HXX_
Definition: v3x1p3x1.hxx:826
Definition: v3x1p3x1.hxx:202
Definition: v3x1p3x1.hxx:579
Definition: v3x1p3x1.hxx:930
Definition: v3x1p3x1.hxx:335
Definition: v3x1p3x1.hxx:733
Definition: v3x1p3x1.hxx:91
Definition: v3x1p3x1.hxx:463