From 4f802689f23456e7db7920aeb690516b7a3f399e Mon Sep 17 00:00:00 2001 From: frohlich Date: Wed, 16 Sep 2009 05:06:56 +0000 Subject: [PATCH] Correct finite precision issues. Use consistent function names. Implement changes consistently over the different vector sizes. Modified Files: SGVec2.hxx SGVec3.hxx SGVec4.hxx --- simgear/math/SGVec2.hxx | 19 ++++++++++++++++++- simgear/math/SGVec3.hxx | 29 +++++++++++++++++------------ simgear/math/SGVec4.hxx | 19 ++++++++++++++++++- 3 files changed, 53 insertions(+), 14 deletions(-) diff --git a/simgear/math/SGVec2.hxx b/simgear/math/SGVec2.hxx index 5024e2c1..65c802ea 100644 --- a/simgear/math/SGVec2.hxx +++ b/simgear/math/SGVec2.hxx @@ -244,7 +244,12 @@ 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 @@ -331,6 +336,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 diff --git a/simgear/math/SGVec3.hxx b/simgear/math/SGVec3.hxx index 9b81ec57..64ceac0a 100644 --- a/simgear/math/SGVec3.hxx +++ b/simgear/math/SGVec3.hxx @@ -358,9 +358,11 @@ template inline SGVec3 normalize(const SGVec3& v) -{ T normv = norm(v); - if (normv > 0.0) return (1/norm(v))*v; - else return v; +{ + T normv = norm(v); + if (normv <= SGLimits::min()) + return SGVec3::zeros(); + return (1/normv)*v; } /// Return true if exactly the same @@ -452,6 +454,18 @@ T distSqr(const SGVec3& v1, const SGVec3& v2) { SGVec3 tmp = v1 - v2; return dot(tmp, tmp); } +// calculate the projection of u along the direction of d. +template +inline +SGVec3 +projection(const SGVec3& u, const SGVec3& 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 @@ -480,15 +494,6 @@ SGVec3d toVec3d(const SGVec3f& v) { return SGVec3d(v(0), v(1), v(2)); } -// calculate the projection of u along the direction of d. -template -inline SGVec3 SGProjection(const SGVec3& u, const SGVec3& d) -{ - T denom = dot(d, d); - if (denom == 0.) return u; - else return d * (dot(u,d) / denom); -} - #ifndef NO_OPENSCENEGRAPH_INTERFACE inline SGVec3d diff --git a/simgear/math/SGVec4.hxx b/simgear/math/SGVec4.hxx index baf9137d..6030c48b 100644 --- a/simgear/math/SGVec4.hxx +++ b/simgear/math/SGVec4.hxx @@ -288,7 +288,12 @@ template inline SGVec4 normalize(const SGVec4& v) -{ return (1/norm(v))*v; } +{ + T normv = norm(v); + if (normv <= SGLimits::min()) + return SGVec4::zeros(); + return (1/normv)*v; +} /// Return true if exactly the same template @@ -383,6 +388,18 @@ T distSqr(const SGVec4& v1, const SGVec4& v2) { SGVec4 tmp = v1 - v2; return dot(tmp, tmp); } +// calculate the projection of u along the direction of d. +template +inline +SGVec4 +projection(const SGVec4& u, const SGVec4& 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 -- 2.39.5