[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