X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fmath%2FSGVec3.hxx;h=4ec4145a399f005a05ab88d85d1271f2cb919488;hb=006f90997a8eef6704de2511e38fcc786672308d;hp=df742744373d7fb472527403d3c4ee95b9df00b2;hpb=3059da5805f53c0cb940b26638ef9f0467d3277b;p=simgear.git diff --git a/simgear/math/SGVec3.hxx b/simgear/math/SGVec3.hxx index df742744..4ec4145a 100644 --- a/simgear/math/SGVec3.hxx +++ b/simgear/math/SGVec3.hxx @@ -92,10 +92,15 @@ public: /// make sure it has at least 3 elements explicit SGVec3(const T* d) { data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; } + template + explicit SGVec3(const SGVec3& d) + { data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; } explicit SGVec3(const osg::Vec3f& d) { data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; } explicit SGVec3(const osg::Vec3d& d) { data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; } + explicit SGVec3(const SGVec2& v2, const T& v3 = 0) + { data()[0] = v2[0]; data()[1] = v2[1]; data()[2] = v3; } /// Access by index, the index is unchecked const T& operator()(unsigned i) const @@ -259,6 +264,15 @@ SGVec3 operator*(const SGVec3& v, S s) { return SGVec3(s*v(0), s*v(1), s*v(2)); } +/// multiplication as a multiplicator, that is assume that the first vector +/// represents a 3x3 diagonal matrix with the diagonal elements in the vector. +/// Then the result is the product of that matrix times the second vector. +template +inline +SGVec3 +mult(const SGVec3& v1, const SGVec3& v2) +{ return SGVec3(v1(0)*v2(0), v1(1)*v2(1), v1(2)*v2(2)); } + /// component wise min template inline @@ -346,6 +360,13 @@ T norm1(const SGVec3& v) { return fabs(v(0)) + fabs(v(1)) + fabs(v(2)); } +/// The inf-norm of the vector +template +inline +T +normI(const SGVec3& v) +{ return SGMisc::max(fabs(v(0)), fabs(v(1)), fabs(v(2))); } + /// Vector cross product template inline @@ -357,6 +378,31 @@ cross(const SGVec3& v1, const SGVec3& v2) v1(0)*v2(1) - v1(1)*v2(0)); } +/// return any normalized vector perpendicular to v +template +inline +SGVec3 +perpendicular(const SGVec3& v) +{ + T absv1 = fabs(v(0)); + T absv2 = fabs(v(1)); + T absv3 = fabs(v(2)); + + if (absv2 < absv1 && absv3 < absv1) { + T quot = v(1)/v(0); + return (1/sqrt(1+quot*quot))*SGVec3(quot, -1, 0); + } else if (absv3 < absv2) { + T quot = v(2)/v(1); + return (1/sqrt(1+quot*quot))*SGVec3(0, quot, -1); + } else if (SGLimits::min() < absv3) { + T quot = v(0)/v(2); + return (1/sqrt(1+quot*quot))*SGVec3(-1, 0, quot); + } else { + // the all zero case ... + return SGVec3(0, 0, 0); + } +} + /// The euclidean norm of the vector, that is what most people call length template inline @@ -378,6 +424,43 @@ bool operator!=(const SGVec3& v1, const SGVec3& v2) { return ! (v1 == v2); } +/// Return true if smaller, good for putting that into a std::map +template +inline +bool +operator<(const SGVec3& v1, const SGVec3& v2) +{ + if (v1(0) < v2(0)) return true; + else if (v2(0) < v1(0)) return false; + else if (v1(1) < v2(1)) return true; + else if (v2(1) < v1(1)) return false; + else return (v1(2) < v2(2)); +} + +template +inline +bool +operator<=(const SGVec3& v1, const SGVec3& v2) +{ + if (v1(0) < v2(0)) return true; + else if (v2(0) < v1(0)) return false; + else if (v1(1) < v2(1)) return true; + else if (v2(1) < v1(1)) return false; + else return (v1(2) <= v2(2)); +} + +template +inline +bool +operator>(const SGVec3& v1, const SGVec3& v2) +{ return operator<(v2, v1); } + +template +inline +bool +operator>=(const SGVec3& v1, const SGVec3& v2) +{ return operator<=(v2, v1); } + /// Return true if equal to the relative tolerance tol template inline