diff --git a/Makefile.am b/Makefile.am
index 20c12607..5d264f4d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -87,6 +87,8 @@ UTIL_FILES = \
pool.cpp \
pool.hpp \
preprocessor.hpp \
+ quaternion.cpp \
+ quaternion.hpp \
raii.hpp \
random.cpp \
random.hpp \
diff --git a/quaternion.cpp b/quaternion.cpp
new file mode 100644
index 00000000..b675479a
--- /dev/null
+++ b/quaternion.cpp
@@ -0,0 +1,68 @@
+/*
+ * This file is part of libgim.
+ *
+ * libgim is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * libgim 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 General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with libgim. If not, see .
+ *
+ * Copyright 2011 Danny Robson
+ */
+
+
+#include "quaternion.hpp"
+
+//-----------------------------------------------------------------------------
+using util::quaternion;
+
+
+//-----------------------------------------------------------------------------
+const quaternion quaternion::IDENTITY = { 1.0, 0.0, 0.0, 0.0 };
+
+
+//-----------------------------------------------------------------------------
+quaternion
+quaternion::rotation (double radians, vector<3> axis) {
+ radians /= 2.0;
+ axis.normalise ();
+
+ return {
+ cos (radians),
+ axis.x * sin (radians),
+ axis.y * sin (radians),
+ axis.z * sin (radians)
+ };
+}
+
+
+quaternion
+quaternion::rotation (vector<3> from, vector<3> to) {
+ auto v = util::cross (from, to);
+
+ return {
+ acos (from.dot (to)),
+ v.x,
+ v.y,
+ v.z
+ };
+}
+
+
+quaternion
+quaternion::operator* (const quaternion &rhs) const {
+ return {
+ w * rhs.w - (x * rhs.x + y * rhs.y + z * rhs.z),
+ w * rhs.x + rhs.w * x + y * rhs.z - z * rhs.y,
+ w * rhs.y + rhs.w * y + z * rhs.x - x * rhs.z,
+ w * rhs.z + rhs.w * z + x * rhs.y - y * rhs.x
+ };
+}
+
diff --git a/quaternion.hpp b/quaternion.hpp
new file mode 100644
index 00000000..24f8e92d
--- /dev/null
+++ b/quaternion.hpp
@@ -0,0 +1,40 @@
+/*
+ * This file is part of libgim.
+ *
+ * libgim is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * libgim 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 General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with libgim. If not, see .
+ *
+ * Copyright 2011 Danny Robson
+ */
+
+#ifndef __UTIL_QUATERNION_HPP
+#define __UTIL_QUATERNION_HPP
+
+#include "annotations.hpp"
+#include "vector.hpp"
+
+namespace util {
+ struct quaternion {
+ double w, x, y, z;
+
+ static const quaternion IDENTITY;
+
+ static quaternion rotation (double radians, vector<3> axis) mustuse;
+ static quaternion rotation (vector<3> from, vector<3> to) mustuse;
+
+ quaternion operator* (const quaternion&) const;
+ };
+}
+
+
+#endif