[Bf-python] AngleBetweenVecs found solution
Campbell Barton
cbarton at metavr.com
Mon Oct 10 03:38:05 CEST 2005
All that was needed was clipping the dot product. near the bottom of
M_Mathutils_AngleBetweenVecs
// clip the quotient to acceptable values for acos
if (dot > 1) {
dot = 1;
} else if (dot < -1) {
dot = -1;
}
# Below for full code.
//----------------------------------Mathutils.AngleBetweenVecs() ---------
//calculates the angle between 2 vectors
PyObject *M_Mathutils_AngleBetweenVecs(PyObject * self, PyObject * args)
{
VectorObject *vec1 = NULL, *vec2 = NULL;
double dot = 0.0f, angleRads, test_v1 = 0.0f, test_v2 = 0.0f;
double norm_a = 0.0f, norm_b = 0.0f;
double vec_a[4], vec_b[4];
int x, size;
if(!PyArg_ParseTuple(args, "O!O!", &vector_Type, &vec1,
&vector_Type, &vec2))
return EXPP_ReturnPyObjError(PyExc_TypeError,
"Mathutils.AngleBetweenVecs(): expects (2) vector objects of
the same size\n");
if(vec1->size != vec2->size)
return EXPP_ReturnPyObjError(PyExc_AttributeError,
"Mathutils.AngleBetweenVecs(): expects (2) vector objects of
the same size\n");
//since size is the same....
size = vec1->size;
for(x = 0; x < size; x++) {
test_v1 += vec1->vec[x] * vec1->vec[x];
test_v2 += vec2->vec[x] * vec2->vec[x];
}
if (!test_v1 || !test_v2){
return EXPP_ReturnPyObjError(PyExc_AttributeError,
"Mathutils.AngleBetweenVecs(): zero-length vectors not
acceptable\n");
}
//copy vector info
for (x = 0; x < size; x++){
vec_a[x] = vec1->vec[x];
vec_b[x] = vec2->vec[x];
}
//normalize vectors
norm_a = (double)sqrt(test_v1);
norm_b = (double)sqrt(test_v2);
for(x = 0; x < size; x++) {
vec_a[x] /= norm_a;
vec_b[x] /= norm_b;
}
//dot product
for(x = 0; x < size; x++) {
dot += vec_a[x] * vec_b[x];
}
// clip the quotient to acceptable values for acos
if (dot > 1) {
dot = 1;
} else if (dot < -1) {
dot = -1;
}
//I believe saacos checks to see if the vectors are normalized
angleRads = (double)acos(dot);
return PyFloat_FromDouble(angleRads * (180 / Py_PI));
}
Campbell Barton wrote:
> Heres a workaround I use when comparing face normals.
> Seems it can return NAN when the normals are either the Same of
> completely opposite.
> Contrived comparisons between vectors dont work. Only that Im getting
> the normals from a mesh.
> - Cam
>
> # Now we can compare a selected face to an unselected face.
> if selFace.normal == unselFace.normal:
> ang = 0
> else:
> ang = AngleBetweenVecs(selFace.normal, unselFace.normal)
> if ang != ang:
> #print selFace.normal, unselFace.normal
> #raise ' ERROR'
> if (selFace.normal - unselFace.normal).length < 0.5: #
> Are we the same or complete opposite.
> ang = 0
> else:
> ang = 180
>
>
>
> Campbell Barton wrote:
>> Theres still a bug that makes AngleBetweenVecs return NAN when both
>> vectors are the same.
>> Checking weather V1 == V2, almost always works, but in some
>> situations a slight difference will make the 2 vectors not equel but
>> still return NAN- if you need a testcase I can provide one. but I
>> assume that looking at the code will show how 2 vectors that are the
>> same could return NAN.
>>
>> - Cam
>>
>> Frank Schafer wrote:
>>> Hi,
>>> IMHO you should simply catch this exception, because (again IMHO) it
>>> MAKES sense that Mathutils complains to calculate angles between
>>> vectors
>>> of zero length.
>>>
>>> Regards
>>> Frank
>>>
>>>
>>> On Fri, 2005-10-07 at 09:57 +1000, Campbell Barton wrote:
>>>
>>>> Found that AngleBetweenVecs raises an error when checking for a
>>>> zero length Vector
>>>>
>>>> # Heres my test from the interactive console.
>>>> print Mathutils.AngleBetweenVecs(Mathutils.Vector(10.0, 0 , 0),
>>>> Mathutils.Vector(0,1,0))
>>>> exceptions.AttributeError: Mathutils.AngleBetweenVecs():
>>>> zero-length vectors not acceptable
>>>>
>>>> - Cam
>>>>
>>>>
>>> _______________________________________________
>>> Bf-python mailing list
>>> Bf-python at projects.blender.org
>>> http://projects.blender.org/mailman/listinfo/bf-python
>>>
>>>
>>
>>
>
>
--
Campbell J Barton
133 Hope Street
Geelong West, Victoria 3218 Australia
URL: http://www.metavr.com
e-mail: cbarton at metavr.com
phone: AU (03) 5229 0241
More information about the Bf-python
mailing list