diff options
author | Campbell Barton <ideasman42@gmail.com> | 2010-09-29 09:15:55 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2010-09-29 09:15:55 +0400 |
commit | 7a950c287692dc44edc23eb9daf865de8e115307 (patch) | |
tree | 413a5b8330c0e7344a897c13ae2d6e309a0f91b1 /source | |
parent | 2b59013490da8f60420c254d1c84d921c61e9c8c (diff) |
patch from Dan Eicher with some edirts.
vec.rotate(axis, angle)
equivalent to...
vec[:] = vec * mathutils.Quaternion(axis, angle)
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenlib/BLI_math_vector.h | 2 | ||||
-rw-r--r-- | source/blender/blenlib/intern/math_vector.c | 30 | ||||
-rw-r--r-- | source/blender/python/generic/mathutils_vector.c | 40 |
3 files changed, 72 insertions, 0 deletions
diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h index 25f58787a43..215ddf2f2d9 100644 --- a/source/blender/blenlib/BLI_math_vector.h +++ b/source/blender/blenlib/BLI_math_vector.h @@ -148,6 +148,8 @@ void project_v3_v3v3(float r[3], const float p[3], const float n[3]); void reflect_v3_v3v3(float r[3], const float v[3], const float n[3]); void ortho_basis_v3v3_v3(float r1[3], float r2[3], const float a[3]); void bisect_v3_v3v3v3(float r[3], const float a[3], const float b[3], const float c[3]); +void rotate_v3_v3v3fl(float v[3], const float p[3], const float axis[3], const float angle); +void rotate_normalized_v3_v3v3fl(float v[3], const float p[3], const float axis[3], const float angle); /*********************************** Other ***********************************/ diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c index 04c8ae49dfa..e3cb5b37470 100644 --- a/source/blender/blenlib/intern/math_vector.c +++ b/source/blender/blenlib/intern/math_vector.c @@ -296,6 +296,36 @@ void ortho_basis_v3v3_v3(float v1[3], float v2[3], const float v[3]) } } +/* Rotate a point p by angle theta around an arbitrary axis r + http://local.wasp.uwa.edu.au/~pbourke/geometry/ +*/ +void rotate_normalized_v3_v3v3fl(float r[3], const float p[3], const float axis[3], const float angle) +{ + const float costheta= cos(angle); + const float sintheta= sin(angle); + + r[0]= ((costheta + (1 - costheta) * axis[0] * axis[0]) * p[0]) + + (((1 - costheta) * axis[0] * axis[1] - axis[2] * sintheta) * p[1]) + + (((1 - costheta) * axis[0] * axis[2] + axis[1] * sintheta) * p[2]); + + r[1]= (((1 - costheta) * axis[0] * axis[1] + axis[2] * sintheta) * p[0]) + + ((costheta + (1 - costheta) * axis[1] * axis[1]) * p[1]) + + (((1 - costheta) * axis[1] * axis[2] - axis[0] * sintheta) * p[2]); + + r[2]= (((1 - costheta) * axis[0] * axis[2] - axis[1] * sintheta) * p[0]) + + (((1 - costheta) * axis[1] * axis[2] + axis[0] * sintheta) * p[1]) + + ((costheta + (1 - costheta) * axis[2] * axis[2]) * p[2]); +} + +void rotate_v3_v3v3fl(float r[3], const float p[3], const float axis[3], const float angle) +{ + float axis_n[3]; + + normalize_v3_v3(axis_n, axis); + + rotate_normalized_v3_v3v3fl(r, p, axis_n, angle); +} + /*********************************** Other ***********************************/ void print_v2(const char *str, const float v[2]) diff --git a/source/blender/python/generic/mathutils_vector.c b/source/blender/python/generic/mathutils_vector.c index 7b73a7501bb..1fe2518c6ef 100644 --- a/source/blender/python/generic/mathutils_vector.c +++ b/source/blender/python/generic/mathutils_vector.c @@ -686,6 +686,45 @@ static PyObject *Vector_Lerp(VectorObject *self, PyObject *args) return newVectorObject(vec, self->size, Py_NEW, NULL); } +/*---------------------------- Vector.rotate(angle, axis) ----------------------*/ +static char Vector_Rotate_doc[] = +".. function:: rotate(axis, angle)\n" +"\n" +" Return vector rotated around axis by angle.\n" +"\n" +" :arg axis: rotation axis.\n" +" :type axis: :class:`Vector`\n" +" :arg angle: angle in radians.\n" +" :type angle: float\n" +" :return: an instance of itself\n" +" :rtype: :class:`Vector`\n"; + +static PyObject *Vector_Rotate(VectorObject *self, PyObject *args) +{ + VectorObject *axis_vec = NULL; + float angle, vec[3]; + + if(!PyArg_ParseTuple(args, "O!f", &vector_Type, &axis_vec, &angle)){ + PyErr_SetString(PyExc_TypeError, "vec.rotate(angle, axis): expected angle (float) and 3D axis"); + return NULL; + } + + if(self->size != 3 || axis_vec->size != 3) { + PyErr_SetString(PyExc_AttributeError, "vec.rotate(angle, axis): expects both vectors to be 3D\n"); + return NULL; + } + + if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(axis_vec)) + return NULL; + + rotate_v3_v3v3fl(vec, self->vec, axis_vec->vec, angle); + + copy_v3_v3(self->vec, vec); + + Py_INCREF(self); + return (PyObject *)self; +} + /*----------------------------Vector.copy() -------------------------------------- */ static char Vector_copy_doc[] = ".. function:: copy()\n" @@ -2050,6 +2089,7 @@ static struct PyMethodDef Vector_methods[] = { {"difference", ( PyCFunction ) Vector_Difference, METH_O, Vector_Difference_doc}, {"project", ( PyCFunction ) Vector_Project, METH_O, Vector_Project_doc}, {"lerp", ( PyCFunction ) Vector_Lerp, METH_VARARGS, Vector_Lerp_doc}, + {"rotate", ( PyCFunction ) Vector_Rotate, METH_VARARGS, Vector_Rotate_doc}, {"copy", (PyCFunction) Vector_copy, METH_NOARGS, Vector_copy_doc}, {"__copy__", (PyCFunction) Vector_copy, METH_NOARGS, NULL}, {NULL, NULL, 0, NULL} |