1 /*
2  * Medical Image Registration ToolKit (MIRTK)
3  *
4  * Copyright 2008-2016 Imperial College London
5  * Copyright 2008-2015 Daniel Rueckert, Julia Schnabel
6  * Copyright 2016      Andreas Schuh
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #ifndef MIRTK_Point_H
22 #define MIRTK_Point_H
23 
24 #include "mirtk/Object.h"
25 #include "mirtk/Math.h"
26 
27 
28 namespace mirtk {
29 
30 
31 // Forward declaration of Vector in particular, as its header
32 // includes mirtk/Vector3D.h which in turn includes this file again.
33 // Therefore, only include mirtk/Vector.h after Point is declared.
34 class Vector;
35 class Vector3;
36 class Matrix;
37 
38 
39 /**
40  * 3D point.
41  */
42 class Point
43 {
44 public:
45 
46   double _x; ///< x coordinate of Point
47   double _y; ///< y coordinate of Point
48   double _z; ///< z coordinate of Point
49 
50   //
51   // Constructors and destructor
52   //
53 
54   /// Constructor
55   Point();
56 
57   /// Constructor with three coordinates
58   Point(double, double, double);
59 
60   /// Constructor with three coordinates
61   Point(const double [3]);
62 
63   /// Constructor with Point
64   Point(const Point &);
65 
66   /// Constructor with Vector
67   explicit Point(const Vector3 &);
68 
69   /// Constructor with Vector
70   explicit Point(const Vector &);
71 
72   /// Default destructor
73   virtual ~Point();
74 
75   //
76   // Operators for indexed element access
77   //
78 
79   /// Get reference to i-th point coordinate
80   double &operator [](int i);
81 
82   /// Get const reference to i-th point coordinate
83   const double &operator [](int i) const;
84 
85   /// Get reference to i-th point coordinate
86   double &operator ()(int i);
87 
88   /// Get const reference to i-th point coordinate
89   const double &operator ()(int i) const;
90 
91   /// Cast to C array pointer
92   operator double *();
93 
94   /// Cast to C array pointer
95   operator const double *() const;
96 
97   //
98   // Operators for Point
99   //
100 
101   /// Copy operator for point
102   Point& operator =(const Point&);
103 
104   /// Substraction operator for point
105   Point& operator-=(const Point&);
106 
107   /// Addition operator for point
108   Point& operator+=(const Point&);
109 
110   /// Multiplication operator for point
111   Point& operator*=(const Point&);
112 
113   /// Division operator for point
114   Point& operator/=(const Point&);
115 
116   /// Return result of point substraction
117   Point operator- (const Point&) const;
118 
119   /// Return result of point addition
120   Point operator+ (const Point&) const;
121 
122   /// Return result of point multiplication
123   Point operator* (const Point&) const;
124 
125   /// Return result of point division
126   Point operator/ (const Point&) const;
127 
128   //
129   // Operators for comparison
130   //
131 
132   /// Comparison operator ==
133   int operator==(const Point&) const;
134 
135   /// Comparison operator != (if USE_STL is defined, negate == operator)
136   int operator!=(const Point&) const;
137 
138   /// Comparison operator <
139   int operator<(const Point&) const;
140 
141   /// Comparison operator >
142   int operator>(const Point&) const;
143 
144   //
145   // Operators for double
146   //
147 
148   /// Assign scalar value to all coordinates
149   Point& operator =(double);
150 
151   /// Substraction of double
152   Point& operator-=(double);
153 
154   /// Addition of double
155   Point& operator+=(double);
156 
157   /// Multiplication with double
158   Point& operator*=(double);
159 
160   /// Division by double
161   Point& operator/=(double);
162 
163   // Return result of substraction of double
164   Point  operator- (double) const;
165 
166   // Return result of addition of double
167   Point  operator+ (double) const;
168 
169   // Return result of multiplication with double
170   Point  operator* (double) const;
171 
172   // Return result of division by double
173   Point  operator/ (double) const;
174 
175   //
176   // Operators for Vector3
177   //
178 
179   /// Copy operator for vectors
180   Point& operator =(const Vector3&);
181 
182   /// Substraction operator for vectors
183   Point& operator-=(const Vector3&);
184 
185   /// Addition operator for vectors
186   Point& operator+=(const Vector3&);
187 
188   /// Multiplication operator for vectors (componentwise)
189   Point& operator*=(const Vector3&);
190 
191   /// Division operator for vectors (componentwise)
192   Point& operator/=(const Vector3&);
193 
194   // Return result of vector substraction
195   Point operator- (const Vector3&) const;
196 
197   // Return result of vector addition
198   Point operator+ (const Vector3&) const;
199 
200   // Return result of vector multiplication
201   Point operator* (const Vector3&) const;
202 
203   // Return result of vector division
204   Point operator/ (const Vector3&) const;
205 
206   //
207   // Operators for Vector
208   //
209 
210   /// Copy operator for vectors
211   Point& operator =(const Vector&);
212 
213   /// Substraction operator for vectors
214   Point& operator-=(const Vector&);
215 
216   /// Addition operator for vectors
217   Point& operator+=(const Vector&);
218 
219   /// Multiplication operator for vectors (componentwise)
220   Point& operator*=(const Vector&);
221 
222   /// Division operator for vectors (componentwise)
223   Point& operator/=(const Vector&);
224 
225   // Return result of vector substraction
226   Point operator- (const Vector&) const;
227 
228   // Return result of vector addition
229   Point operator+ (const Vector&) const;
230 
231   // Return result of vector multiplication
232   Point operator* (const Vector&) const;
233 
234   // Return result of vector division
235   Point operator/ (const Vector&) const;
236 
237   //
238   // Operators for Matrix
239   //
240 
241   /// Point multiplication operator for matrices
242   Point& operator*=(const Matrix&);
243 
244   /// Return result from Matrix multiplication
245   Point operator* (const Matrix&) const;
246 
247   //
248   // Distance methods
249   //
250 
251   /// Squared distance from origin
252   double SquaredDistance() const;
253 
254   /// Squared distance from point
255   double SquaredDistance(const Point&) const;
256 
257   /// Distance from origin
258   double Distance() const;
259 
260   /// Distance from point
261   double Distance(const Point&) const;
262 
263 };
264 
265 } // namespace mirtk
266 
267 #include "mirtk/Vector.h"
268 #include "mirtk/Vector3.h"
269 #include "mirtk/Matrix.h"
270 
271 namespace mirtk {
272 
273 ////////////////////////////////////////////////////////////////////////////////
274 // Streaming operators
275 ////////////////////////////////////////////////////////////////////////////////
276 
277 /// Write point coordinates to output stream
278 ostream& operator <<(ostream&, const Point&);
279 
280 /// Read point coordiantes from input stream
281 istream& operator >>(istream&, Point&);
282 
283 ////////////////////////////////////////////////////////////////////////////////
284 // Inline definitions
285 ////////////////////////////////////////////////////////////////////////////////
286 
287 // -----------------------------------------------------------------------------
Point()288 inline Point::Point()
289 {
290   _x = 0;
291   _y = 0;
292   _z = 0;
293 }
294 
295 // -----------------------------------------------------------------------------
Point(double x,double y,double z)296 inline Point::Point(double x, double y, double z)
297 {
298   _x = x;
299   _y = y;
300   _z = z;
301 }
302 
303 // -----------------------------------------------------------------------------
Point(const double p[3])304 inline Point::Point(const double p[3])
305 {
306   _x = p[0];
307   _y = p[1];
308   _z = p[2];
309 }
310 
311 // -----------------------------------------------------------------------------
Point(const Point & p)312 inline Point::Point(const Point& p)
313 {
314   _x = p._x;
315   _y = p._y;
316   _z = p._z;
317 }
318 
319 // -----------------------------------------------------------------------------
Point(const Vector3 & v)320 inline Point::Point(const Vector3& v)
321 {
322   _x = v._x;
323   _y = v._y;
324   _z = v._z;
325 }
326 
327 // -----------------------------------------------------------------------------
Point(const Vector & v)328 inline Point::Point(const Vector& v)
329 {
330   if ((v.Rows() < 0) || (v.Rows() > 3)) {
331     cerr << "Point::Point(const Vector&) Illegal dimension: " << v.Rows() << endl;
332     exit(1);
333   } else {
334     if (v.Rows() == 1) {
335       _x = v(0);
336       _y = 0;
337       _z = 0;
338     }
339     if (v.Rows() == 2) {
340       _x = v(0);
341       _y = v(1);
342       _z = 0;
343     }
344     if (v.Rows() == 3) {
345       _x = v(0);
346       _y = v(1);
347       _z = v(2);
348     }
349   }
350 }
351 
352 // -----------------------------------------------------------------------------
~Point()353 inline Point::~Point()
354 {
355 }
356 
357 // -----------------------------------------------------------------------------
358 inline double &Point::operator [](int i)
359 {
360   switch (i) {
361     case 0: return _x;
362     case 1: return _y;
363     case 2: return _z;
364     default:
365       cerr << "Point::operator []: Invalid coorindate index: " << i << endl;
366       exit(1);
367   }
368 }
369 
370 // -----------------------------------------------------------------------------
371 inline const double &Point::operator [](int i) const
372 {
373   switch (i) {
374     case 0: return _x;
375     case 1: return _y;
376     case 2: return _z;
377     default:
378       cerr << "Point::operator []: Invalid coorindate index: " << i << endl;
379       exit(1);
380   }
381 }
382 
383 // -----------------------------------------------------------------------------
operator()384 inline double &Point::operator ()(int i)
385 {
386   return operator [](i);
387 }
388 
389 // -----------------------------------------------------------------------------
operator()390 inline const double &Point::operator ()(int i) const
391 {
392   return operator [](i);
393 }
394 
395 // -----------------------------------------------------------------------------
396 inline Point::operator double *()
397 {
398   return &_x;
399 }
400 
401 // -----------------------------------------------------------------------------
402 inline Point::operator const double *() const
403 {
404   return &_x;
405 }
406 
407 // -----------------------------------------------------------------------------
408 inline Point& Point::operator =(const Point& p)
409 {
410   _x = p._x;
411   _y = p._y;
412   _z = p._z;
413   return *this;
414 }
415 
416 // -----------------------------------------------------------------------------
417 inline Point& Point::operator+=(const Point& p)
418 {
419   _x += p._x;
420   _y += p._y;
421   _z += p._z;
422   return *this;
423 }
424 
425 // -----------------------------------------------------------------------------
426 inline Point& Point::operator-=(const Point& p)
427 {
428   _x -= p._x;
429   _y -= p._y;
430   _z -= p._z;
431   return *this;
432 }
433 
434 // -----------------------------------------------------------------------------
435 inline Point& Point::operator*=(const Point& p)
436 {
437   _x *= p._x;
438   _y *= p._y;
439   _z *= p._z;
440   return *this;
441 }
442 
443 // -----------------------------------------------------------------------------
444 inline Point& Point::operator/=(const Point& p)
445 {
446   _x /= p._x;
447   _y /= p._y;
448   _z /= p._z;
449   return *this;
450 }
451 
452 // -----------------------------------------------------------------------------
453 inline Point Point::operator+ (const Point& p) const
454 {
455   Point tmp;
456   tmp._x = _x + p._x;
457   tmp._y = _y + p._y;
458   tmp._z = _z + p._z;
459   return tmp;
460 }
461 
462 // -----------------------------------------------------------------------------
463 inline Point Point::operator- (const Point& p) const
464 {
465   Point tmp;
466   tmp._x = _x - p._x;
467   tmp._y = _y - p._y;
468   tmp._z = _z - p._z;
469   return tmp;
470 }
471 
472 // -----------------------------------------------------------------------------
473 inline Point Point::operator* (const Point& p) const
474 {
475   Point tmp;
476   tmp._x = _x * p._x;
477   tmp._y = _y * p._y;
478   tmp._z = _z * p._z;
479   return tmp;
480 }
481 
482 // -----------------------------------------------------------------------------
483 inline Point Point::operator/ (const Point& p) const
484 {
485   Point tmp;
486   tmp._x = _x / p._x;
487   tmp._y = _y / p._y;
488   tmp._z = _z / p._z;
489   return tmp;
490 }
491 
492 // -----------------------------------------------------------------------------
493 inline int Point::operator==(Point const &p) const
494 {
495   return ((_x == p._x) && (_y == p._y) && (_z == p._z));
496 }
497 
498 // -----------------------------------------------------------------------------
499 inline int Point::operator!=(Point const &p) const
500 {
501   return ((_x != p._x) || (_y != p._y) || (_z != p._z));
502 }
503 
504 // -----------------------------------------------------------------------------
505 inline int Point::operator<(Point const& p) const
506 {
507   return ((_x < p._x) && (_y < p._y) && (_z < p._z));
508 }
509 
510 // -----------------------------------------------------------------------------
511 inline int Point::operator>(Point const& p) const
512 {
513   return ((_x > p._x) && (_y > p._y) && (_z > p._z));
514 }
515 
516 // -----------------------------------------------------------------------------
517 inline Point& Point::operator =(double x)
518 {
519   _x = x;
520   _y = x;
521   _z = x;
522   return *this;
523 }
524 
525 // -----------------------------------------------------------------------------
526 inline Point& Point::operator+=(double x)
527 {
528   _x += x;
529   _y += x;
530   _z += x;
531   return *this;
532 }
533 
534 // -----------------------------------------------------------------------------
535 inline Point& Point::operator-=(double x)
536 {
537   _x -= x;
538   _y -= x;
539   _z -= x;
540   return *this;
541 }
542 
543 // -----------------------------------------------------------------------------
544 inline Point& Point::operator/=(double x)
545 {
546   _x /= x;
547   _y /= x;
548   _z /= x;
549   return *this;
550 }
551 
552 // -----------------------------------------------------------------------------
553 inline Point& Point::operator*=(double x)
554 {
555   _x *= x;
556   _y *= x;
557   _z *= x;
558   return *this;
559 }
560 
561 // -----------------------------------------------------------------------------
562 inline Point Point::operator+ (double x) const
563 {
564   Point p;
565   p._x = _x + x;
566   p._y = _y + x;
567   p._z = _z + x;
568   return p;
569 }
570 
571 // -----------------------------------------------------------------------------
572 inline Point Point::operator- (double x) const
573 {
574   Point p;
575   p._x = _x - x;
576   p._y = _y - x;
577   p._z = _z - x;
578   return p;
579 }
580 
581 // -----------------------------------------------------------------------------
582 inline Point Point::operator* (double x) const
583 {
584   Point p;
585   p._x = _x * x;
586   p._y = _y * x;
587   p._z = _z * x;
588   return p;
589 }
590 
591 // -----------------------------------------------------------------------------
592 inline Point Point::operator/ (double x) const
593 {
594   Point p;
595   p._x = _x / x;
596   p._y = _y / x;
597   p._z = _z / x;
598   return p;
599 }
600 
601 // -----------------------------------------------------------------------------
602 inline Point& Point::operator =(const Vector3& v)
603 {
604   _x = v._x;
605   _y = v._y;
606   _z = v._z;
607   return *this;
608 }
609 
610 // -----------------------------------------------------------------------------
611 inline Point& Point::operator +=(const Vector3 &v)
612 {
613   _x += v._x;
614   _y += v._y;
615   _z += v._z;
616   return *this;
617 }
618 
619 // -----------------------------------------------------------------------------
620 inline Point& Point::operator -=(const Vector3 &v)
621 {
622   _x -= v._x;
623   _y -= v._y;
624   _z -= v._z;
625   return *this;
626 }
627 
628 // -----------------------------------------------------------------------------
629 inline Point& Point::operator *=(const Vector3 &v)
630 {
631   _x *= v._x;
632   _y *= v._y;
633   _z *= v._z;
634   return *this;
635 }
636 
637 // -----------------------------------------------------------------------------
638 inline Point& Point::operator /=(const Vector3 &v)
639 {
640   _x /= v._x;
641   _y /= v._y;
642   _z /= v._z;
643   return *this;
644 }
645 
646 // -----------------------------------------------------------------------------
647 inline Point Point::operator +(const Vector3 &v) const
648 {
649   return (Point(*this) += v);
650 }
651 
652 // -----------------------------------------------------------------------------
653 inline Point Point::operator -(const Vector3 &v) const
654 {
655   return (Point(*this) -= v);
656 }
657 
658 // -----------------------------------------------------------------------------
659 inline Point Point::operator *(const Vector3 &v) const
660 {
661   return (Point(*this) *= v);
662 }
663 
664 // -----------------------------------------------------------------------------
665 inline Point Point::operator /(const Vector3 &v) const
666 {
667   return (Point(*this) /= v);
668 }
669 
670 // -----------------------------------------------------------------------------
671 inline Point& Point::operator+=(const Vector& v)
672 {
673   if (v.Rows() != 3) {
674     cerr << "Point::operator+=(const Vector& v): Size mismatch" << endl;
675     exit(1);
676   }
677   _x += v(0);
678   _y += v(1);
679   _z += v(2);
680   return *this;
681 }
682 
683 // -----------------------------------------------------------------------------
684 inline Point& Point::operator-=(const Vector& v)
685 {
686   if (v.Rows() != 3) {
687     cerr << "Point::operator-=(const Vector& v): Size mismatch" << endl;
688     exit(1);
689   }
690   _x -= v(0);
691   _y -= v(1);
692   _z -= v(2);
693   return *this;
694 }
695 
696 // -----------------------------------------------------------------------------
697 inline Point& Point::operator*=(const Vector& v)
698 {
699   if (v.Rows() != 3) {
700     cerr << "Point::operator*=(const Vector& v): Size mismatch" << endl;
701     exit(1);
702   }
703   _x *= v(0);
704   _y *= v(1);
705   _z *= v(2);
706   return *this;
707 }
708 
709 // -----------------------------------------------------------------------------
710 inline Point& Point::operator/=(const Vector& v)
711 {
712   if (v.Rows() != 3) {
713     cerr << "Point::operator/=(const Vector& v): Size mismatch" << endl;
714     exit(1);
715   }
716   _x /= v(0);
717   _y /= v(1);
718   _z /= v(2);
719   return *this;
720 }
721 
722 // -----------------------------------------------------------------------------
723 inline Point Point::operator+ (const Vector& v) const
724 {
725   Point tmp;
726   if (v.Rows() != 3) {
727     cerr << "Point::operator+(const Vector& v): Size mismatch" << endl;
728     exit(1);
729   }
730   tmp._x = _x + v(0);
731   tmp._y = _y + v(1);
732   tmp._z = _z + v(2);
733   return tmp;
734 }
735 
736 // -----------------------------------------------------------------------------
737 inline Point Point::operator- (const Vector& v) const
738 {
739   Point tmp;
740   if (v.Rows() != 3) {
741     cerr << "Point::operator-(const Vector& v): Size mismatch" << endl;
742     exit(1);
743   }
744   tmp._x = _x - v(0);
745   tmp._y = _y - v(1);
746   tmp._z = _z - v(2);
747   return tmp;
748 }
749 
750 // -----------------------------------------------------------------------------
751 inline Point Point::operator* (const Vector& v) const
752 {
753   Point tmp;
754   if (v.Rows() != 3) {
755     cerr << "Point::operator*(const Vector& v): Size mismatch" << endl;
756     exit(1);
757   }
758   tmp._x = _x * v(0);
759   tmp._y = _y * v(1);
760   tmp._z = _z * v(2);
761   return tmp;
762 }
763 
764 // -----------------------------------------------------------------------------
765 inline Point Point::operator/ (const Vector& v) const
766 {
767   Point tmp;
768   if (v.Rows() != 3) {
769     cerr << "Point::operator/(const Vector& v): Size mismatch" << endl;
770     exit(1);
771   }
772   tmp._x = _x / v(0);
773   tmp._y = _y / v(1);
774   tmp._z = _z / v(2);
775   return tmp;
776 }
777 
778 // -----------------------------------------------------------------------------
779 inline Point Point::operator* (const Matrix& m) const
780 {
781   Point tmp;
782   if ((m.Rows() != 4) && (m.Cols() != 4)) {
783     cerr << "Point::operator*(const Matrix& m): Size mismatch" << endl;
784     exit(1);
785   }
786   tmp._x = _x * m(0, 0) + _y * m(0, 1) + _z * m(0, 2) + m(0, 3);
787   tmp._y = _x * m(1, 0) + _y * m(1, 1) + _z * m(1, 2) + m(1, 3);
788   tmp._z = _x * m(2, 0) + _y * m(2, 1) + _z * m(2, 2) + m(2, 3);
789   return tmp;
790 }
791 
792 // -----------------------------------------------------------------------------
793 inline Point& Point::operator*=(const Matrix& m)
794 {
795   Point tmp;
796   if ((m.Rows() != 4) && (m.Cols() != 4)) {
797     cerr << "Point::operator*(const Matrix& m): Size mismatch" << endl;
798     exit(1);
799   }
800   tmp._x = _x * m(0, 0) + _y * m(0, 1) + _z * m(0, 2) + m(0, 3);
801   tmp._y = _x * m(1, 0) + _y * m(1, 1) + _z * m(1, 2) + m(1, 3);
802   tmp._z = _x * m(2, 0) + _y * m(2, 1) + _z * m(2, 2) + m(2, 3);
803   *this  = tmp;
804   return *this;
805 }
806 
807 // -----------------------------------------------------------------------------
SquaredDistance()808 inline double Point::SquaredDistance() const
809 {
810   return _x*_x + _y*_y  + _z *_z;
811 }
812 
813 // -----------------------------------------------------------------------------
SquaredDistance(const Point & p)814 inline double Point::SquaredDistance(const Point &p) const
815 {
816   const double dx = _x - p._x;
817   const double dy = _y - p._y;
818   const double dz = _z - p._z;
819   return dx*dx + dy*dy + dz*dz;
820 }
821 
822 // -----------------------------------------------------------------------------
Distance()823 inline double Point::Distance() const
824 {
825   return sqrt(SquaredDistance());
826 }
827 
828 // -----------------------------------------------------------------------------
Distance(const Point & p)829 inline double Point::Distance(const Point &p) const
830 {
831   return sqrt(SquaredDistance(p));
832 }
833 
834 
835 } // namespace mirtk
836 
837 #endif // MIRTK_Point_H
838