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
00028 #ifndef OLENA_CORE_FPOINT2D_HH
00029 # define OLENA_CORE_FPOINT2D_HH
00030
00031 # include <iostream>
00032
00033 # include <oln/core/image2d.hh>
00034 # include <oln/core/abstract/image.hh>
00035 # include <oln/core/point2d.hh>
00036
00037 namespace oln {
00038
00039
00040
00041 template <class F>
00042 class fpoint2d;
00043
00044 template <class F>
00045 class fdpoint2d;
00046
00052 template<class F>
00053 struct point_traits<fpoint2d<F> >
00054 {
00055 enum { dim = 2 };
00056 typedef fdpoint2d<F> dpoint_type;
00057 };
00058
00064 template <class F>
00065 class fpoint2d
00066 {
00067 private:
00068
00069 F coord_[2];
00070
00071 public:
00072
00073 typedef fpoint2d<F> exact_type;
00074 typedef fpoint2d<F> self_type;
00075 typedef fdpoint2d<F> dpoint_type;
00076
00077 fpoint2d(F x, F y)
00078 {
00079 coord_[0] = x;
00080 coord_[1] = y;
00081 }
00082
00083 fpoint2d()
00084 {}
00085
00087
00088 F
00089 row() const
00090 {
00091 return coord_[0];
00092 }
00093
00094 F&
00095 row()
00096 {
00097 return coord_[0];
00098 }
00099
00100 F
00101 col() const
00102 {
00103 return coord_[1];
00104 }
00105
00106 F&
00107 col()
00108 {
00109 return coord_[1];
00110 }
00111
00112 F
00113 nth(const unsigned dim) const
00114 {
00115 assert(dim < 2);
00116 return coord_[dim];
00117 }
00118
00120
00121 F&
00122 nth(const unsigned dim)
00123 {
00124 assert(dim < 2);
00125 return coord_[dim];
00126 }
00127
00128 exact_type
00129 operator-() const
00130 {
00131 return exact_type(-coord_[0], -coord_[1]);
00132 }
00133
00134 exact_type&
00135 operator+=(const dpoint_type& dp)
00136 {
00137 row() += dp.row();
00138 col() += dp.col();
00139 return *this;
00140 }
00141
00142 exact_type&
00143 operator-=(const dpoint_type& dp)
00144 {
00145 row() += dp.row();
00146 col() += dp.col();
00147 return *this;
00148 }
00149
00150 dpoint_type
00151 operator-(const self_type& p) const
00152 {
00153 dpoint_type dp(row() - p.row(), col() - p.col());
00154 return dp;
00155 }
00156
00157
00158 exact_type
00159 operator-(const dpoint_type& dp) const
00160 {
00161 exact_type p = *this;
00162 p += dp;
00163 return p;
00164 }
00165
00166 dpoint_type
00167 operator+(const self_type& p) const
00168 {
00169 dpoint_type dp(row() + p.row(), col() + p.col());
00170 return dp;
00171 }
00172
00173 exact_type
00174 operator+(const dpoint_type& dp) const
00175 {
00176 exact_type p = *this;
00177 p -= dp;
00178 return p;
00179 }
00180
00181
00188 bool
00189 operator==(const self_type& p) const
00190 {
00191 return p.nth(0) == coord_[0] && p.nth(1) == coord_[1];
00192 }
00193
00194
00202 bool
00203 operator!=(const self_type& p) const
00204 {
00205 return !(p.nth(0) == coord_[0] && p.nth(1) == coord_[1]);
00206 }
00207
00208
00209
00210 };
00211
00212 template <class T>
00213 struct func_traits
00214 {
00215 };
00216
00217 template <class T, class F>
00218 struct nearest;
00219
00220 template <class T, class F>
00221 struct bilinear;
00222
00223 template <class T, class F>
00224 struct func_traits<nearest<T, F> >
00225 {
00226 typedef F f_type;
00227 };
00228
00229 template <class T, class F>
00230 struct func_traits<bilinear<T, F> >
00231 {
00232 typedef F f_type;
00233 };
00234
00235 template <class T, class Exact>
00236 struct fpoint2d_access
00237 {
00238
00239 typedef typename func_traits<Exact>::f_type f_type;
00240
00241 const T operator()(const image2d<T> &ima, const fpoint2d<f_type> p) const
00242 {
00243 return (static_cast<const Exact *>(this))->access_impl(ima, p);
00244 }
00245
00246 };
00247
00248
00249 template <class T, class F>
00250 struct nearest : public fpoint2d_access<T, nearest<T, F> >
00251 {
00252
00253 const T access_impl(const image2d<T> &ima, const fpoint2d<F> p) const
00254 {
00255
00256 point2d p2d(int(p.nth(0)), int(p.nth(1)));
00257
00258 if (ima.hold(p2d))
00259 return ima[p2d];
00260 else
00261 return ntg::rgb_8(255, 255, 255);
00262 }
00263
00264 };
00265
00266 template <class T, class F>
00267 struct bilinear : public fpoint2d_access<T, bilinear<T, F> >
00268 {
00269
00270 const T access_impl(const image2d<T> &ima, const fpoint2d<F> p) const
00271 {
00272 double x = floorf(p.nth(0));
00273 double y = floorf(p.nth(1));
00274
00275 int a = int(x);
00276 int b = int(y);
00277
00278
00279 if (ima.hold(point2d(a, b)) && ima.hold(point2d(a + 1, b + 1)))
00280 {
00281 int res[3];
00282
00283 res[0] = int((double(ima(a, b)[0]) * (x + 1 - p.nth(0)) +
00284 double(ima(a + 1, b)[0]) * (p.nth(0) - x)) * (y + 1 - p.nth(1)) +
00285 (double(ima(a, b + 1)[0]) * (p.nth(0) - x) +
00286 double(ima(a + 1, b + 1)[0]) * (x + 1 - p.nth(0))) * (p.nth(1) - y));
00287 res[1] = int((double(ima(a, b)[1]) * (x + 1 - p.nth(0)) +
00288 double(ima(a + 1, b)[1]) * (p.nth(0) - x)) * (y + 1 - p.nth(1)) +
00289 (double(ima(a, b + 1)[1]) * (p.nth(0) - x) +
00290 double(ima(a + 1, b + 1)[1]) * (x + 1 - p.nth(0))) * (p.nth(1) - y));
00291 res[2] = int((double(ima(a, b)[2]) * (x + 1 - p.nth(0)) +
00292 double(ima(a + 1, b)[2]) * (p.nth(0) - x)) * (y + 1 - p.nth(1)) +
00293 (double(ima(a, b + 1)[2]) * (p.nth(0) - x) +
00294 double(ima(a + 1, b + 1)[2]) * (x + 1 - p.nth(0))) * (p.nth(1) - y));
00295 return ntg::rgb_8(res[0], res[1], res[2]);
00296 }
00297 else if (ima.hold(point2d(a, b)))
00298 return ima(a, b);
00299 else
00300 return ntg::rgb_8(255, 255, 255);
00301 }
00302
00303 };
00304
00305
00306 }
00307
00308
00310
00311 template <class F>
00312 inline std::ostream&
00313 operator<<(std::ostream& o, const oln::fpoint2d<F>& p)
00314 {
00315 return o << '(' << p.nth(0) << ',' << p.nth(1) << ')';
00316 }
00317
00318
00319
00320
00321
00322 #endif // ! OLENA_CORE_FPOINT2D_HH