X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fmath%2FSGVec3.hxx;h=4ec4145a399f005a05ab88d85d1271f2cb919488;hb=006f90997a8eef6704de2511e38fcc786672308d;hp=d9d998dfd4de0e158db233f0199e48314e805f9f;hpb=67d837c4ec71e21c9d52914344b4dafb7fc06b45;p=simgear.git diff --git a/simgear/math/SGVec3.hxx b/simgear/math/SGVec3.hxx index d9d998df..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 @@ -364,18 +378,29 @@ cross(const SGVec3& v1, const SGVec3& v2) v1(0)*v2(1) - v1(1)*v2(0)); } -/// return any vector perpandicular to v +/// return any normalized vector perpendicular to v template inline SGVec3 -perpandicular(const SGVec3& v) +perpendicular(const SGVec3& v) { - if (fabs(v.x()) < fabs(v.y()) && fabs(v.x()) < fabs(v.z())) - return cross(SGVec3f(1, 0, 0), v); - else if (fabs(v.y()) < fabs(v.x()) && fabs(v.y()) < fabs(v.z())) - return cross(SGVec3f(0, 1, 0), v); - else - return cross(SGVec3f(0, 0, 1), 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 @@ -399,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