00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef SGVec2_H
00019 #define SGVec2_H
00020
00021 #ifndef NO_OPENSCENEGRAPH_INTERFACE
00022 #include <osg/Vec2f>
00023 #include <osg/Vec2d>
00024 #endif
00025
00027 template<typename T>
00028 class SGVec2 {
00029 public:
00030 typedef T value_type;
00031
00034 SGVec2(void)
00035 {
00039 #ifndef NDEBUG
00040 for (unsigned i = 0; i < 2; ++i)
00041 data()[i] = SGLimits<T>::quiet_NaN();
00042 #endif
00043 }
00045 SGVec2(T x, T y)
00046 { data()[0] = x; data()[1] = y; }
00049 explicit SGVec2(const T* d)
00050 { data()[0] = d[0]; data()[1] = d[1]; }
00051 template<typename S>
00052 explicit SGVec2(const SGVec2<S>& d)
00053 { data()[0] = d[0]; data()[1] = d[1]; }
00054
00056 const T& operator()(unsigned i) const
00057 { return data()[i]; }
00059 T& operator()(unsigned i)
00060 { return data()[i]; }
00061
00063 const T& operator[](unsigned i) const
00064 { return data()[i]; }
00066 T& operator[](unsigned i)
00067 { return data()[i]; }
00068
00070 const T& x(void) const
00071 { return data()[0]; }
00073 T& x(void)
00074 { return data()[0]; }
00076 const T& y(void) const
00077 { return data()[1]; }
00079 T& y(void)
00080 { return data()[1]; }
00081
00083 const T (&data(void) const)[2]
00084 { return _data; }
00086 T (&data(void))[2]
00087 { return _data; }
00088
00090 SGVec2& operator+=(const SGVec2& v)
00091 { data()[0] += v(0); data()[1] += v(1); return *this; }
00093 SGVec2& operator-=(const SGVec2& v)
00094 { data()[0] -= v(0); data()[1] -= v(1); return *this; }
00096 template<typename S>
00097 SGVec2& operator*=(S s)
00098 { data()[0] *= s; data()[1] *= s; return *this; }
00100 template<typename S>
00101 SGVec2& operator/=(S s)
00102 { return operator*=(1/T(s)); }
00103
00105 static SGVec2 zeros(void)
00106 { return SGVec2(0, 0); }
00108 static SGVec2 e1(void)
00109 { return SGVec2(1, 0); }
00110 static SGVec2 e2(void)
00111 { return SGVec2(0, 1); }
00112
00113 private:
00114 T _data[2];
00115 };
00116
00118 template<typename T>
00119 inline
00120 const SGVec2<T>&
00121 operator+(const SGVec2<T>& v)
00122 { return v; }
00123
00125 template<typename T>
00126 inline
00127 SGVec2<T>
00128 operator-(const SGVec2<T>& v)
00129 { return SGVec2<T>(-v(0), -v(1)); }
00130
00132 template<typename T>
00133 inline
00134 SGVec2<T>
00135 operator+(const SGVec2<T>& v1, const SGVec2<T>& v2)
00136 { return SGVec2<T>(v1(0)+v2(0), v1(1)+v2(1)); }
00137
00139 template<typename T>
00140 inline
00141 SGVec2<T>
00142 operator-(const SGVec2<T>& v1, const SGVec2<T>& v2)
00143 { return SGVec2<T>(v1(0)-v2(0), v1(1)-v2(1)); }
00144
00146 template<typename S, typename T>
00147 inline
00148 SGVec2<T>
00149 operator*(S s, const SGVec2<T>& v)
00150 { return SGVec2<T>(s*v(0), s*v(1)); }
00151
00153 template<typename S, typename T>
00154 inline
00155 SGVec2<T>
00156 operator*(const SGVec2<T>& v, S s)
00157 { return SGVec2<T>(s*v(0), s*v(1)); }
00158
00162 template<typename T>
00163 inline
00164 SGVec2<T>
00165 mult(const SGVec2<T>& v1, const SGVec2<T>& v2)
00166 { return SGVec2<T>(v1(0)*v2(0), v1(1)*v2(1)); }
00167
00169 template<typename T>
00170 inline
00171 SGVec2<T>
00172 min(const SGVec2<T>& v1, const SGVec2<T>& v2)
00173 {return SGVec2<T>(SGMisc<T>::min(v1(0), v2(0)), SGMisc<T>::min(v1(1), v2(1)));}
00174 template<typename S, typename T>
00175 inline
00176 SGVec2<T>
00177 min(const SGVec2<T>& v, S s)
00178 { return SGVec2<T>(SGMisc<T>::min(s, v(0)), SGMisc<T>::min(s, v(1))); }
00179 template<typename S, typename T>
00180 inline
00181 SGVec2<T>
00182 min(S s, const SGVec2<T>& v)
00183 { return SGVec2<T>(SGMisc<T>::min(s, v(0)), SGMisc<T>::min(s, v(1))); }
00184
00186 template<typename T>
00187 inline
00188 SGVec2<T>
00189 max(const SGVec2<T>& v1, const SGVec2<T>& v2)
00190 {return SGVec2<T>(SGMisc<T>::max(v1(0), v2(0)), SGMisc<T>::max(v1(1), v2(1)));}
00191 template<typename S, typename T>
00192 inline
00193 SGVec2<T>
00194 max(const SGVec2<T>& v, S s)
00195 { return SGVec2<T>(SGMisc<T>::max(s, v(0)), SGMisc<T>::max(s, v(1))); }
00196 template<typename S, typename T>
00197 inline
00198 SGVec2<T>
00199 max(S s, const SGVec2<T>& v)
00200 { return SGVec2<T>(SGMisc<T>::max(s, v(0)), SGMisc<T>::max(s, v(1))); }
00201
00203 template<typename T>
00204 inline
00205 T
00206 dot(const SGVec2<T>& v1, const SGVec2<T>& v2)
00207 { return v1(0)*v2(0) + v1(1)*v2(1); }
00208
00210 template<typename T>
00211 inline
00212 T
00213 norm(const SGVec2<T>& v)
00214 { return sqrt(dot(v, v)); }
00215
00217 template<typename T>
00218 inline
00219 T
00220 length(const SGVec2<T>& v)
00221 { return sqrt(dot(v, v)); }
00222
00225 template<typename T>
00226 inline
00227 T
00228 norm1(const SGVec2<T>& v)
00229 { return fabs(v(0)) + fabs(v(1)); }
00230
00232 template<typename T>
00233 inline
00234 T
00235 normI(const SGVec2<T>& v)
00236 { return SGMisc<T>::max(fabs(v(0)), fabs(v(1))); }
00237
00239 template<typename T>
00240 inline
00241 SGVec2<T>
00242 normalize(const SGVec2<T>& v)
00243 {
00244 T normv = norm(v);
00245 if (normv <= SGLimits<T>::min())
00246 return SGVec2<T>::zeros();
00247 return (1/normv)*v;
00248 }
00249
00251 template<typename T>
00252 inline
00253 bool
00254 operator==(const SGVec2<T>& v1, const SGVec2<T>& v2)
00255 { return v1(0) == v2(0) && v1(1) == v2(1); }
00256
00258 template<typename T>
00259 inline
00260 bool
00261 operator!=(const SGVec2<T>& v1, const SGVec2<T>& v2)
00262 { return ! (v1 == v2); }
00263
00265 template<typename T>
00266 inline
00267 bool
00268 operator<(const SGVec2<T>& v1, const SGVec2<T>& v2)
00269 {
00270 if (v1(0) < v2(0)) return true;
00271 else if (v2(0) < v1(0)) return false;
00272 else return (v1(1) < v2(1));
00273 }
00274
00275 template<typename T>
00276 inline
00277 bool
00278 operator<=(const SGVec2<T>& v1, const SGVec2<T>& v2)
00279 {
00280 if (v1(0) < v2(0)) return true;
00281 else if (v2(0) < v1(0)) return false;
00282 else return (v1(1) <= v2(1));
00283 }
00284
00285 template<typename T>
00286 inline
00287 bool
00288 operator>(const SGVec2<T>& v1, const SGVec2<T>& v2)
00289 { return operator<(v2, v1); }
00290
00291 template<typename T>
00292 inline
00293 bool
00294 operator>=(const SGVec2<T>& v1, const SGVec2<T>& v2)
00295 { return operator<=(v2, v1); }
00296
00298 template<typename T>
00299 inline
00300 bool
00301 equivalent(const SGVec2<T>& v1, const SGVec2<T>& v2, T rtol, T atol)
00302 { return norm1(v1 - v2) < rtol*(norm1(v1) + norm1(v2)) + atol; }
00303
00305 template<typename T>
00306 inline
00307 bool
00308 equivalent(const SGVec2<T>& v1, const SGVec2<T>& v2, T rtol)
00309 { return norm1(v1 - v2) < rtol*(norm1(v1) + norm1(v2)); }
00310
00312 template<typename T>
00313 inline
00314 bool
00315 equivalent(const SGVec2<T>& v1, const SGVec2<T>& v2)
00316 {
00317 T tol = 100*SGLimits<T>::epsilon();
00318 return equivalent(v1, v2, tol, tol);
00319 }
00320
00322 template<typename T>
00323 inline
00324 T
00325 dist(const SGVec2<T>& v1, const SGVec2<T>& v2)
00326 { return norm(v1 - v2); }
00327
00329 template<typename T>
00330 inline
00331 T
00332 distSqr(const SGVec2<T>& v1, const SGVec2<T>& v2)
00333 { SGVec2<T> tmp = v1 - v2; return dot(tmp, tmp); }
00334
00335
00336 template<typename T>
00337 inline
00338 SGVec2<T>
00339 projection(const SGVec2<T>& u, const SGVec2<T>& d)
00340 {
00341 T denom = dot(d, d);
00342 T ud = dot(u, d);
00343 if (SGLimits<T>::min() < denom) return u;
00344 else return d * (dot(u, d) / denom);
00345 }
00346
00347 #ifndef NDEBUG
00348 template<typename T>
00349 inline
00350 bool
00351 isNaN(const SGVec2<T>& v)
00352 {
00353 return SGMisc<T>::isNaN(v(0)) || SGMisc<T>::isNaN(v(1));
00354 }
00355 #endif
00356
00358 template<typename char_type, typename traits_type, typename T>
00359 inline
00360 std::basic_ostream<char_type, traits_type>&
00361 operator<<(std::basic_ostream<char_type, traits_type>& s, const SGVec2<T>& v)
00362 { return s << "[ " << v(0) << ", " << v(1) << " ]"; }
00363
00364 inline
00365 SGVec2f
00366 toVec2f(const SGVec2d& v)
00367 { return SGVec2f((float)v(0), (float)v(1)); }
00368
00369 inline
00370 SGVec2d
00371 toVec2d(const SGVec2f& v)
00372 { return SGVec2d(v(0), v(1)); }
00373
00374 #ifndef NO_OPENSCENEGRAPH_INTERFACE
00375 inline
00376 SGVec2d
00377 toSG(const osg::Vec2d& v)
00378 { return SGVec2d(v[0], v[1]); }
00379
00380 inline
00381 SGVec2f
00382 toSG(const osg::Vec2f& v)
00383 { return SGVec2f(v[0], v[1]); }
00384
00385 inline
00386 osg::Vec2d
00387 toOsg(const SGVec2d& v)
00388 { return osg::Vec2d(v[0], v[1]); }
00389
00390 inline
00391 osg::Vec2f
00392 toOsg(const SGVec2f& v)
00393 { return osg::Vec2f(v[0], v[1]); }
00394
00395 #endif
00396
00397 #endif