Browse Source

python: expose the new Quaternion rotation overload.

next
Vladimír Vondruš 2 years ago
parent
commit
1f830e6bad
  1. 2
      doc/python/magnum.math.rst
  2. 4
      doc/python/pages/changelog.rst
  3. 7
      src/python/magnum/math.cpp
  4. 19
      src/python/magnum/test/test_math.py

2
doc/python/magnum.math.rst

@ -322,6 +322,8 @@
:raise ValueError: If either of the quaternions is not normalized
.. py:function:: magnum.Quaternion.rotation(angle: magnum.Rad, normalized_axis: magnum.Vector3)
:raise ValueError: If :p:`normalized_axis` is not normalized
.. py:function:: magnum.Quaternion.rotation(normalized_from: magnum.Vector3, normalized_to: magnum.Vector3)
:raise ValueError: If either of the vectors is not normalized
.. py:function:: magnum.Quaterniond.rotation(angle: magnum.Rad, normalized_axis: magnum.Vector3d)
:raise ValueError: If :p:`normalized_axis` is not normalized
.. py:function:: magnum.Quaternion.reflection

4
doc/python/pages/changelog.rst

@ -68,8 +68,8 @@ Changelog
- Exposed :ref:`Color3.from_xyz()`, :ref:`Color3.from_linear_rgb_int()`,
:ref:`Color3.to_xyz()`, :ref:`Color3.to_linear_rgb_int()` and equivalent
APIs on :ref:`Color4`
- Exposed new :ref:`Quaternion.reflection()` and
:ref:`Quaternion.reflect_vector()` APIs
- Exposed new :ref:`Quaternion.rotation()`, :ref:`Quaternion.reflection()`
and :ref:`Quaternion.reflect_vector()` APIs
- Exposed :ref:`gl.Context` and its platform-specific subclasses for EGL, WGL
and GLX
- Exposed :ref:`gl.Framebuffer.attach_texture()` and missing sRGB, depth

7
src/python/magnum/math.cpp

@ -348,6 +348,13 @@ template<class T> void quaternion(py::module_& m, py::class_<T>& c) {
}
return T::rotation(Math::Rad<typename T::Type>(angle), normalizedAxis);
}, "Rotation quaternion", py::arg("angle"), py::arg("normalized_axis"))
.def_static("rotation", [](const Math::Vector3<typename T::Type>& normalizedFrom, const Math::Vector3<typename T::Type>& normalizedTo) {
if(!normalizedFrom.isNormalized() || !normalizedTo.isNormalized()) {
PyErr_Format(PyExc_ValueError, "vectors %S and %S are not normalized", py::cast(normalizedFrom).ptr(), py::cast(normalizedTo).ptr());
throw py::error_already_set{};
}
return T::rotation(normalizedFrom, normalizedTo);
}, "Quaternion rotating from a vector to another", py::arg("normalized_from"), py::arg("normalized_to"))
.def_static("reflection", [](const Math::Vector3<typename T::Type>& normal) {
if(!normal.isNormalized()) {
PyErr_Format(PyExc_ValueError, "normal %S is not normalized", py::cast(normal).ptr());

19
src/python/magnum/test/test_math.py

@ -1451,15 +1451,26 @@ class Quaternion_(unittest.TestCase):
self.assertEqual(a, Quaternion((0.382683, 0.0, 0.0), 0.92388))
self.assertEqual(a.to_matrix(), Matrix4.rotation_x(Deg(45.0)).rotation_scaling())
b = Quaternion.from_matrix(Matrix4.rotation_x(Deg(45.0)).rotation_scaling())
self.assertEqual(b, Quaternion((0.382683, 0.0, 0.0), 0.92388))
# Same as in QuaternionTest::rotationTwoVectors()
b = Vector3(1.0/math.sqrt3)
c = Vector3(Vector2(1.0/math.sqrt2), 0.0)
d = Quaternion.rotation(b, c)
self.assertEqual(d, Quaternion((-0.214186, 0.214186, 0.0), 0.953021))
self.assertEqual(d.transform_vector(b), c)
c = Quaternion.reflection(Vector3.x_axis())
self.assertEqual(c, Quaternion((1.0, 0.0, 0.0), 0.0))
e = Quaternion.from_matrix(Matrix4.rotation_x(Deg(45.0)).rotation_scaling())
self.assertEqual(e, Quaternion((0.382683, 0.0, 0.0), 0.92388))
f = Quaternion.reflection(Vector3.x_axis())
self.assertEqual(f, Quaternion((1.0, 0.0, 0.0), 0.0))
def test_static_methods_invalid(self):
with self.assertRaisesRegex(ValueError, "axis Vector\\(2, 0, 1\\) is not normalized"):
Quaternion.rotation(Deg(35.0), Vector3(2.0, 0.0, 1.0))
with self.assertRaisesRegex(ValueError, "vectors Vector\\(2, 0, 0\\) and Vector\\(0, 1, 0\\) are not normalized"):
Quaternion.rotation(Vector3(2.0, 0.0, 0.0), Vector3(0.0, 1.0, 0.0))
with self.assertRaisesRegex(ValueError, "vectors Vector\\(1, 0, 0\\) and Vector\\(0, 2, 0\\) are not normalized"):
Quaternion.rotation(Vector3(1.0, 0.0, 0.0), Vector3(0.0, 2.0, 0.0))
with self.assertRaisesRegex(ValueError, "normal Vector\\(2, 0, 1\\) is not normalized"):
Quaternion.reflection(Vector3(2.0, 0.0, 1.0))
with self.assertRaisesRegex(ValueError, """the matrix is not a rotation:

Loading…
Cancel
Save