Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorSybren A. Stüvel <sybren@stuvel.eu>2015-02-01 13:58:10 +0300
committerSybren A. Stüvel <sybren@stuvel.eu>2015-02-01 15:06:00 +0300
commit9fa628f35be31a18edfdb1e1fca8a6bd3b6b453c (patch)
tree999052f41e41117200da4bb1d177ffc6a7ff9fab /source
parent8c7e1b648b782542c4906ccb849c39b167265558 (diff)
mathutils: added exponential map to Quaternion
Added conversion to and from exponential map representation. This representation is useful for interpolation of > 2 quaternions, or in PD controllers. Implementation in C functions quat_to_expmap, quat_normalized_to_expmap, and expmap_to_quat with Python API, unit tests and documentation. Added Quaternion.to_exponential_map() and Quaternion(3-vector) to Python API. Reviewers: campbellbarton Projects: #bf_blender Differential Revision: https://developer.blender.org/D1049
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenlib/BLI_math_rotation.h5
-rw-r--r--source/blender/blenlib/intern/math_rotation.c34
-rw-r--r--source/blender/python/mathutils/mathutils_Quaternion.c40
3 files changed, 78 insertions, 1 deletions
diff --git a/source/blender/blenlib/BLI_math_rotation.h b/source/blender/blenlib/BLI_math_rotation.h
index 905889a33d7..fbd026f7617 100644
--- a/source/blender/blenlib/BLI_math_rotation.h
+++ b/source/blender/blenlib/BLI_math_rotation.h
@@ -119,6 +119,11 @@ void mat4_to_axis_angle(float axis[3], float *angle, float M[4][4]);
void axis_angle_to_mat3_single(float R[3][3], const char axis, const float angle);
void angle_to_mat2(float R[2][2], const float angle);
+/****************************** Exponential Map ******************************/
+void quat_to_expmap(float expmap[3], const float q[4]);
+void quat_normalized_to_expmap(float expmap[3], const float q[4]);
+void expmap_to_quat(float r[4], const float expmap[3]);
+
/******************************** XYZ Eulers *********************************/
void eul_to_quat(float quat[4], const float eul[3]);
diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c
index 3ac031d7b90..3d5d47bc2e0 100644
--- a/source/blender/blenlib/intern/math_rotation.c
+++ b/source/blender/blenlib/intern/math_rotation.c
@@ -1016,6 +1016,40 @@ void angle_to_mat2(float mat[2][2], const float angle)
mat[1][1] = angle_cos;
}
+/****************************** Exponential Map ******************************/
+
+void quat_normalized_to_expmap(float expmap[3], const float q[4])
+{
+ float angle;
+ BLI_ASSERT_UNIT_QUAT(q);
+
+ /* Obtain axis/angle representation. */
+ quat_to_axis_angle(expmap, &angle, q);
+
+ /* Convert to exponential map. */
+ mul_v3_fl(expmap, angle);
+}
+
+void quat_to_expmap(float expmap[3], const float q[4])
+{
+ float q_no[4];
+ normalize_qt_qt(q_no, q);
+ quat_normalized_to_expmap(expmap, q_no);
+}
+
+void expmap_to_quat(float r[4], const float expmap[3])
+{
+ float axis[3];
+ float angle;
+
+ /* Obtain axis/angle representation. */
+ angle = normalize_v3_v3(axis, expmap);
+ angle = angle_wrap_rad(angle);
+
+ /* Convert to quaternion. */
+ axis_angle_to_quat(r, axis, angle);
+}
+
/******************************** XYZ Eulers *********************************/
/* XYZ order */
diff --git a/source/blender/python/mathutils/mathutils_Quaternion.c b/source/blender/python/mathutils/mathutils_Quaternion.c
index 98ee2fbd7cc..786a9324adf 100644
--- a/source/blender/python/mathutils/mathutils_Quaternion.c
+++ b/source/blender/python/mathutils/mathutils_Quaternion.c
@@ -177,6 +177,28 @@ static PyObject *Quaternion_to_axis_angle(QuaternionObject *self)
return ret;
}
+PyDoc_STRVAR(Quaternion_to_exponential_map_doc,
+".. method:: to_exponential_map()\n"
+"\n"
+" Return the exponential map representation of the quaternion.\n"
+"\n"
+" This representation consist of the rotation axis multiplied by the rotation angle."
+" Such a representation is useful for interpolation between multiple orientations.\n"
+"\n"
+" :return: exponential map.\n"
+" :rtype: :class:`Vector` of size 3\n"
+);
+static PyObject *Quaternion_to_exponential_map(QuaternionObject *self)
+{
+ float expmap[3];
+
+ if (BaseMath_ReadCallback(self) == -1)
+ return NULL;
+
+ quat_to_expmap(expmap, self->quat);
+ return Vector_CreatePyObject(expmap, 3, NULL);
+}
+
PyDoc_STRVAR(Quaternion_cross_doc,
".. method:: cross(other)\n"
"\n"
@@ -1077,9 +1099,24 @@ static PyObject *Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kw
case 0:
break;
case 1:
- if (mathutils_array_parse(quat, QUAT_SIZE, QUAT_SIZE, seq, "mathutils.Quaternion()") == -1)
+ {
+ int size;
+
+ if ((size = mathutils_array_parse(quat, 3, QUAT_SIZE, seq, "mathutils.Quaternion()")) == -1) {
return NULL;
+ }
+
+ if (size == 4) {
+ /* 4d: Quaternion (common case) */
+ }
+ else {
+ /* 3d: Interpret as exponential map */
+ BLI_assert(size == 3);
+ expmap_to_quat(quat, quat);
+ }
+
break;
+ }
case 2:
{
float axis[3];
@@ -1156,6 +1193,7 @@ static struct PyMethodDef Quaternion_methods[] = {
{"to_euler", (PyCFunction) Quaternion_to_euler, METH_VARARGS, Quaternion_to_euler_doc},
{"to_matrix", (PyCFunction) Quaternion_to_matrix, METH_NOARGS, Quaternion_to_matrix_doc},
{"to_axis_angle", (PyCFunction) Quaternion_to_axis_angle, METH_NOARGS, Quaternion_to_axis_angle_doc},
+ {"to_exponential_map", (PyCFunction) Quaternion_to_exponential_map, METH_NOARGS, Quaternion_to_exponential_map_doc},
/* operation between 2 or more types */
{"cross", (PyCFunction) Quaternion_cross, METH_O, Quaternion_cross_doc},