$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
point.hh
1 // Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 EPITA
2 // Research and Development Laboratory (LRDE)
3 //
4 // This file is part of Olena.
5 //
6 // Olena is free software: you can redistribute it and/or modify it under
7 // the terms of the GNU General Public License as published by the Free
8 // Software Foundation, version 2 of the License.
9 //
10 // Olena 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 GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
17 //
18 // As a special exception, you may use this file as part of a free
19 // software project without restriction. Specifically, if other files
20 // instantiate templates or use macros or inline functions from this
21 // file, or you compile this file and link it with other files to produce
22 // an executable, this file does not by itself cause the resulting
23 // executable to be covered by the GNU General Public License. This
24 // exception does not however invalidate any other reasons why the
25 // executable file might be covered by the GNU General Public License.
26 
27 #ifndef MLN_CORE_POINT_HH
28 # define MLN_CORE_POINT_HH
29 
38 
39 # include <cmath>
40 # include <mln/core/def/coord.hh>
41 # include <mln/core/concept/proxy.hh>
42 # include <mln/core/concept/gpoint.hh>
43 # include <mln/core/internal/coord_impl.hh>
44 
45 # include <mln/metal/bool.hh>
46 # include <mln/metal/is_not.hh>
47 # include <mln/algebra/vec.hh>
48 # include <mln/metal/converts_to.hh>
49 # include <mln/algebra/h_vec.hh>
50 # include <mln/util/yes.hh>
51 
52 
53 namespace mln
54 {
55 
57  template <typename G, typename C> struct point;
58  template <typename G, typename C> struct dpoint;
59  namespace literal {
60  struct zero_t;
61  struct one_t;
62  struct origin_t;
63  }
65 
66 
67  namespace internal
68  {
69  // This is a hack so that g++-2.95 can compile the method
70  // "point<G,C>::operator vec() const".
71  template <typename G, typename C>
72  struct vec_of_point
73  {
75  };
76 
77  }
78 
83  template <typename G, typename C>
84  struct point : public Gpoint< point<G,C> >,
85  public internal::mutable_coord_impl_< G::dim, C, point<G,C> >
86  {
87  // FIXME: Temporary hack.
88  typedef point site;
89  typedef point psite;
90 
91 
95  enum { dim = G::dim };
96 
98  typedef G grid;
99 
102 
105 
107  typedef C coord;
108 
111 
114 
118  const C& operator[](unsigned i) const;
119 
123  C& operator[](unsigned i);
124 
125 
127  const C& last_coord() const;
128 
130  C& last_coord();
131 
132 
134  point();
135 
137  template <typename C2>
139 
141 
142 
145  explicit point(C ind);
146  point(C row, C col);
147  point(C sli, C row, C col);
149 
151  point(const literal::origin_t&);
153  // Works only in 1D:
154  point(const literal::zero_t&);
156  point(const literal::one_t&);
159 
161  template <typename F>
162  point(const Function_v2v<F>& f);
163 
165  void set_all(C c);
166 
168  static const point<G,C> origin;
169 
171  point<G,C>& operator+=(const delta& dp);
172 
174  point<G,C>& operator-=(const delta& dp);
175 
176  /* FIXME: Seems highly non-generic!
177  This (non documented change, even in ChangeLog) change was
178  introduce by revision 1224, see
179  https://trac.lrde.org/olena/changeset/1224#file2
180  https://www.lrde.epita.fr/pipermail/olena-patches/2007-October/001592.html
181  */
182  operator typename internal::vec_of_point<G,C>::ret () const; // Hack to help g++-2.95.
183 
185  vec to_vec() const;
186 
188  h_vec to_h_vec() const;
189 
191  static const point<G,C>& plus_infty();
192 
194  static const point<G,C>& minus_infty();
195 
198 
199  protected:
201  };
202 
203 
208  template <typename G, typename C1, typename C2>
209  void from_to_(const point<G,C1>& from, point<G,C2>& to);
210 
211 
212  namespace internal
213  {
214 
217 
218  template <typename P, typename E>
219  struct subject_point_impl;
220 
221  template <typename G, typename C, typename E>
222  struct subject_point_impl< point<G,C>, E >
223  {
224  typename point<G,C>::vec to_vec() const;
225  operator typename point<G,C>::vec () const; // Hack to help g++-2.95.
226 
227  private:
228  const E& exact_() const;
229  };
230 
232 
233  } // end of namespace mln::internal
234 
235 
238  template <typename G, typename C>
239  const mln::algebra::vec<point<G,C>::dim - 1, C>& cut_(const point<G,C>& p);
240 
241  template <typename C>
242  const util::yes& cut_(const point<grid::tick,C>& p);
244 
245 
246 # ifndef MLN_INCLUDE_ONLY
247 
248 
249  template <typename G, typename C>
250  inline
251  const C& point<G,C>::operator[](unsigned i) const
252  {
253  assert(i < dim);
254  return this->coord_[i];
255  }
256 
257  template <typename G, typename C>
258  inline
259  C& point<G,C>::operator[](unsigned i)
260  {
261  assert(i < dim);
262  return this->coord_[i];
263  }
264 
265  template <typename G, typename C>
266  inline
267  const C&
268  point<G,C>::last_coord() const
269  {
270  return this->coord_[dim - 1];
271  }
272 
273  template <typename G, typename C>
274  inline
275  C&
277  {
278  return this->coord_[dim - 1];
279  }
280 
281 
282  // Constructors.
283 
284  template <typename G, typename C>
285  inline
287  {
288  }
289 
290  template <typename G, typename C>
291  template <typename C2>
292  inline
294  {
295  from_to_(v, *this);
296  }
297 
298 
299  template <typename G, typename C>
300  inline
302  {
303  from_to_(v, *this);
304  }
305 
306 
307  template <typename G, typename C>
308  inline
309  point<G,C>::point(C ind)
310  {
311  metal::bool_<(dim == 1)>::check();
312  coord_[0] = ind;
313  }
314 
315  template <typename G, typename C>
316  inline
317  point<G,C>::point(C row, C col)
318  {
319  metal::bool_<(dim == 2)>::check();
320  coord_[0] = row;
321  coord_[1] = col;
322  }
323 
324  template <typename G, typename C>
325  inline
326  point<G,C>::point(C sli, C row, C col)
327  {
328  metal::bool_<(dim == 3)>::check();
329  coord_[0] = sli;
330  coord_[1] = row;
331  coord_[2] = col;
332  }
333 
334  template <typename G, typename C>
335  template <typename F>
336  inline
337  point<G,C>::point(const Function_v2v<F>& f_)
338  {
339  mlc_converts_to(mln_result(F), C)::check();
340  const F& f = exact(f_);
341  for (unsigned i = 0; i < dim; ++i)
342  coord_[i] = static_cast<C>( f(i) );
343  }
344 
345  template <typename G, typename C>
346  inline
347  point<G,C>::point(const literal::origin_t&)
348  {
349  coord_.set_all(0);
350  }
351 
352  template <typename G, typename C>
353  inline
354  point<G,C>&
355  point<G,C>::operator=(const literal::origin_t&)
356  {
357  coord_.set_all(0);
358  return *this;
359  }
360 
361  template <typename G, typename C>
362  inline
363  point<G,C>::point(const literal::zero_t&)
364  {
365  metal::bool_<(dim == 1)>::check();
366  coord_[0] = 1;
367  }
368 
369  template <typename G, typename C>
370  inline
371  point<G,C>&
372  point<G,C>::operator=(const literal::zero_t&)
373  {
374  metal::bool_<(dim == 1)>::check();
375  coord_[0] = 1;
376  return *this;
377  }
378 
379  template <typename G, typename C>
380  inline
381  point<G,C>::point(const literal::one_t&)
382  {
383  metal::bool_<(dim == 1)>::check();
384  coord_[0] = 1;
385  }
386 
387  template <typename G, typename C>
388  inline
389  point<G,C>&
390  point<G,C>::operator=(const literal::one_t&)
391  {
392  metal::bool_<(dim == 1)>::check();
393  coord_[0] = 1;
394  return *this;
395  }
396 
397  template <typename G, typename C>
398  inline
399  void point<G,C>::set_all(C c)
400  {
401  coord_.set_all(c);
402  }
403 
404  template <typename G, typename C>
405  const point<G,C> point<G,C>::origin = all_to(0);
406 
407  template <typename G, typename C>
408  inline
409  point<G,C>&
410  point<G,C>::operator+=(const delta& dp)
411  {
412  for (unsigned i = 0; i < dim; ++i)
413  coord_[i] = static_cast<C>(coord_[i] + dp[i]);
414  return *this;
415  }
416 
417  template <typename G, typename C>
418  inline
419  point<G,C>&
420  point<G,C>::operator-=(const delta& dp)
421  {
422  for (unsigned i = 0; i < dim; ++i)
423  coord_[i] -= dp[i];
424  return *this;
425  }
426 
427  template <typename G, typename C>
428  inline
429  point<G,C>::operator typename internal::vec_of_point<G,C>::ret () const // Hack to help g++-2.95.
430  {
431  return to_vec();
432  }
433 
434  template <typename G, typename C>
435  inline
436  typename point<G,C>::vec
437  point<G,C>::to_vec() const
438  {
439  //FIXME: to be improved.
440  if (dim > 2)
441  {
443  unsigned j = 0;
444  for (unsigned i = dim - 2; i < dim; ++i)
445  tmp[j++] = mln::internal::convert_data<float>(coord_[i]);
446  for (unsigned i = 2; i < dim; ++i, ++j)
447  tmp[j] = mln::internal::convert_data<float>(coord_[i-j]);
448 
449  return tmp;
450  }
451 
452  return coord_;
453  }
454 
455  template <typename G, typename C>
456  inline
457  typename point<G,C>::h_vec
458  point<G,C>::to_h_vec() const
459  {
461 
462  //FIXME: to be improved.
463  if (dim == 1)
464  tmp[0] = coord_[0];
465  else
466  {
467  unsigned j = 0;
468  for (unsigned i = dim - 2; i < dim; ++i)
469  tmp[j++] = coord_[i];
470 
471  for (unsigned i = 2; i < dim; ++i, ++j)
472  tmp[j] = coord_[i-j];
473 
474  tmp[G::dim] = 1;
475  }
476 
477  return tmp;
478  }
479 
480 
481  template <typename G, typename C>
482  inline
483  const point<G,C>&
485  {
486  static const point<G,C> the_(all_to(mln_max(C)));
487  return the_;
488  }
489 
490  template <typename G, typename C>
491  inline
492  const point<G,C>&
494  {
495  static const point<G,C> the_(all_to(mln_min(C)));
496  return the_;
497  }
498 
499  template <typename G, typename C>
500  inline
503  {
504  return coord_;
505  }
506 
507 
508  // Conversions
509 
510  template <typename G, typename C1, typename C2>
511  inline
512  void
513  from_to_(const point<G,C1>& from, point<G,C2>& to)
514  {
515  mlc_converts_to(C1,C2)::check();
516  enum { dim = G::dim };
517 
518  for (unsigned i = 0; i < dim; ++i)
519  to[i] = mln::internal::convert_data<C2>(from[i]);
520  }
521 
522 
523  namespace internal
524  {
525 
526  template <typename G, typename C, typename E>
527  inline
528  const E&
529  subject_point_impl< point<G,C>, E >::exact_() const
530  {
531  return internal::force_exact<const E>(*this);
532  }
533 
534  template <typename G, typename C, typename E>
535  inline
536  typename point<G,C>::vec
537  subject_point_impl< point<G,C>, E >::to_vec() const
538  {
539  return exact_().get_subject().to_vec();
540  }
541 
542  template <typename G, typename C, typename E>
543  inline
544  subject_point_impl< point<G,C>, E >::operator typename point<G,C>::vec () const // Hack to help g++-2.95.
545  {
546  return exact_().get_subject();
547  }
548 
549  } // end of namespace mln::internal
550 
551  template <typename G, typename C>
552  inline
553  const mln::algebra::vec<point<G,C>::dim - 1, C>&
554  cut_(const point<G,C>& p)
555  {
556  return *(mln::algebra::vec<point<G,C>::dim - 1, C>*)(& p.to_vec());
557  }
558 
559  template <typename C>
560  inline
561  const util::yes&
562  cut_(const point<grid::tick,C>& p)
563  {
564  (void) p;
565  util::yes* the_;
566  return *the_;
567  }
568 
569 # endif // ! MLN_INCLUDE_ONLY
570 
571 
572 } // end of namespace mln
573 
574 
575 #endif // ! MLN_CORE_POINT_HH