00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef INSTIGATE_GEOMETRY_ALGORITHM
00011 #define INSTIGATE_GEOMETRY_ALGORITHM
00012
00023
00024 #include "concept_point.hpp"
00025 #include "concept_line.hpp"
00026 #include "concept_rectangle.hpp"
00027
00028
00029 #include <stl/algorithm.hpp>
00030
00031
00032 #include <limits>
00033
00034 namespace instigate {
00035 namespace geometry {
00036
00038 namespace implementation {
00039
00040 template <typename C>
00041 C get_middle_point(const C& a, const C& b,
00042 const C& c, const C& d);
00043
00044 }
00045
00046 template <typename P, typename C>
00047 void set_x(P& p, const C& c);
00048
00049 template <typename P, typename C>
00050 void set_y(P& p, const C& c);
00051
00052 template <typename R, typename P>
00053 void set_right(R& r, const P& x);
00054
00055 template <typename R, typename P>
00056 void set_left(R& r, const P& x);
00057
00058 template <typename R>
00059 bool is_intersect(const R& a, const R& b);
00060
00061 template <typename R, typename P>
00062 void get_first_nearest_point(const R& a, const R& b, P& p);
00063
00064 template <typename R, typename P>
00065 void get_second_nearest_point(const R& a, const R& b, P& p);
00066
00067 template <typename R, typename P>
00068 void set_bottom(R& r, const P& x);
00069
00070 template <typename R, typename P>
00071 void set_top(R& r, const P& x);
00072
00073 template <typename R, typename P>
00074 P get_right(R& r);
00075
00076 template <typename R, typename P>
00077 P get_left(R& r);
00078
00079 template <typename R, typename P>
00080 P get_bottom(R& r);
00081
00082 template <typename R, typename P>
00083 P get_top(R& r);
00084
00085 template <typename L, typename C>
00086 void set_source_x(L& l, const C& x);
00087
00088 template <typename L, typename C>
00089 void set_source_y(L& l, const C& y);
00090
00091 template <typename L, typename C>
00092 void set_target_x(L& l, const C& x);
00093
00094 template <typename L, typename C>
00095 void set_target_y(L& l, const C& y);
00096
00097 template <typename L, typename P>
00098 P get_source_x(L& l);
00099
00100 template <typename L, typename P>
00101 P get_source_y(L& l);
00102
00103 template <typename L, typename P>
00104 P get_target_x(L& l);
00105
00106 template <typename L, typename P>
00107 P get_target_y(L& l);
00108
00109 template <typename L, typename P>
00110 void set_source(L& l, const P& v);
00111
00112 }
00113 }
00114
00115
00132 template <typename C>
00133 C instigate::geometry::implementation::get_middle_point(const C& a,
00134 const C& b, const C& c, const C& d)
00135 {
00136 typedef std::numeric_limits<C> L;
00137 CHECK(instigate::generic::require<L::is_specialized>);
00138 namespace N = instigate::stl;
00139 return (N::max(N::min(a, b), c) + N::min(N::max(c, d), a)) / 2;
00140 }
00141
00158 template <typename P, typename C>
00159 void instigate::geometry::set_x(P& p, const C& c)
00160 {
00161 typedef concept::point::interface<P> PC;
00162 typedef std::numeric_limits<C> L;
00163 CHECK(instigate::generic::require<L::is_specialized>);
00164 CHECK(concept::point::requirements<P>);
00165 CHECK_CONVERTIBILITY(C, typename PC::coordinate_type);
00166 PC::set_x(p, c);
00167 }
00168
00185 template <typename P, typename C>
00186 void instigate::geometry::set_y(P& p, const C& c)
00187 {
00188 typedef concept::point::interface<P> PC;
00189 typedef std::numeric_limits<C> L;
00190 CHECK(concept::point::requirements<P>);
00191 CHECK(generic::require<L::is_specialized>);
00192 CHECK_CONVERTIBILITY(C, typename PC::coordinate_type);
00193 PC::set_y(p, c);
00194 }
00195
00211 template <typename R, typename P>
00212 void instigate::geometry::set_right(R& r, const P& x)
00213 {
00214 typedef concept::rectangle::interface<R> RCI;
00215 typedef typename RCI::coordinate_type C;
00216 typedef std::numeric_limits<P> L;
00217 CHECK(instigate::generic::require<L::is_specialized>);
00218 CHECK(concept::rectangle::requirements<R>);
00219 CHECK_CONVERTIBILITY(P, C);
00220 RCI::set_right(r, x);
00221 }
00222
00238 template <typename R, typename P>
00239 void instigate::geometry::set_left(R& r, const P& x)
00240 {
00241 typedef concept::rectangle::interface<R> RCI;
00242 typedef typename RCI::coordinate_type C;
00243 typedef std::numeric_limits<P> L;
00244 CHECK(instigate::generic::require<L::is_specialized>);
00245 CHECK(concept::rectangle::requirements<R>);
00246 CHECK_CONVERTIBILITY(P, C);
00247 RCI::set_left(r, x);
00248 }
00249
00262 template <typename R>
00263 bool instigate::geometry::is_intersect(const R& a, const R& b)
00264 {
00265 CHECK(concept::rectangle::requirements<R>);
00266 typedef concept::rectangle::interface<R> RI;
00267 namespace N = instigate::stl;
00268 if (RI::get_bottom(a) < RI::get_top(b)) {
00269 return ! (RI::get_bottom(a) > RI::get_top(b) ||
00270 RI::get_top(a) < RI::get_bottom(b) ||
00271 RI::get_right(a) < RI::get_left(b) ||
00272 RI::get_left(a) > RI::get_right(b));
00273 }
00274 return ! (RI::get_bottom(a) < RI::get_top(b) ||
00275 RI::get_top(a) > RI::get_bottom(b) ||
00276 RI::get_right(a) < RI::get_left(b) ||
00277 RI::get_left(a) > RI::get_right(b));
00278 }
00279
00297 template <typename R, typename P>
00298 void instigate::geometry::get_first_nearest_point(const R& a,
00299 const R& b, P& p)
00300 {
00301 typedef concept::rectangle::interface<R> RI;
00302 CHECK(concept::rectangle::requirements<R>);
00303 namespace N = instigate::stl;
00304 set_x(p, implementation::get_middle_point(
00305 N::max(RI::get_right(a), RI::get_left(a)),
00306 N::max(RI::get_right(b), RI::get_left(b)),
00307 N::min(RI::get_right(a), RI::get_left(a)),
00308 N::min(RI::get_right(b), RI::get_left(b))));
00309 set_y(p, implementation::get_middle_point(
00310 N::max(RI::get_top(a), RI::get_bottom(a)),
00311 N::max(RI::get_top(b), RI::get_bottom(b)),
00312 N::min(RI::get_top(a), RI::get_bottom(a)),
00313 N::min(RI::get_top(b), RI::get_bottom(b))));
00314 }
00315
00334 template <typename R, typename P>
00335 void instigate::geometry::get_second_nearest_point(const R& a,
00336 const R& b, P& p)
00337 {
00338 typedef concept::rectangle::interface<R> RI;
00339 CHECK(concept::rectangle::requirements<R>);
00340 namespace N = instigate::stl;
00341 set_x(p, implementation::get_middle_point(
00342 N::max(RI::get_right(b), RI::get_left(b)),
00343 N::max(RI::get_right(a), RI::get_left(a)),
00344 N::min(RI::get_right(b), RI::get_left(b)),
00345 N::min(RI::get_right(a), RI::get_left(a))));
00346 set_y(p, implementation::get_middle_point(
00347 N::max(RI::get_top(b), RI::get_bottom(b)),
00348 N::max(RI::get_top(a), RI::get_bottom(a)),
00349 N::min(RI::get_top(b), RI::get_bottom(b)),
00350 N::min(RI::get_top(a), RI::get_bottom(a))));
00351 }
00352
00368 template <typename R, typename P>
00369 void instigate::geometry::set_bottom(R& r, const P& x)
00370 {
00371 typedef concept::rectangle::interface<R> RCI;
00372 typedef typename RCI::coordinate_type C;
00373 typedef std::numeric_limits<P> L;
00374 CHECK(instigate::generic::require<L::is_specialized>);
00375 CHECK(concept::rectangle::requirements<R>);
00376 CHECK_CONVERTIBILITY(P, C);
00377 RCI::set_bottom(r, x);
00378 }
00379
00395 template <typename R, typename P>
00396 void instigate::geometry::set_top(R& r, const P& x)
00397 {
00398 typedef concept::rectangle::interface<R> RCI;
00399 typedef typename RCI::coordinate_type C;
00400 typedef std::numeric_limits<P> L;
00401 CHECK(instigate::generic::require<L::is_specialized>);
00402 CHECK(concept::rectangle::requirements<R>);
00403 CHECK_CONVERTIBILITY(P, C);
00404 RCI::set_top(r, x);
00405 }
00406
00422 template <typename R, typename P>
00423 P instigate::geometry::get_right(R& r)
00424 {
00425 typedef concept::rectangle::interface<R> RCI;
00426 typedef typename RCI::coordinate_type C;
00427 typedef std::numeric_limits<P> L;
00428 CHECK(instigate::generic::require<L::is_specialized>);
00429 CHECK(concept::rectangle::requirements<R>);
00430 CHECK_CONVERTIBILITY(P, C);
00431 return RCI::get_right(r);
00432 }
00433
00449 template <typename R, typename P>
00450 P instigate::geometry::get_left(R& r)
00451 {
00452 typedef concept::rectangle::interface<R> RCI;
00453 typedef typename RCI::coordinate_type C;
00454 typedef std::numeric_limits<P> L;
00455 CHECK(instigate::generic::require<L::is_specialized>);
00456 CHECK(concept::rectangle::requirements<R>);
00457 CHECK_CONVERTIBILITY(P, C);
00458 return RCI::get_left(r);
00459 }
00460
00476 template <typename R, typename P>
00477 P instigate::geometry::get_bottom(R& r)
00478 {
00479 typedef concept::rectangle::interface<R> RCI;
00480 typedef typename RCI::coordinate_type C;
00481 typedef std::numeric_limits<P> L;
00482 CHECK(instigate::generic::require<L::is_specialized>);
00483 CHECK(concept::rectangle::requirements<R>);
00484 CHECK_CONVERTIBILITY(P, C);
00485 return RCI::get_bottom(r);
00486 }
00487
00503 template <typename R, typename P>
00504 P instigate::geometry::get_top(R& r)
00505 {
00506 typedef concept::rectangle::interface<R> RCI;
00507 typedef typename RCI::coordinate_type C;
00508 typedef std::numeric_limits<P> L;
00509 CHECK(instigate::generic::require<L::is_specialized>);
00510 CHECK(concept::rectangle::requirements<R>);
00511 CHECK_CONVERTIBILITY(P, C);
00512 return RCI::get_top(r);
00513 }
00514
00531 template <typename L, typename C>
00532 void instigate::geometry::set_source_x(L& l, const C& x)
00533 {
00534 typedef concept::line::interface<L> LCI;
00535 typedef std::numeric_limits<C> N;
00536 CHECK(generic::require<N::is_specialized>);
00537 CHECK(concept::line::requirements<L>);
00538 CHECK_CONVERTIBILITY(C, typename LCI::coordinate_type);
00539 LCI::set_source_x(l, x);
00540 }
00541
00558 template <typename L, typename C>
00559 void instigate::geometry::set_source_y(L& l, const C& y)
00560 {
00561 typedef concept::line::interface<L> LCI;
00562 typedef std::numeric_limits<C> N;
00563 CHECK(generic::require<N::is_specialized>);
00564 CHECK(concept::line::requirements<L>);
00565 CHECK_CONVERTIBILITY(C, typename LCI::coordinate_type);
00566 LCI::set_source_y(l, y);
00567 }
00568
00585 template <typename L, typename C>
00586 void instigate::geometry::set_target_x(L& l, const C& x)
00587 {
00588 typedef concept::line::interface<L> LCI;
00589 typedef std::numeric_limits<C> N;
00590 CHECK(generic::require<N::is_specialized>);
00591 CHECK(concept::line::requirements<L>);
00592 CHECK_CONVERTIBILITY(C, typename LCI::coordinate_type);
00593 LCI::set_target_x(l, x);
00594 }
00595
00612 template <typename L, typename C>
00613 void instigate::geometry::set_target_y(L& l, const C& y)
00614 {
00615 typedef concept::line::interface<L> LCI;
00616 typedef std::numeric_limits<C> N;
00617 CHECK(generic::require<N::is_specialized>);
00618 CHECK(concept::line::requirements<L>);
00619 CHECK_CONVERTIBILITY(C, typename LCI::coordinate_type);
00620 LCI::set_target_y(l, y);
00621 }
00622
00638 template <typename L, typename P>
00639 P instigate::geometry::get_source_x(L& l)
00640 {
00641 typedef concept::line::interface<L> LCI;
00642 typedef typename LCI::coordinate_type C;
00643 typedef std::numeric_limits<P> N;
00644 CHECK(generic::require<N::is_specialized>);
00645 CHECK(concept::line::requirements<L>);
00646 CHECK_CONVERTIBILITY(P, C);
00647 return LCI::get_source_x(l);
00648 }
00649
00665 template <typename L, typename P>
00666 P instigate::geometry::get_source_y(L& l)
00667 {
00668 typedef concept::line::interface<L> LCI;
00669 typedef typename LCI::coordinate_type C;
00670 typedef std::numeric_limits<P> N;
00671 CHECK(generic::require<N::is_specialized>);
00672 CHECK(concept::line::requirements<L>);
00673 CHECK_CONVERTIBILITY(P, C);
00674 return LCI::get_source_y(l);
00675 }
00676
00677
00693 template <typename L, typename P>
00694 P instigate::geometry::get_target_x(L& l)
00695 {
00696 typedef concept::line::interface<L> LCI;
00697 typedef typename LCI::coordinate_type C;
00698 typedef std::numeric_limits<P> N;
00699 CHECK(generic::require<N::is_specialized>);
00700 CHECK(concept::line::requirements<L>);
00701 CHECK_CONVERTIBILITY(P, C);
00702 return LCI::get_target_x(l);
00703 }
00704
00720 template <typename L, typename P>
00721 P instigate::geometry::get_target_y(L& l)
00722 {
00723 typedef concept::line::interface<L> LCI;
00724 typedef typename LCI::coordinate_type C;
00725 typedef std::numeric_limits<P> N;
00726 CHECK(generic::require<N::is_specialized>);
00727 CHECK(concept::line::requirements<L>);
00728 CHECK_CONVERTIBILITY(P, C);
00729 return LCI::get_target_y(l);
00730 }
00731
00747 template <typename L, typename P>
00748 void instigate::geometry::set_source(L& l, const P& v)
00749 {
00750 typedef concept::line::interface<L> LC;
00751 typedef std::numeric_limits<typename P::coordinate_type> N;
00752 CHECK(generic::require<N::is_specialized>);
00753 typedef std::numeric_limits<typename L::coordinate_type> H;
00754 CHECK(generic::require<H::is_specialized>);
00755 CHECK(concept::line::requirements<L>);
00756 CHECK(concept::point::requirements<P>);
00757 CHECK_CONVERTIBILITY(P, typename LC::point_type);
00758 LC::set_source_x(l, v.get_x());
00759 LC::set_source_y(l, v.get_y());
00760 }
00761
00762 #endif // INSTIGATE_FRAMEWORK_GEOMETRY_ALGORITHM