Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE) 00002 // 00003 // This file is part of Olena. 00004 // 00005 // Olena is free software: you can redistribute it and/or modify it under 00006 // the terms of the GNU General Public License as published by the Free 00007 // Software Foundation, version 2 of the License. 00008 // 00009 // Olena is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 // General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with Olena. If not, see <http://www.gnu.org/licenses/>. 00016 // 00017 // As a special exception, you may use this file as part of a free 00018 // software project without restriction. Specifically, if other files 00019 // instantiate templates or use macros or inline functions from this 00020 // file, or you compile this file and link it with other files to produce 00021 // an executable, this file does not by itself cause the resulting 00022 // executable to be covered by the GNU General Public License. This 00023 // exception does not however invalidate any other reasons why the 00024 // executable file might be covered by the GNU General Public License. 00025 00026 #ifndef MLN_CORE_SITE_SET_P_LINE2D_HH 00027 # define MLN_CORE_SITE_SET_P_LINE2D_HH 00028 00033 00034 # include <mln/core/site_set/p_array.hh> 00035 # include <mln/core/alias/box2d.hh> 00036 00037 # include <mln/math/sign.hh> 00038 # include <mln/math/abs.hh> 00039 # include <mln/math/min.hh> 00040 # include <mln/math/max.hh> 00041 00042 00043 namespace mln 00044 { 00045 00046 // Forward declaration. 00047 class p_line2d; 00048 00049 00050 00051 namespace trait 00052 { 00053 00054 template <> 00055 struct site_set_< p_line2d > 00056 { 00057 typedef trait::site_set::nsites::known nsites; 00058 typedef trait::site_set::bbox::straight bbox; 00059 typedef trait::site_set::contents::fixed contents; 00060 typedef trait::site_set::arity::unique arity; 00061 }; 00062 00063 template <> 00064 struct set_precise_unary_< op::ord, p_line2d > 00065 { 00066 typedef set_precise_unary_< op::ord, p_line2d > ret; // Itself. 00067 bool strict(const p_line2d& lhs, const p_line2d& rhs) const; 00068 }; 00069 00070 } // end of namespace trait 00071 00072 00073 00078 // 00079 class p_line2d : public internal::site_set_base_< point2d, p_line2d > 00080 { 00081 typedef p_line2d self_; 00082 public: 00083 00085 typedef point2d element; 00086 00088 typedef p_indexed_psite<self_> psite; 00089 00091 typedef p_indexed_fwd_piter<self_> piter; 00092 00094 typedef p_indexed_fwd_piter<self_> fwd_piter; 00095 00097 typedef p_indexed_bkd_piter<self_> bkd_piter; 00098 00099 00101 p_line2d(); 00102 00104 p_line2d(const point2d& beg, const point2d& end, 00105 bool is_end_excluded = false); 00106 00107 00109 bool has(const psite& p) const; 00110 00112 bool has(const util::index& i) const; 00113 00115 bool is_valid() const; 00116 00117 00119 unsigned nsites() const; 00120 00122 const point2d& begin() const; 00123 00125 const point2d& end() const; 00126 00128 const point2d& operator[](unsigned i) const; 00129 00130 00132 typedef const box2d& q_box; 00133 00135 const box2d& bbox() const; 00136 00137 00139 std::size_t memory_size() const; 00140 00142 const std::vector<point2d>& std_vector() const; 00143 00144 // Return the corresponding algebra::vec. 00145 algebra::vec<2, float> to_vec() const; 00146 00147 protected: 00148 00149 p_array<point2d> arr_; 00150 box2d bb_; 00151 00152 void compute_(const point2d& beg, const point2d& end, 00153 bool is_end_excluded); 00154 }; 00155 00156 00157 00158 # ifndef MLN_INCLUDE_ONLY 00159 00160 inline 00161 p_line2d::p_line2d() 00162 { 00163 mln_postcondition(! is_valid()); 00164 } 00165 00166 inline 00167 p_line2d::p_line2d(const point2d& beg, const point2d& end, 00168 bool is_end_excluded) 00169 { 00170 if (is_end_excluded) 00171 mln_precondition(end != beg); 00172 compute_(beg, end, is_end_excluded); 00173 mln_postcondition(is_valid()); 00174 } 00175 00176 inline 00177 void 00178 p_line2d::compute_(const point2d& beg, const point2d& end, 00179 bool is_end_excluded) 00180 { 00181 if (is_end_excluded) 00182 mln_precondition(end != beg); 00183 00184 // Compute arr_. 00185 dpoint2d dp = end - beg; 00186 int 00187 srow = math::sign(dp.row()), drow = math::abs(dp.row()), ddrow = 2 * drow, 00188 scol = math::sign(dp.col()), dcol = math::abs(dp.col()), ddcol = 2 * dcol, 00189 row = beg.row(), 00190 col = beg.col(); 00191 if ( dcol > drow ) 00192 { 00193 int e = ddrow - dcol; 00194 for (int i = 0; i < dcol; ++i) 00195 { 00196 arr_.append(point2d(static_cast<def::coord>(row), 00197 static_cast<def::coord>(col))); 00198 while (e >= 0) 00199 { 00200 row += srow; 00201 e -= ddcol; 00202 } 00203 col += scol; 00204 e += ddrow; 00205 } 00206 } 00207 else 00208 { 00209 int e = ddcol - drow; 00210 for (int i = 0; i < drow; ++i) 00211 { 00212 arr_.append(point2d(static_cast<def::coord>(row), 00213 static_cast<def::coord>(col))); 00214 while (e >= 0) 00215 { 00216 col += scol; 00217 e -= ddrow; 00218 } 00219 row += srow; 00220 e += ddcol; 00221 } 00222 } 00223 if (! is_end_excluded) 00224 arr_.append(point2d(static_cast<def::coord>(row), 00225 static_cast<def::coord>(col))); 00226 00227 // Compute bb_. 00228 point2d end_ = arr_[arr_.nsites() - 1]; 00229 bb_.pmin() = point2d(math::min(beg.row(), end_.row()), 00230 math::min(beg.col(), end_.col())); 00231 bb_.pmax() = point2d(math::max(beg.row(), end_.row()), 00232 math::max(beg.col(), end_.col())); 00233 00234 mln_postcondition(this->begin() == beg); 00235 mln_postcondition(is_end_excluded == (this->end() != end)); 00236 } 00237 00238 inline 00239 bool 00240 p_line2d::has(const psite& p) const 00241 { 00242 mln_precondition(p.target_() == this); // FIXME: Refine. 00243 if (! has(p.index())) 00244 return false; 00245 mln_invariant(p.to_site() == (*this)[p.index()]); 00246 return true; 00247 } 00248 00249 inline 00250 bool 00251 p_line2d::has(const util::index& i) const 00252 { 00253 return i >= 0 && unsigned(i) < nsites(); 00254 } 00255 00256 inline 00257 bool 00258 p_line2d::is_valid() const 00259 { 00260 mln_invariant(implies(bb_.is_valid(), ! arr_.is_empty())); 00261 return bb_.is_valid(); 00262 } 00263 00264 inline 00265 unsigned 00266 p_line2d::nsites() const 00267 { 00268 return arr_.nsites(); 00269 } 00270 00271 inline 00272 const box2d& 00273 p_line2d::bbox() const 00274 { 00275 mln_precondition(is_valid()); 00276 return bb_; 00277 } 00278 00279 inline 00280 const std::vector<point2d>& 00281 p_line2d::std_vector() const 00282 { 00283 return arr_.std_vector(); 00284 } 00285 00286 // FIXME: make it more generic? 00287 inline 00288 algebra::vec<2, float> 00289 p_line2d::to_vec() const 00290 { 00291 algebra::vec<2, float> res; 00292 res[0] = float(end().row() - begin().row()); 00293 res[1] = float(end().col() - begin().col()); 00294 return res; 00295 } 00296 00297 inline 00298 const point2d& 00299 p_line2d::operator[](unsigned i) const 00300 { 00301 mln_precondition(i < nsites()); 00302 return arr_[i]; 00303 } 00304 00305 inline 00306 const point2d& 00307 p_line2d::begin() const 00308 { 00309 mln_precondition(is_valid()); 00310 return arr_[0]; 00311 } 00312 00313 inline 00314 const point2d& 00315 p_line2d::end() const 00316 { 00317 mln_precondition(is_valid()); 00318 return arr_[nsites() - 1]; 00319 } 00320 00321 inline 00322 std::size_t 00323 p_line2d::memory_size() const 00324 { 00325 return arr_.memory_size() + sizeof(box2d); 00326 } 00327 00328 00329 namespace trait 00330 { 00331 00332 inline 00333 bool 00334 set_precise_unary_< op::ord, p_line2d >::strict(const p_line2d& lhs, 00335 const p_line2d& rhs) const 00336 { 00337 return util::ord_lexi_strict(lhs.begin(), lhs.end(), 00338 rhs.begin(), rhs.end()); 00339 } 00340 00341 } // end of namespace mln::trait 00342 00343 # endif // ! MLN_INCLUDE_ONLY 00344 00345 } // end of namespace mln 00346 00347 00348 #endif // ! MLN_CORE_SITE_SET_P_LINE2D_HH