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 #ifndef MLN_CORE_POINT_HH
00027 # define MLN_CORE_POINT_HH
00028
00037
00038 # include <mln/core/def/coord.hh>
00039 # include <mln/core/concept/proxy.hh>
00040 # include <mln/core/concept/gpoint.hh>
00041 # include <mln/core/internal/coord_impl.hh>
00042 # include <mln/fun/i2v/all_to.hh>
00043
00044 # include <mln/metal/bool.hh>
00045 # include <mln/metal/is_not.hh>
00046 # include <mln/algebra/vec.hh>
00047 # include <mln/metal/converts_to.hh>
00048 # include <mln/algebra/h_vec.hh>
00049 # include <mln/util/yes.hh>
00050
00051
00052 namespace mln
00053 {
00054
00056 template <typename G, typename C> struct point;
00057 template <typename G, typename C> struct dpoint;
00058 namespace literal {
00059 struct zero_t;
00060 struct one_t;
00061 struct origin_t;
00062 }
00064
00065
00066 namespace convert
00067 {
00068
00069 namespace over_load
00070 {
00071
00072 template <typename G, typename C1, typename C2>
00073 void from_to_(const point<G,C1>& from, point<G,C2>& to);
00074
00075 }
00076
00077 }
00078
00079
00080
00081 namespace internal
00082 {
00083
00084
00085 template <typename G, typename C>
00086 struct vec_of_point
00087 {
00088 typedef algebra::vec<G::dim, float> ret;
00089 };
00090 }
00091
00096 template <typename G, typename C>
00097 struct point : public Gpoint< point<G,C> >,
00098 public internal::mutable_coord_impl_< G::dim, C, point<G,C> >
00099 {
00100
00101 typedef point site;
00102 typedef point psite;
00103
00104
00108 enum { dim = G::dim };
00109
00111 typedef G grid;
00112
00114 typedef dpoint<G,C> delta;
00115
00117 typedef dpoint<G,C> dpsite;
00118
00120 typedef C coord;
00121
00123 typedef algebra::vec<G::dim, float> vec;
00124
00126 typedef algebra::h_vec<G::dim, float> h_vec;
00127
00131 const C& operator[](unsigned i) const;
00132
00136 C& operator[](unsigned i);
00137
00138
00140 const C& last_coord() const;
00141
00143 C& last_coord();
00144
00145
00147 point();
00148
00150 template <typename C2>
00151 point(const algebra::vec<dim,C2>& v);
00152
00155 explicit point(C ind);
00156 point(C row, C col);
00157 point(C sli, C row, C col);
00159
00161 point(const literal::origin_t&);
00162 point<G,C>& operator=(const literal::origin_t&);
00163
00164 point(const literal::zero_t&);
00165 point<G,C>& operator=(const literal::zero_t&);
00166 point(const literal::one_t&);
00167 point<G,C>& operator=(const literal::one_t&);
00169
00171 template <typename F>
00172 point(const Function_v2v<F>& f);
00173
00175 void set_all(C c);
00176
00178 static const point<G,C> origin;
00179
00181 point<G,C>& operator+=(const delta& dp);
00182
00184 point<G,C>& operator-=(const delta& dp);
00185
00186
00187
00188
00189
00190
00191
00192 operator typename internal::vec_of_point<G,C>::ret () const;
00193
00195 vec to_vec() const;
00196
00198 h_vec to_h_vec() const;
00199
00201 static const point<G,C>& plus_infty();
00202
00204 static const point<G,C>& minus_infty();
00205
00206 protected:
00207 algebra::vec<G::dim, C> coord_;
00208 };
00209
00210 namespace internal
00211 {
00212
00215
00216 template <typename P, typename E>
00217 struct subject_point_impl;
00218
00219 template <typename G, typename C, typename E>
00220 struct subject_point_impl< point<G,C>, E >
00221 {
00222 typename point<G,C>::vec to_vec() const;
00223 operator typename point<G,C>::vec () const;
00224
00225 private:
00226 const E& exact_() const;
00227 };
00228
00230
00231 }
00232
00233
00235 template <typename G, typename C>
00236 const algebra::vec<point<G,C>::dim - 1, C>& cut_(const point<G,C>& p);
00237
00238 template <typename C>
00239 const util::yes& cut_(const point<grid::tick,C>& p);
00240
00241
00242
00243 # ifndef MLN_INCLUDE_ONLY
00244
00245 namespace convert
00246 {
00247
00248 namespace over_load
00249 {
00250
00251 template <typename G, typename C1, typename C2>
00252 inline
00253 void
00254 from_to_(const point<G,C1>& from, point<G,C2>& to)
00255 {
00256 mlc_converts_to(C1,C2)::check();
00257 to = point<G,C2>(from.to_vec());
00258 }
00259
00260 }
00261
00262 }
00263
00264
00265 template <typename G, typename C>
00266 inline
00267 const C& point<G,C>::operator[](unsigned i) const
00268 {
00269 assert(i < dim);
00270 return this->coord_[i];
00271 }
00272
00273 template <typename G, typename C>
00274 inline
00275 C& point<G,C>::operator[](unsigned i)
00276 {
00277 assert(i < dim);
00278 return this->coord_[i];
00279 }
00280
00281 template <typename G, typename C>
00282 inline
00283 const C&
00284 point<G,C>::last_coord() const
00285 {
00286 return this->coord_[dim - 1];
00287 }
00288
00289 template <typename G, typename C>
00290 inline
00291 C&
00292 point<G,C>::last_coord()
00293 {
00294 return this->coord_[dim - 1];
00295 }
00296
00297
00298
00299
00300 template <typename G, typename C>
00301 inline
00302 point<G,C>::point()
00303 {
00304 }
00305
00306 template <typename G, typename C>
00307 template <typename C2>
00308 inline
00309 point<G,C>::point(const algebra::vec<dim,C2>& v)
00310 {
00311 mlc_converts_to(C2, C)::check();
00312 unsigned j = 0;
00313
00314 if (dim < 3)
00315 coord_ = v;
00316 else
00317 {
00318 for (unsigned i = dim - 2; i < dim; ++i)
00319 coord_[i] = static_cast<C>(v[j++]);
00320 for (unsigned i = 2; i < dim; ++i, ++j)
00321 coord_[i-j] = static_cast<C>(v[j]);
00322 }
00323 }
00324
00325 template <typename G, typename C>
00326 inline
00327 point<G,C>::point(C ind)
00328 {
00329 metal::bool_<(dim == 1)>::check();
00330 coord_[0] = ind;
00331 }
00332
00333 template <typename G, typename C>
00334 inline
00335 point<G,C>::point(C row, C col)
00336 {
00337 metal::bool_<(dim == 2)>::check();
00338 coord_[0] = row;
00339 coord_[1] = col;
00340 }
00341
00342 template <typename G, typename C>
00343 inline
00344 point<G,C>::point(C sli, C row, C col)
00345 {
00346 metal::bool_<(dim == 3)>::check();
00347 coord_[0] = sli;
00348 coord_[1] = row;
00349 coord_[2] = col;
00350 }
00351
00352 template <typename G, typename C>
00353 template <typename F>
00354 inline
00355 point<G,C>::point(const Function_v2v<F>& f_)
00356 {
00357 mlc_converts_to(mln_result(F), C)::check();
00358 const F& f = exact(f_);
00359 for (unsigned i = 0; i < dim; ++i)
00360 coord_[i] = static_cast<C>( f(i) );
00361 }
00362
00363 template <typename G, typename C>
00364 inline
00365 point<G,C>::point(const literal::origin_t&)
00366 {
00367 coord_.set_all(0);
00368 }
00369
00370 template <typename G, typename C>
00371 inline
00372 point<G,C>&
00373 point<G,C>::operator=(const literal::origin_t&)
00374 {
00375 coord_.set_all(0);
00376 return *this;
00377 }
00378
00379 template <typename G, typename C>
00380 inline
00381 point<G,C>::point(const literal::zero_t&)
00382 {
00383 metal::bool_<(dim == 1)>::check();
00384 coord_[0] = 1;
00385 }
00386
00387 template <typename G, typename C>
00388 inline
00389 point<G,C>&
00390 point<G,C>::operator=(const literal::zero_t&)
00391 {
00392 metal::bool_<(dim == 1)>::check();
00393 coord_[0] = 1;
00394 return *this;
00395 }
00396
00397 template <typename G, typename C>
00398 inline
00399 point<G,C>::point(const literal::one_t&)
00400 {
00401 metal::bool_<(dim == 1)>::check();
00402 coord_[0] = 1;
00403 }
00404
00405 template <typename G, typename C>
00406 inline
00407 point<G,C>&
00408 point<G,C>::operator=(const literal::one_t&)
00409 {
00410 metal::bool_<(dim == 1)>::check();
00411 coord_[0] = 1;
00412 return *this;
00413 }
00414
00415 template <typename G, typename C>
00416 inline
00417 void point<G,C>::set_all(C c)
00418 {
00419 coord_.set_all(c);
00420 }
00421
00422 template <typename G, typename C>
00423 const point<G,C> point<G,C>::origin = all_to(0);
00424
00425 template <typename G, typename C>
00426 inline
00427 point<G,C>&
00428 point<G,C>::operator+=(const delta& dp)
00429 {
00430 for (unsigned i = 0; i < dim; ++i)
00431 coord_[i] = static_cast<C>(coord_[i] + dp[i]);
00432 return *this;
00433 }
00434
00435 template <typename G, typename C>
00436 inline
00437 point<G,C>&
00438 point<G,C>::operator-=(const delta& dp)
00439 {
00440 for (unsigned i = 0; i < dim; ++i)
00441 coord_[i] -= dp[i];
00442 return *this;
00443 }
00444
00445 template <typename G, typename C>
00446 inline
00447 point<G,C>::operator typename internal::vec_of_point<G,C>::ret () const
00448 {
00449 return to_vec();
00450 }
00451
00452 template <typename G, typename C>
00453 inline
00454 typename point<G,C>::vec
00455 point<G,C>::to_vec() const
00456 {
00457
00458 if (dim > 2)
00459 {
00460 algebra::vec<G::dim, float> tmp;
00461 unsigned j = 0;
00462 for (unsigned i = dim - 2; i < dim; ++i)
00463 tmp[j++] = coord_[i];
00464 for (unsigned i = 2; i < dim; ++i, ++j)
00465 tmp[j] = coord_[i-j];
00466
00467 return tmp;
00468 }
00469
00470 return coord_;
00471 }
00472
00473 template <typename G, typename C>
00474 inline
00475 typename point<G,C>::h_vec
00476 point<G,C>::to_h_vec() const
00477 {
00478 algebra::h_vec<G::dim, float> tmp;
00479
00480
00481 if (dim == 1)
00482 tmp[0] = coord_[0];
00483 else
00484 {
00485 unsigned j = 0;
00486 for (unsigned i = dim - 2; i < dim; ++i)
00487 tmp[j++] = coord_[i];
00488
00489 for (unsigned i = 2; i < dim; ++i, ++j)
00490 tmp[j] = coord_[i-j];
00491
00492 tmp[G::dim] = 1;
00493 }
00494
00495 return tmp;
00496 }
00497
00498
00499 template <typename G, typename C>
00500 inline
00501 const point<G,C>&
00502 point<G,C>::plus_infty()
00503 {
00504 static const point<G,C> the_(all_to(mln_max(C)));
00505 return the_;
00506 }
00507
00508 template <typename G, typename C>
00509 inline
00510 const point<G,C>&
00511 point<G,C>::minus_infty()
00512 {
00513 static const point<G,C> the_(all_to(mln_min(C)));
00514 return the_;
00515 }
00516
00517 namespace internal
00518 {
00519
00520 template <typename G, typename C, typename E>
00521 inline
00522 const E&
00523 subject_point_impl< point<G,C>, E >::exact_() const
00524 {
00525 return internal::force_exact<const E>(*this);
00526 }
00527
00528 template <typename G, typename C, typename E>
00529 inline
00530 typename point<G,C>::vec
00531 subject_point_impl< point<G,C>, E >::to_vec() const
00532 {
00533 return exact_().get_subject().to_vec();
00534 }
00535
00536 template <typename G, typename C, typename E>
00537 inline
00538 subject_point_impl< point<G,C>, E >::operator typename point<G,C>::vec () const
00539 {
00540 return exact_().get_subject();
00541 }
00542
00543 }
00544
00545 template <typename G, typename C>
00546 inline
00547 const algebra::vec<point<G,C>::dim - 1, C>&
00548 cut_(const point<G,C>& p)
00549 {
00550 return *(algebra::vec<point<G,C>::dim - 1, C>*)(& p.to_vec());
00551 }
00552
00553 template <typename C>
00554 inline
00555 const util::yes&
00556 cut_(const point<grid::tick,C>& p)
00557 {
00558 util::yes* the_;
00559 return *the_;
00560 }
00561
00562 # endif // ! MLN_INCLUDE_ONLY
00563
00564
00565 }
00566
00567
00568 #endif // ! MLN_CORE_POINT_HH