X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fmath%2FSGVec2.hxx;h=0695cded19f232e7cc14b698e2f1c6892be2e0fe;hb=914d3e6a2b323cf9f186cbef2aef7865ea07b309;hp=2b539b848c356e60c332b980e02cbaca9b1a0179;hpb=5127e2f89c915f3441c4ba1a777d94c344f33e7e;p=simgear.git diff --git a/simgear/math/SGVec2.hxx b/simgear/math/SGVec2.hxx index 2b539b84..0695cded 100644 --- a/simgear/math/SGVec2.hxx +++ b/simgear/math/SGVec2.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2006 Mathias Froehlich - Mathias.Froehlich@web.de +// Copyright (C) 2006-2009 Mathias Froehlich - Mathias.Froehlich@web.de // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Library General Public @@ -18,58 +18,11 @@ #ifndef SGVec2_H #define SGVec2_H -#include -#include - -template -struct SGVec2Storage { - /// Readonly raw storage interface - const T (&data(void) const)[2] - { return _data; } - /// Readonly raw storage interface - T (&data(void))[2] - { return _data; } - - void osg() const - { } - -private: - T _data[2]; -}; - -template<> -struct SGVec2Storage : public osg::Vec2f { - /// Access raw data by index, the index is unchecked - const float (&data(void) const)[2] - { return osg::Vec2f::_v; } - /// Access raw data by index, the index is unchecked - float (&data(void))[2] - { return osg::Vec2f::_v; } - - const osg::Vec2f& osg() const - { return *this; } - osg::Vec2f& osg() - { return *this; } -}; - -template<> -struct SGVec2Storage : public osg::Vec2d { - /// Access raw data by index, the index is unchecked - const double (&data(void) const)[2] - { return osg::Vec2d::_v; } - /// Access raw data by index, the index is unchecked - double (&data(void))[2] - { return osg::Vec2d::_v; } - - const osg::Vec2d& osg() const - { return *this; } - osg::Vec2d& osg() - { return *this; } -}; +#include /// 2D Vector Class template -class SGVec2 : protected SGVec2Storage { +class SGVec2 { public: typedef T value_type; @@ -92,9 +45,8 @@ public: /// make sure it has at least 2 elements explicit SGVec2(const T* d) { data()[0] = d[0]; data()[1] = d[1]; } - explicit SGVec2(const osg::Vec2f& d) - { data()[0] = d[0]; data()[1] = d[1]; } - explicit SGVec2(const osg::Vec2d& d) + template + explicit SGVec2(const SGVec2& d) { data()[0] = d[0]; data()[1] = d[1]; } /// Access by index, the index is unchecked @@ -124,18 +76,12 @@ public: T& y(void) { return data()[1]; } - /// Get the data pointer - using SGVec2Storage::data; - - /// Readonly interface function to ssg's sgVec2/sgdVec2 - const T (&sg(void) const)[2] - { return data(); } - /// Interface function to ssg's sgVec2/sgdVec2 - T (&sg(void))[2] - { return data(); } - - /// Interface function to osg's Vec2* - using SGVec2Storage::osg; + /// Access raw data + const T (&data(void) const)[2] + { return _data; } + /// Access raw data + T (&data(void))[2] + { return _data; } /// Inplace addition SGVec2& operator+=(const SGVec2& v) @@ -160,6 +106,9 @@ public: { return SGVec2(1, 0); } static SGVec2 e2(void) { return SGVec2(0, 1); } + +private: + T _data[2]; }; /// Unary +, do nothing ... @@ -204,6 +153,49 @@ SGVec2 operator*(const SGVec2& v, S s) { return SGVec2(s*v(0), s*v(1)); } +/// multiplication as a multiplicator, that is assume that the first vector +/// represents a 2x2 diagonal matrix with the diagonal elements in the vector. +/// Then the result is the product of that matrix times the second vector. +template +inline +SGVec2 +mult(const SGVec2& v1, const SGVec2& v2) +{ return SGVec2(v1(0)*v2(0), v1(1)*v2(1)); } + +/// component wise min +template +inline +SGVec2 +min(const SGVec2& v1, const SGVec2& v2) +{return SGVec2(SGMisc::min(v1(0), v2(0)), SGMisc::min(v1(1), v2(1)));} +template +inline +SGVec2 +min(const SGVec2& v, S s) +{ return SGVec2(SGMisc::min(s, v(0)), SGMisc::min(s, v(1))); } +template +inline +SGVec2 +min(S s, const SGVec2& v) +{ return SGVec2(SGMisc::min(s, v(0)), SGMisc::min(s, v(1))); } + +/// component wise max +template +inline +SGVec2 +max(const SGVec2& v1, const SGVec2& v2) +{return SGVec2(SGMisc::max(v1(0), v2(0)), SGMisc::max(v1(1), v2(1)));} +template +inline +SGVec2 +max(const SGVec2& v, S s) +{ return SGVec2(SGMisc::max(s, v(0)), SGMisc::max(s, v(1))); } +template +inline +SGVec2 +max(S s, const SGVec2& v) +{ return SGVec2(SGMisc::max(s, v(0)), SGMisc::max(s, v(1))); } + /// Scalar dot product template inline @@ -233,12 +225,24 @@ T norm1(const SGVec2& v) { return fabs(v(0)) + fabs(v(1)); } +/// The inf-norm of the vector +template +inline +T +normI(const SGVec2& v) +{ return SGMisc::max(fabs(v(0)), fabs(v(1))); } + /// The euclidean norm of the vector, that is what most people call length template inline SGVec2 normalize(const SGVec2& v) -{ return (1/norm(v))*v; } +{ + T normv = norm(v); + if (normv <= SGLimits::min()) + return SGVec2::zeros(); + return (1/normv)*v; +} /// Return true if exactly the same template @@ -254,6 +258,39 @@ bool operator!=(const SGVec2& v1, const SGVec2& v2) { return ! (v1 == v2); } +/// Return true if smaller, good for putting that into a std::map +template +inline +bool +operator<(const SGVec2& v1, const SGVec2& v2) +{ + if (v1(0) < v2(0)) return true; + else if (v2(0) < v1(0)) return false; + else return (v1(1) < v2(1)); +} + +template +inline +bool +operator<=(const SGVec2& v1, const SGVec2& v2) +{ + if (v1(0) < v2(0)) return true; + else if (v2(0) < v1(0)) return false; + else return (v1(1) <= v2(1)); +} + +template +inline +bool +operator>(const SGVec2& v1, const SGVec2& v2) +{ return operator<(v2, v1); } + +template +inline +bool +operator>=(const SGVec2& v1, const SGVec2& v2) +{ return operator<=(v2, v1); } + /// Return true if equal to the relative tolerance tol template inline @@ -292,6 +329,18 @@ T distSqr(const SGVec2& v1, const SGVec2& v2) { SGVec2 tmp = v1 - v2; return dot(tmp, tmp); } +// calculate the projection of u along the direction of d. +template +inline +SGVec2 +projection(const SGVec2& u, const SGVec2& d) +{ + T denom = dot(d, d); + T ud = dot(u, d); + if (SGLimits::min() < denom) return u; + else return d * (dot(u, d) / denom); +} + #ifndef NDEBUG template inline