From d55c28d057d9109a3791c9440e9f6e7dd3541dcc Mon Sep 17 00:00:00 2001
From: Andreas Schenk <andreas_schenk@hms.harvard.edu>
Date: Tue, 3 Jan 2012 16:24:47 -0500
Subject: [PATCH] some fixes in Quat and Rotation3 / added basic unit tests for
 Rotation3 and Quat

---
 modules/geom/pymod/export_quat.cc     |  1 -
 modules/geom/src/composite3.cc        |  5 +--
 modules/geom/src/quat.cc              | 20 +--------
 modules/geom/src/quat.hh              |  2 -
 modules/geom/tests/CMakeLists.txt     |  1 +
 modules/geom/tests/test_composite3.cc | 11 +++++
 modules/geom/tests/test_quat.cc       | 58 +++++++++++++++++++++++++++
 7 files changed, 72 insertions(+), 26 deletions(-)
 create mode 100644 modules/geom/tests/test_quat.cc

diff --git a/modules/geom/pymod/export_quat.cc b/modules/geom/pymod/export_quat.cc
index 4e136ea8e..7e233f69c 100644
--- a/modules/geom/pymod/export_quat.cc
+++ b/modules/geom/pymod/export_quat.cc
@@ -59,7 +59,6 @@ void export_Quat()
   ;
   def("Conjugate",&Conjugate);
   def("Slerp",&Slerp);
-  def("Grassman",&Grassmann);
   def("Normalize",normalize);
 }
 
diff --git a/modules/geom/src/composite3.cc b/modules/geom/src/composite3.cc
index 751901b30..347629d2c 100644
--- a/modules/geom/src/composite3.cc
+++ b/modules/geom/src/composite3.cc
@@ -266,10 +266,7 @@ void Rotation3::SetRotationMatrix(const Mat3& rot)
 }
 Vec3 Rotation3::Apply(const Vec3& v) const
 {
-  // We can use Conjugate instead of Invert because q is guaranteed to
-  // be unit Quat
-  return origin_+(Grassmann(Grassmann(q_,Quat(0,v-origin_)),
-                            Conjugate(q_))).GetAxis();
+  return origin_+q_.Rotate(v-origin_);
 }
 
 bool Rotation3::operator==(const Rotation3& rhs) const
diff --git a/modules/geom/src/quat.cc b/modules/geom/src/quat.cc
index f9b852cae..44e39ee2b 100644
--- a/modules/geom/src/quat.cc
+++ b/modules/geom/src/quat.cc
@@ -455,30 +455,12 @@ Quat Log(const Quat& q)
 
 Vec3 Quat::Rotate(const Vec3& vec) const {
   Quat tmp(0.0, vec[0], vec[1], vec[2]);
+  // We use Conjugate instead of Invert here because we assume *this to be normalized
   Quat conj=Conjugate(*this);
   Quat res=*this*tmp*conj;
   return Vec3(res.x, res.y, res.z);
 }
 
-Quat Grassmann(const Quat& lhs, const Quat& rhs)
-{
-  return Quat(lhs.GetAngle()*rhs.GetAngle()-
-              lhs.GetAxis().x*rhs.GetAxis().x-
-              lhs.GetAxis().y*rhs.GetAxis().y-
-              lhs.GetAxis().z*rhs.GetAxis().z,
-                    lhs.GetAngle()*rhs.GetAxis().x+
-                    lhs.GetAxis().x*rhs.GetAngle()+
-                    lhs.GetAxis().y*rhs.GetAxis().z-
-                    lhs.GetAxis().z*rhs.GetAxis().y,
-               lhs.GetAngle()*rhs.GetAxis().y-
-               lhs.GetAxis().x*rhs.GetAxis().z+
-               lhs.GetAxis().y*rhs.GetAngle()+
-               lhs.GetAxis().z*rhs.GetAxis().x,
-                    lhs.GetAngle()*rhs.GetAxis().z+
-                    lhs.GetAxis().x*rhs.GetAxis().y-
-                    lhs.GetAxis().y*rhs.GetAxis().x+
-                    lhs.GetAxis().z*rhs.GetAngle());
-}
 
 std::ostream& operator<<(std::ostream& str, const Quat& q)
 {
diff --git a/modules/geom/src/quat.hh b/modules/geom/src/quat.hh
index dc206e4e5..881f69b5b 100644
--- a/modules/geom/src/quat.hh
+++ b/modules/geom/src/quat.hh
@@ -116,8 +116,6 @@ Quat DLLEXPORT_OST_GEOM Inv(const Quat& q);
 Quat DLLEXPORT_OST_GEOM Exp(const Quat& q);
 Quat DLLEXPORT_OST_GEOM Log(const Quat& q);
 
-Quat DLLEXPORT_OST_GEOM Grassmann(const Quat& lhs, const Quat& rhs);
-
 //normalize quaternion
 Quat DLLEXPORT_OST_GEOM Normalize(const Quat& q);
 
diff --git a/modules/geom/tests/CMakeLists.txt b/modules/geom/tests/CMakeLists.txt
index 42d7f4c43..027a16749 100644
--- a/modules/geom/tests/CMakeLists.txt
+++ b/modules/geom/tests/CMakeLists.txt
@@ -7,6 +7,7 @@ set(GEOM_UNITTESTS
   test_op2.cc
   test_op3.cc
   test_op4.cc
+  test_quat.cc
   test_vec2.cc
   test_vec3.cc
   test_vec4.cc
diff --git a/modules/geom/tests/test_composite3.cc b/modules/geom/tests/test_composite3.cc
index 6548b53da..5602df4dd 100644
--- a/modules/geom/tests/test_composite3.cc
+++ b/modules/geom/tests/test_composite3.cc
@@ -17,6 +17,7 @@
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 //------------------------------------------------------------------------------
 
+#include <cmath>
 #include <ost/geom/geom.hh>
 
 #include "helper.hh"
@@ -193,4 +194,14 @@ BOOST_AUTO_TEST_CASE(func_composite3)
 
 }
 
+BOOST_AUTO_TEST_CASE(rotation3)
+{
+  Vec3 v(1,0,0);
+  Rotation3 r(Vec3(0,1,0), 30.0*M_PI/180.0);
+  Vec3 vrot=r.Apply(v);
+  BOOST_CHECK_CLOSE(cos(30.0*M_PI/180.0),vrot[0],float(1e-5));
+  BOOST_CHECK_SMALL(vrot[1],float(1e-5));
+  BOOST_CHECK_CLOSE(-sin(30.0*M_PI/180.0),vrot[2],float(1e-5));
+}
+
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/modules/geom/tests/test_quat.cc b/modules/geom/tests/test_quat.cc
new file mode 100644
index 000000000..0869fd518
--- /dev/null
+++ b/modules/geom/tests/test_quat.cc
@@ -0,0 +1,58 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2011 by the OpenStructure authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//------------------------------------------------------------------------------
+
+#include <ost/geom/geom.hh>
+
+#include "helper.hh"
+using namespace geom;
+
+#define BOOST_TEST_DYN_LINK
+#include <boost/test/unit_test.hpp>
+
+BOOST_AUTO_TEST_SUITE( geom )
+
+BOOST_AUTO_TEST_CASE(init_quat)
+{
+  // default
+  Quat q1;
+  BOOST_CHECK_CLOSE(q1.w,1.0,1.0e-5);
+  BOOST_CHECK_CLOSE(q1.x,0.0,1.0e-5);
+  BOOST_CHECK_CLOSE(q1.y,0.0,1.0e-5);
+  BOOST_CHECK_CLOSE(q1.z,0.0,1.0e-5);
+
+  Quat q2(2.0,3.0,4.0,5.0);
+  BOOST_CHECK_CLOSE(q2.w,2.0,1.0e-5);
+  BOOST_CHECK_CLOSE(q2.x,3.0,1.0e-5);
+  BOOST_CHECK_CLOSE(q2.y,4.0,1.0e-5);
+  BOOST_CHECK_CLOSE(q2.z,5.0,1.0e-5);
+}
+
+BOOST_AUTO_TEST_CASE(quat_rotate)
+{
+  Vec3 v(1,0,0);
+  Quat q(30.0*M_PI/180.0,Vec3(0,1,0));
+  Vec3 vrot=q.Rotate(v);
+  BOOST_CHECK_CLOSE(cos(30.0*M_PI/180.0),vrot[0],float(1e-5));
+  BOOST_CHECK_SMALL(vrot[1],float(1e-5));
+  BOOST_CHECK_CLOSE(-sin(30.0*M_PI/180.0),vrot[2],float(1e-5));
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
-- 
GitLab