00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef MLN_CORE_POINT_HH
00028 # define MLN_CORE_POINT_HH
00029
00038
00039 # include <cmath>
00040 # include <mln/core/def/coord.hh>
00041 # include <mln/core/concept/proxy.hh>
00042 # include <mln/core/concept/gpoint.hh>
00043 # include <mln/core/internal/coord_impl.hh>
00044 # include <mln/fun/i2v/all_to.hh>
00045
00046 # include <mln/metal/bool.hh>
00047 # include <mln/metal/is_not.hh>
00048 # include <mln/algebra/vec.hh>
00049 # include <mln/metal/converts_to.hh>
00050 # include <mln/algebra/h_vec.hh>
00051 # include <mln/util/yes.hh>
00052
00053
00054 namespace mln
00055 {
00056
00058 template <typename G, typename C> struct point;
00059 template <typename G, typename C> struct dpoint;
00060 namespace literal {
00061 struct zero_t;
00062 struct one_t;
00063 struct origin_t;
00064 }
00066
00067
00068 namespace convert
00069 {
00070
00071 namespace over_load
00072 {
00073
00074 template <typename G, typename C1, typename C2>
00075 void from_to_(const point<G,C1>& from, point<G,C2>& to);
00076
00077 template <unsigned n, typename C1, typename G, typename C2>
00078 void
00079 from_to_(const mln::algebra::vec<n,C1>& from, point<G,C2>& to);
00080
00081 template <unsigned n, typename C1, typename G>
00082 void
00083 from_to_(const mln::algebra::vec<n,C1>& from, point<G,C1>& to);
00084
00085 }
00086
00087 }
00088
00089
00090
00091 namespace internal
00092 {
00093
00094
00095 template <typename G, typename C>
00096 struct vec_of_point
00097 {
00098 typedef mln::algebra::vec<G::dim, float> ret;
00099 };
00100
00101 }
00102
00107 template <typename G, typename C>
00108 struct point : public Gpoint< point<G,C> >,
00109 public internal::mutable_coord_impl_< G::dim, C, point<G,C> >
00110 {
00111
00112 typedef point site;
00113 typedef point psite;
00114
00115
00119 enum { dim = G::dim };
00120
00122 typedef G grid;
00123
00125 typedef dpoint<G,C> delta;
00126
00128 typedef dpoint<G,C> dpsite;
00129
00131 typedef C coord;
00132
00134 typedef mln::algebra::vec<G::dim, float> vec;
00135
00137 typedef mln::algebra::h_vec<G::dim, float> h_vec;
00138
00142 const C& operator[](unsigned i) const;
00143
00147 C& operator[](unsigned i);
00148
00149
00151 const C& last_coord() const;
00152
00154 C& last_coord();
00155
00156
00158 point();
00159
00161 template <typename C2>
00162 point(const mln::algebra::vec<dim,C2>& v);
00163
00164 point(const mln::algebra::vec<dim,C>& v);
00165
00166
00169 explicit point(C ind);
00170 point(C row, C col);
00171 point(C sli, C row, C col);
00173
00175 point(const literal::origin_t&);
00176 point<G,C>& operator=(const literal::origin_t&);
00177
00178 point(const literal::zero_t&);
00179 point<G,C>& operator=(const literal::zero_t&);
00180 point(const literal::one_t&);
00181 point<G,C>& operator=(const literal::one_t&);
00183
00185 template <typename F>
00186 point(const Function_v2v<F>& f);
00187
00189 void set_all(C c);
00190
00192 static const point<G,C> origin;
00193
00195 point<G,C>& operator+=(const delta& dp);
00196
00198 point<G,C>& operator-=(const delta& dp);
00199
00200
00201
00202
00203
00204
00205
00206 operator typename internal::vec_of_point<G,C>::ret () const;
00207
00209 vec to_vec() const;
00210
00212 h_vec to_h_vec() const;
00213
00215 static const point<G,C>& plus_infty();
00216
00218 static const point<G,C>& minus_infty();
00219
00221 mln::algebra::vec<G::dim, C>& hook_coord_();
00222
00223 protected:
00224 mln::algebra::vec<G::dim, C> coord_;
00225 };
00226
00227 namespace internal
00228 {
00229
00232
00233 template <typename P, typename E>
00234 struct subject_point_impl;
00235
00236 template <typename G, typename C, typename E>
00237 struct subject_point_impl< point<G,C>, E >
00238 {
00239 typename point<G,C>::vec to_vec() const;
00240 operator typename point<G,C>::vec () const;
00241
00242 private:
00243 const E& exact_() const;
00244 };
00245
00247
00248 }
00249
00250
00252 template <typename G, typename C>
00253 const mln::algebra::vec<point<G,C>::dim - 1, C>& cut_(const point<G,C>& p);
00254
00255 template <typename C>
00256 const util::yes& cut_(const point<grid::tick,C>& p);
00257
00258
00259
00260 # ifndef MLN_INCLUDE_ONLY
00261
00262
00263 namespace internal
00264 {
00265
00266 template <typename C, typename C2>
00267 inline
00268 C
00269 convert_data_(metal::bool_<false>, const C2& v)
00270 {
00271 return static_cast<C>(v);
00272 }
00273
00274 template <typename C, typename C2>
00275 inline
00276 C
00277 convert_data_(metal::bool_<true>, const C2& v)
00278 {
00279 return static_cast<C>(round(v));
00280 }
00281
00282 template <typename C, typename C2>
00283 inline
00284 C
00285 convert_data(const C2& v)
00286 {
00287
00288
00289
00290
00291 return convert_data_<C>(
00292 typename mlc_and(
00293 mlc_and(mlc_is_not(C,float),
00294 mlc_is_not(C,double)),
00295 mlc_or(mlc_is(C2,float),
00296 mlc_is(C2, double)))::eval(), v);
00297 }
00298
00299
00300
00301 }
00302
00303
00304
00305 namespace convert
00306 {
00307
00308 namespace over_load
00309 {
00310
00311 template <typename G, typename C1, typename C2>
00312 inline
00313 void
00314 from_to_(const point<G,C1>& from, point<G,C2>& to)
00315 {
00316 mlc_converts_to(C1,C2)::check();
00317 enum { dim = G::dim };
00318
00319 for (unsigned i = 0; i < dim; ++i)
00320 to[i] = mln::internal::convert_data<C2>(from[i]);
00321 }
00322
00323
00324 template <unsigned n, typename C1, typename G, typename C2>
00325 inline
00326 void
00327 from_to_(const mln::algebra::vec<n,C1>& from, point<G,C2>& to)
00328 {
00329 mlc_converts_to(C1, C2)::check();
00330 enum { dim = G::dim };
00331 mlc_bool(G::dim == n)::check();
00332
00333 unsigned j = 0;
00334 for (unsigned i = dim - 2; i < dim; ++i)
00335 to[i] = mln::internal::convert_data<C2>(from[j++]);
00336 for (unsigned i = 2; i < dim; ++i, ++j)
00337 to[i-j] = mln::internal::convert_data<C2>(from[j]);
00338 }
00339
00340 template <typename C1, typename G, typename C2>
00341 inline
00342 void
00343 from_to_(const mln::algebra::vec<1,C1>& from, point<G,C2>& to)
00344 {
00345 mlc_converts_to(C1, C2)::check();
00346 enum { dim = G::dim };
00347 mlc_bool(G::dim == 1)::check();
00348
00349 to[0] = mln::internal::convert_data<C2>(from[0]);
00350 }
00351
00352 template <unsigned n, typename C1, typename G>
00353 inline
00354 void
00355 from_to_(const mln::algebra::vec<n,C1>& from, point<G,C1>& to)
00356 {
00357 enum { dim = G::dim };
00358 mlc_bool(G::dim == n)::check();
00359
00360 unsigned j = 0;
00361 for (unsigned i = dim - 2; i < dim; ++i)
00362 to[i] = from[j++];
00363 for (unsigned i = 2; i < dim; ++i, ++j)
00364 to[i-j] = from[j];
00365 }
00366
00367 template <typename C1, typename G>
00368 inline
00369 void
00370 from_to_(const mln::algebra::vec<1,C1>& from, point<G,C1>& to)
00371 {
00372 enum { dim = G::dim };
00373 mlc_bool(G::dim == 1)::check();
00374
00375 to[0] = from[0];
00376 }
00377
00378 }
00379
00380 }
00381
00382
00383 template <typename G, typename C>
00384 inline
00385 const C& point<G,C>::operator[](unsigned i) const
00386 {
00387 assert(i < dim);
00388 return this->coord_[i];
00389 }
00390
00391 template <typename G, typename C>
00392 inline
00393 C& point<G,C>::operator[](unsigned i)
00394 {
00395 assert(i < dim);
00396 return this->coord_[i];
00397 }
00398
00399 template <typename G, typename C>
00400 inline
00401 const C&
00402 point<G,C>::last_coord() const
00403 {
00404 return this->coord_[dim - 1];
00405 }
00406
00407 template <typename G, typename C>
00408 inline
00409 C&
00410 point<G,C>::last_coord()
00411 {
00412 return this->coord_[dim - 1];
00413 }
00414
00415
00416
00417
00418 template <typename G, typename C>
00419 inline
00420 point<G,C>::point()
00421 {
00422 }
00423
00424 template <typename G, typename C>
00425 template <typename C2>
00426 inline
00427 point<G,C>::point(const mln::algebra::vec<dim,C2>& v)
00428 {
00429 convert::over_load::from_to_(v, *this);
00430 }
00431
00432
00433 template <typename G, typename C>
00434 inline
00435 point<G,C>::point(const mln::algebra::vec<dim,C>& v)
00436 {
00437 convert::over_load::from_to_(v, *this);
00438 }
00439
00440
00441 template <typename G, typename C>
00442 inline
00443 point<G,C>::point(C ind)
00444 {
00445 metal::bool_<(dim == 1)>::check();
00446 coord_[0] = ind;
00447 }
00448
00449 template <typename G, typename C>
00450 inline
00451 point<G,C>::point(C row, C col)
00452 {
00453 metal::bool_<(dim == 2)>::check();
00454 coord_[0] = row;
00455 coord_[1] = col;
00456 }
00457
00458 template <typename G, typename C>
00459 inline
00460 point<G,C>::point(C sli, C row, C col)
00461 {
00462 metal::bool_<(dim == 3)>::check();
00463 coord_[0] = sli;
00464 coord_[1] = row;
00465 coord_[2] = col;
00466 }
00467
00468 template <typename G, typename C>
00469 template <typename F>
00470 inline
00471 point<G,C>::point(const Function_v2v<F>& f_)
00472 {
00473 mlc_converts_to(mln_result(F), C)::check();
00474 const F& f = exact(f_);
00475 for (unsigned i = 0; i < dim; ++i)
00476 coord_[i] = static_cast<C>( f(i) );
00477 }
00478
00479 template <typename G, typename C>
00480 inline
00481 point<G,C>::point(const literal::origin_t&)
00482 {
00483 coord_.set_all(0);
00484 }
00485
00486 template <typename G, typename C>
00487 inline
00488 point<G,C>&
00489 point<G,C>::operator=(const literal::origin_t&)
00490 {
00491 coord_.set_all(0);
00492 return *this;
00493 }
00494
00495 template <typename G, typename C>
00496 inline
00497 point<G,C>::point(const literal::zero_t&)
00498 {
00499 metal::bool_<(dim == 1)>::check();
00500 coord_[0] = 1;
00501 }
00502
00503 template <typename G, typename C>
00504 inline
00505 point<G,C>&
00506 point<G,C>::operator=(const literal::zero_t&)
00507 {
00508 metal::bool_<(dim == 1)>::check();
00509 coord_[0] = 1;
00510 return *this;
00511 }
00512
00513 template <typename G, typename C>
00514 inline
00515 point<G,C>::point(const literal::one_t&)
00516 {
00517 metal::bool_<(dim == 1)>::check();
00518 coord_[0] = 1;
00519 }
00520
00521 template <typename G, typename C>
00522 inline
00523 point<G,C>&
00524 point<G,C>::operator=(const literal::one_t&)
00525 {
00526 metal::bool_<(dim == 1)>::check();
00527 coord_[0] = 1;
00528 return *this;
00529 }
00530
00531 template <typename G, typename C>
00532 inline
00533 void point<G,C>::set_all(C c)
00534 {
00535 coord_.set_all(c);
00536 }
00537
00538 template <typename G, typename C>
00539 const point<G,C> point<G,C>::origin = all_to(0);
00540
00541 template <typename G, typename C>
00542 inline
00543 point<G,C>&
00544 point<G,C>::operator+=(const delta& dp)
00545 {
00546 for (unsigned i = 0; i < dim; ++i)
00547 coord_[i] = static_cast<C>(coord_[i] + dp[i]);
00548 return *this;
00549 }
00550
00551 template <typename G, typename C>
00552 inline
00553 point<G,C>&
00554 point<G,C>::operator-=(const delta& dp)
00555 {
00556 for (unsigned i = 0; i < dim; ++i)
00557 coord_[i] -= dp[i];
00558 return *this;
00559 }
00560
00561 template <typename G, typename C>
00562 inline
00563 point<G,C>::operator typename internal::vec_of_point<G,C>::ret () const
00564 {
00565 return to_vec();
00566 }
00567
00568 template <typename G, typename C>
00569 inline
00570 typename point<G,C>::vec
00571 point<G,C>::to_vec() const
00572 {
00573
00574 if (dim > 2)
00575 {
00576 mln::algebra::vec<G::dim, float> tmp;
00577 unsigned j = 0;
00578 for (unsigned i = dim - 2; i < dim; ++i)
00579 tmp[j++] = mln::internal::convert_data<float>(coord_[i]);
00580 for (unsigned i = 2; i < dim; ++i, ++j)
00581 tmp[j] = mln::internal::convert_data<float>(coord_[i-j]);
00582
00583 return tmp;
00584 }
00585
00586 return coord_;
00587 }
00588
00589 template <typename G, typename C>
00590 inline
00591 typename point<G,C>::h_vec
00592 point<G,C>::to_h_vec() const
00593 {
00594 mln::algebra::h_vec<G::dim, float> tmp;
00595
00596
00597 if (dim == 1)
00598 tmp[0] = coord_[0];
00599 else
00600 {
00601 unsigned j = 0;
00602 for (unsigned i = dim - 2; i < dim; ++i)
00603 tmp[j++] = coord_[i];
00604
00605 for (unsigned i = 2; i < dim; ++i, ++j)
00606 tmp[j] = coord_[i-j];
00607
00608 tmp[G::dim] = 1;
00609 }
00610
00611 return tmp;
00612 }
00613
00614
00615 template <typename G, typename C>
00616 inline
00617 const point<G,C>&
00618 point<G,C>::plus_infty()
00619 {
00620 static const point<G,C> the_(all_to(mln_max(C)));
00621 return the_;
00622 }
00623
00624 template <typename G, typename C>
00625 inline
00626 const point<G,C>&
00627 point<G,C>::minus_infty()
00628 {
00629 static const point<G,C> the_(all_to(mln_min(C)));
00630 return the_;
00631 }
00632
00633 template <typename G, typename C>
00634 inline
00635 mln::algebra::vec<G::dim, C>&
00636 point<G,C>::hook_coord_()
00637 {
00638 return coord_;
00639 }
00640
00641 namespace internal
00642 {
00643
00644 template <typename G, typename C, typename E>
00645 inline
00646 const E&
00647 subject_point_impl< point<G,C>, E >::exact_() const
00648 {
00649 return internal::force_exact<const E>(*this);
00650 }
00651
00652 template <typename G, typename C, typename E>
00653 inline
00654 typename point<G,C>::vec
00655 subject_point_impl< point<G,C>, E >::to_vec() const
00656 {
00657 return exact_().get_subject().to_vec();
00658 }
00659
00660 template <typename G, typename C, typename E>
00661 inline
00662 subject_point_impl< point<G,C>, E >::operator typename point<G,C>::vec () const
00663 {
00664 return exact_().get_subject();
00665 }
00666
00667 }
00668
00669 template <typename G, typename C>
00670 inline
00671 const mln::algebra::vec<point<G,C>::dim - 1, C>&
00672 cut_(const point<G,C>& p)
00673 {
00674 return *(mln::algebra::vec<point<G,C>::dim - 1, C>*)(& p.to_vec());
00675 }
00676
00677 template <typename C>
00678 inline
00679 const util::yes&
00680 cut_(const point<grid::tick,C>& )
00681 {
00682 util::yes* the_;
00683 return *the_;
00684 }
00685
00686 # endif // ! MLN_INCLUDE_ONLY
00687
00688
00689 }
00690
00691
00692 #endif // ! MLN_CORE_POINT_HH