- added a new math function double_round, useful for rounding a number to a number of decimal places.
- added Mathutils vector method, vec.asTuple(round), since this is tedious in python and fairly common task.
This commit is contained in:
@@ -148,6 +148,8 @@ float power_of_2(float f);
|
||||
|
||||
float shell_angle_to_dist(float angle);
|
||||
|
||||
double double_round(double x, int ndigits);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -109,3 +109,34 @@ float power_of_2(float val)
|
||||
return (float)pow(2, ceil(log(val) / log(2)));
|
||||
}
|
||||
|
||||
/* from python 3.1 floatobject.c
|
||||
* ndigits must be between 0 and 21 */
|
||||
double double_round(double x, int ndigits) {
|
||||
double pow1, pow2, y, z;
|
||||
if (ndigits >= 0) {
|
||||
pow1 = pow(10.0, (double)ndigits);
|
||||
pow2 = 1.0;
|
||||
y = (x*pow1)*pow2;
|
||||
/* if y overflows, then rounded value is exactly x */
|
||||
if (!finite(y))
|
||||
return x;
|
||||
}
|
||||
else {
|
||||
pow1 = pow(10.0, (double)-ndigits);
|
||||
pow2 = 1.0; /* unused; silences a gcc compiler warning */
|
||||
y = x / pow1;
|
||||
}
|
||||
|
||||
z = round(y);
|
||||
if (fabs(y-z) == 0.5)
|
||||
/* halfway between two integers; use round-half-even */
|
||||
z = 2.0*round(y/2.0);
|
||||
|
||||
if (ndigits >= 0)
|
||||
z = (z / pow2) / pow1;
|
||||
else
|
||||
z *= pow1;
|
||||
|
||||
/* if computation resulted in overflow, raise OverflowError */
|
||||
return z;
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ static PyObject *Vector_Negate( VectorObject * self );
|
||||
static PyObject *Vector_Resize2D( VectorObject * self );
|
||||
static PyObject *Vector_Resize3D( VectorObject * self );
|
||||
static PyObject *Vector_Resize4D( VectorObject * self );
|
||||
static PyObject *Vector_ToTuple( VectorObject * self, PyObject *value );
|
||||
static PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args );
|
||||
static PyObject *Vector_Reflect( VectorObject *self, VectorObject *value );
|
||||
static PyObject *Vector_Cross( VectorObject * self, VectorObject * value );
|
||||
@@ -61,6 +62,7 @@ static struct PyMethodDef Vector_methods[] = {
|
||||
{"resize2D", (PyCFunction) Vector_Resize2D, METH_NOARGS, NULL},
|
||||
{"resize3D", (PyCFunction) Vector_Resize3D, METH_NOARGS, NULL},
|
||||
{"resize4D", (PyCFunction) Vector_Resize4D, METH_NOARGS, NULL},
|
||||
{"toTuple", (PyCFunction) Vector_ToTuple, METH_O, NULL},
|
||||
{"toTrackQuat", ( PyCFunction ) Vector_ToTrackQuat, METH_VARARGS, NULL},
|
||||
{"reflect", ( PyCFunction ) Vector_Reflect, METH_O, NULL},
|
||||
{"cross", ( PyCFunction ) Vector_Cross, METH_O, NULL},
|
||||
@@ -236,6 +238,30 @@ static PyObject *Vector_Resize4D(VectorObject * self)
|
||||
Py_INCREF(self);
|
||||
return (PyObject*)self;
|
||||
}
|
||||
|
||||
/*----------------------------Vector.resize4D() ------------------
|
||||
resize the vector to x,y,z,w */
|
||||
static PyObject *Vector_ToTuple(VectorObject * self, PyObject *value)
|
||||
{
|
||||
int ndigits= PyLong_AsSsize_t(value);
|
||||
int x;
|
||||
|
||||
PyObject *ret;
|
||||
|
||||
if(ndigits > 22 || ndigits < 0) { /* accounts for non ints */
|
||||
PyErr_SetString(PyExc_TypeError, "vector.key(ndigits): ndigits must be between 0 and 21");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret= PyTuple_New(self->size);
|
||||
|
||||
for(x = 0; x < self->size; x++) {
|
||||
PyTuple_SET_ITEM(ret, x, PyFloat_FromDouble(double_round((double)self->vec[x], ndigits)));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*----------------------------Vector.toTrackQuat(track, up) ----------------------
|
||||
extract a quaternion from the vector and the track and up axis */
|
||||
static PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args )
|
||||
|
||||
Reference in New Issue
Block a user