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