PointSet.h
1 /*
2  * Medical Image Registration ToolKit (MIRTK)
3  *
4  * Copyright 2008-2015 Imperial College London
5  * Copyright 2008-2015 Daniel Rueckert, Julia Schnabel
6  * Copyright 2013-2015 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_PointSet_H
22 #define MIRTK_PointSet_H
23 
24 #include "mirtk/Object.h"
25 
26 #include "mirtk/Memory.h"
27 #include "mirtk/Cfstream.h"
28 #include "mirtk/Point.h"
29 #include "mirtk/Array.h"
30 #include "mirtk/OrderedSet.h"
31 
32 #include "mirtk/NumericsExport.h"
33 
34 
35 // Forward declaration of VTK type
36 class vtkAbstractArray;
37 
38 
39 namespace mirtk {
40 
41 
42 /**
43  * Point set
44  */
45 class PointSet : public Object
46 {
47  mirtkObjectMacro(PointSet);
48 
49  // ---------------------------------------------------------------------------
50  // Attributes
51 
52 protected:
53 
54  /// Allocated size of PointSet
55  int _m;
56 
57  /// Actual size of PointSet
58  int _n;
59 
60  /// Pointer to Points
62 
63  MIRTK_Numerics_EXPORT static int POINTSET_SIZE;
64 
65 public:
66 
67  // ---------------------------------------------------------------------------
68  // Constructors and destructor
69 
70  /// Default constructor
71  PointSet(int = 0);
72 
73  /// Copy constructor
74  PointSet(const PointSet &);
75 
76  /// Copy subset constructor
77  PointSet(const PointSet &, const Array<int> &);
78 
79  /// Copy subset constructor
80  PointSet(const PointSet &, const OrderedSet<int> &);
81 
82  /// Destructor
83  virtual ~PointSet();
84 
85  // ---------------------------------------------------------------------------
86  // Size get acccessor and clearing of PointSet
87 
88  /// Resizes container so it contains n elements
89  void Resize(int, const Point & = Point());
90 
91  /// Request a change in capacity
92  void Reserve(int);
93 
94  /// Return size of allocated storage capacity
95  int Capacity() const;
96 
97  /// Set container size (and capacity)
98  ///
99  /// The result of this function is equivalent to
100  /// \code
101  /// Resize(n);
102  /// ShrinkToFit();
103  /// \endcode
104  /// but with only one reallocation operation. It sets both the size and
105  /// the capacity of the point set container.
106  void Size(int);
107 
108  /// Access function for size
109  int Size() const;
110 
111  /// Requests the container to reduce its capacity to fit its size
112  void ShrinkToFit();
113 
114  /// Clearing of PointSet
115  ///
116  /// \param[in] deallocate Whether to deallocate memory.
117  void Clear(bool deallocate = true);
118 
119  // ---------------------------------------------------------------------------
120  // Operators for access
121 
122  /// Get n-th point
123  Point &GetPoint(int);
124 
125  /// Get n-th point
126  const Point &GetPoint(int) const;
127 
128  /// Get n-th point
129  void GetPoint(int, Point &) const;
130 
131  /// Get n-th point
132  void GetPoint(int, double [3]) const;
133 
134  /// Set n-th point
135  void SetPoint(int, const Point &);
136 
137  /// Set n-th point
138  void SetPoint(int, const double [3]);
139 
140  /// Operator for Point put access
141  Point &operator()(int);
142 
143  /// Operator for Point get access
144  const Point &operator()(int) const;
145 
146  /// Operator
147  PointSet operator()(int, int) const;
148 
149  // ---------------------------------------------------------------------------
150  // Operators for PointSet arithmetic
151 
152  // PointSet operation for =
153  PointSet &operator=(const PointSet &);
154 
155  // PointSet operator for Point adding
156  PointSet& operator+=(const Point &);
157 
158  // PointSet operator for Point substraction
159  PointSet& operator-=(const Point &);
160 
161  // PointSet operator for PointSet adding
162  PointSet& operator+=(const PointSet &);
163 
164  // PointSet operator for PointSet substraction
165  PointSet& operator-=(const PointSet &);
166 
167  /// Centre of gravity
168  virtual Point CenterOfGravity() const;
169 
170  /// Closest point to given point
171  virtual Point ClosestPoint(Point&);
172 
173  /// Point set distance to given point
174  virtual double PointDistance(Point&);
175 
176  /// Bounding box
177  virtual void BoundingBox(Point &, Point &) const;
178 
179  // ---------------------------------------------------------------------------
180  // Operators for PointSet comparison
181 
182  /// Test for equality
183  bool operator ==(const PointSet &) const;
184 
185  /// Test for inequality
186  bool operator !=(const PointSet &) const;
187 
188  // ---------------------------------------------------------------------------
189  // Explicit methods to add or delete points
190 
191  /// Adding of a point to point set
192  void Add(const Point &);
193 
194  /// Deleting of a point from point set
195  void Del(const Point &);
196 
197  /// Adding of a PointSet to Pointset
198  void Add(const PointSet &);
199 
200  /// Deleting of a PointSet from Pointset
201  void Del(const PointSet &);
202 
203  /// Adding of a Point to Pointset
204  void Add(double *);
205 
206  /// Deleting of a Point from Pointset
207  void Del(double *);
208 
209  /// Delete all points without freeing already allocated memory
210  void Del();
211 
212  // ---------------------------------------------------------------------------
213  // I/O
214 
215  /// Read pointset from file
216  void Read(const char *);
217 
218  /// Write pointset to file
219  void Write(const char *) const;
220 
221  /// Read point set from file in VTK format
222  ///
223  /// \note Use this function only when MIRTK_Numerics_WITH_VTK is 1.
224  void ReadVTK(const char *);
225 
226  /// Add point set from file in VTK format
227  ///
228  /// \note Use this function only when MIRTK_Numerics_WITH_VTK is 1.
229  void AddVTK(const char *);
230 
231  /// Write point set to file in VTK format
232  ///
233  /// \note Use this function only when MIRTK_Numerics_WITH_VTK is 1.
234  void WriteVTK(const char *, vtkAbstractArray * = NULL) const;
235 
236  // ---------------------------------------------------------------------------
237  // Misc. functions
238 
239  /// Computes the standard deviation ellipsoid about the centroid of a point set.
241 
242  /// Tests if a point is inside the polygon defined by the point set
243  int IsInside(double, double) const;
244 
245  /// Get (unweighted) centroid of point set
246  Point Centroid() const;
247 };
248 
249 ////////////////////////////////////////////////////////////////////////////////
250 // Streaming operators
251 ////////////////////////////////////////////////////////////////////////////////
252 
253 /// Write point set to binary output file stream
254 Cofstream &operator <<(Cofstream &, const PointSet &);
255 
256 /// Read point set from binary input file stream
257 Cifstream &operator >>(Cifstream &, PointSet &);
258 
259 /// Write point set to text output stream
260 ostream &operator <<(ostream &, const PointSet &);
261 
262 /// Read point set from text input stream
263 istream &operator >>(istream &, PointSet &);
264 
265 ////////////////////////////////////////////////////////////////////////////////
266 // Inline definitions
267 ////////////////////////////////////////////////////////////////////////////////
268 
269 // -----------------------------------------------------------------------------
270 inline PointSet::PointSet(int n)
271 :
272  _m(n), _n(n), _data(Allocate<Point>(n))
273 {
274 }
275 
276 // -----------------------------------------------------------------------------
277 inline PointSet::PointSet(const PointSet &pset)
278 :
279  Object(pset),
280  _m(0), _n(0), _data(NULL)
281 {
282  (*this) = pset;
283 }
284 
285 // -----------------------------------------------------------------------------
286 inline PointSet::PointSet(const PointSet &pset, const Array<int> &subset)
287 :
288  Object(pset),
289  _m(0), _n(0), _data(NULL)
290 {
291  int i = 0;
292  Size(static_cast<int>(subset.size()));
293  for (Array<int>::const_iterator it = subset.begin(); it != subset.end(); ++it, ++i) {
294  _data[i] = pset(*it);
295  }
296 }
297 
298 // -----------------------------------------------------------------------------
299 inline PointSet::PointSet(const PointSet &pset, const OrderedSet<int> &subset)
300 :
301  Object(pset),
302  _m(0), _n(0), _data(NULL)
303 {
304  int i = 0;
305  Size(static_cast<int>(subset.size()));
306  for (OrderedSet<int>::const_iterator it = subset.begin(); it != subset.end(); ++it, ++i) {
307  _data[i] = pset(*it);
308  }
309 }
310 
311 // -----------------------------------------------------------------------------
313 {
314  Clear();
315 }
316 
317 // -----------------------------------------------------------------------------
319 {
320  return _data[j];
321 }
322 
323 // -----------------------------------------------------------------------------
324 inline const Point &PointSet::operator()(int j) const
325 {
326  return _data[j];
327 }
328 
329 // -----------------------------------------------------------------------------
330 inline Point &PointSet::GetPoint(int i)
331 {
332  return this->operator()(i);
333 }
334 
335 // -----------------------------------------------------------------------------
336 inline const Point &PointSet::GetPoint(int i) const
337 {
338  return this->operator()(i);
339 }
340 
341 // -----------------------------------------------------------------------------
342 inline void PointSet::GetPoint(int i, Point &p) const
343 {
344  p = this->operator()(i);
345 }
346 
347 // -----------------------------------------------------------------------------
348 inline void PointSet::GetPoint(int i, double p[3]) const
349 {
350  const Point &pt = this->operator()(i);
351  p[0] = pt._x, p[1] = pt._y, p[2] = pt._z;
352 }
353 
354 // -----------------------------------------------------------------------------
355 inline void PointSet::SetPoint(int i, const Point &p)
356 {
357  this->operator()(i) = p;
358 }
359 
360 // -----------------------------------------------------------------------------
361 inline void PointSet::SetPoint(int i, const double p[3])
362 {
363  Point &pt = this->operator()(i);
364  pt._x = p[0], pt._y = p[1], pt._z = p[2];
365 }
366 
367 // -----------------------------------------------------------------------------
368 inline PointSet& PointSet::operator+=(const Point &p)
369 {
370  this->Add(p);
371  return *this;
372 }
373 
374 // -----------------------------------------------------------------------------
375 inline PointSet& PointSet::operator-=(const Point &p)
376 {
377  this->Del(p);
378  return *this;
379 }
380 
381 // -----------------------------------------------------------------------------
382 inline PointSet& PointSet::operator+=(const PointSet &pset)
383 {
384  this->Add(pset);
385  return *this;
386 }
387 
388 // -----------------------------------------------------------------------------
389 inline PointSet& PointSet::operator-=(const PointSet &pset)
390 {
391  this->Del(pset);
392  return *this;
393 }
394 
395 // -----------------------------------------------------------------------------
396 inline PointSet PointSet::operator()(int j, int k) const
397 {
398  PointSet pset;
399  for (int i = j; i < k; j++) {
400  pset += _data[i];
401  }
402  return pset;
403 }
404 
405 // -----------------------------------------------------------------------------
406 inline void PointSet::Resize(int n, const Point &p)
407 {
408  int m = _m;
409  while (n > m) m += POINTSET_SIZE;
410  this->Reserve(m);
411  _n = n;
412  for (int i = _n; i < _m; ++i) _data[i] = p;
413 }
414 
415 // -----------------------------------------------------------------------------
416 inline void PointSet::Reserve(int m)
417 {
418  if (_m < m) {
419  _m = m;
420  Point *new_data = Allocate<Point>(m);
421  for (int i = 0; i < _n; ++i) new_data[i] = _data[i];
422  Deallocate(_data);
423  _data = new_data;
424  }
425 }
426 
427 // -----------------------------------------------------------------------------
428 inline int PointSet::Capacity() const
429 {
430  return _m;
431 }
432 
433 // -----------------------------------------------------------------------------
434 inline void PointSet::Size(int n)
435 {
436  if (_m != n) {
437  Point *new_data = Allocate<Point>(n);
438  for (int i = 0; i < _n; ++i) new_data[i] = _data[i];
439  Deallocate(_data);
440  _data = new_data;
441  _m = _n = n;
442  }
443 }
444 
445 // -----------------------------------------------------------------------------
446 inline int PointSet::Size() const
447 {
448  return _n;
449 }
450 
451 // -----------------------------------------------------------------------------
453 {
454  if (_n < _m) {
455  Point *new_data = Allocate<Point>(_n);
456  for (int i = 0; i < _n; ++i) new_data[i] = _data[i];
457  Deallocate(_data);
458  _data = new_data;
459  _m = _n;
460  }
461 }
462 
463 // -----------------------------------------------------------------------------
464 inline void PointSet::Add(double *p)
465 {
466  this->Add(Point(p[0], p[1], p[2]));
467 }
468 
469 // -----------------------------------------------------------------------------
470 inline void PointSet::Del(double *p)
471 {
472  this->Del(Point(p[0], p[1], p[2]));
473 }
474 
475 // -----------------------------------------------------------------------------
476 inline void PointSet::Del()
477 {
478  this->Clear(false);
479 }
480 
481 
482 } // namespace mirtk
483 
484 #endif // MIRTK_PointSet_H
485 
bool operator==(const PointSet &) const
Test for equality.
Point & operator()(int)
Operator for Point put access.
Definition: PointSet.h:318
void ReadVTK(const char *)
int Size() const
Access function for size.
Definition: PointSet.h:446
void WriteVTK(const char *, vtkAbstractArray *=NULL) const
void Write(const char *) const
Write pointset to file.
double _x
x coordinate of Point
Definition: Point.h:46
void Del()
Delete all points without freeing already allocated memory.
Definition: PointSet.h:476
int _n
Actual size of PointSet.
Definition: PointSet.h:58
int _m
Allocated size of PointSet.
Definition: PointSet.h:55
void Allocate(Type *&matrix, int n)
Allocate 1D array.
Definition: Allocate.h:62
bool operator!=(const PointSet &) const
Test for inequality.
virtual ~PointSet()
Destructor.
Definition: PointSet.h:312
void ShrinkToFit()
Requests the container to reduce its capacity to fit its size.
Definition: PointSet.h:452
int Capacity() const
Return size of allocated storage capacity.
Definition: PointSet.h:428
virtual void BoundingBox(Point &, Point &) const
Bounding box.
void Add(const Point &)
Adding of a point to point set.
virtual double PointDistance(Point &)
Point set distance to given point.
Definition: IOConfig.h:41
virtual Point ClosestPoint(Point &)
Closest point to given point.
virtual Point CenterOfGravity() const
Centre of gravity.
void Resize(int, const Point &=Point())
Resizes container so it contains n elements.
Definition: PointSet.h:406
Point & GetPoint(int)
Get n-th point.
Definition: PointSet.h:330
Point StandardDeviationEllipsoid() const
Computes the standard deviation ellipsoid about the centroid of a point set.
void Deallocate(Type *&p)
Deallocate 1D array.
Definition: Deallocate.h:36
void AddVTK(const char *)
int IsInside(double, double) const
Tests if a point is inside the polygon defined by the point set.
PointSet(int=0)
Default constructor.
Definition: PointSet.h:270
void Read(const char *)
Read pointset from file.
void SetPoint(int, const Point &)
Set n-th point.
Definition: PointSet.h:355
void Clear(bool deallocate=true)
double _z
z coordinate of Point
Definition: Point.h:48
Point * _data
Pointer to Points.
Definition: PointSet.h:61
double _y
y coordinate of Point
Definition: Point.h:47
Point Centroid() const
Get (unweighted) centroid of point set.
void Reserve(int)
Request a change in capacity.
Definition: PointSet.h:416