I’m porting a code that is calling many functions from Rhino.Geometry to C++. Today I noticed I have no idea how to do VectorAngle() with my own code… It’s a bit embarrassing but if anybody could give me some insights, I’ll appreciate it very much. A pseudo-code is much more appreciated.
Thanks!!!
Hi @mikity_kogekoge,
This is from RhinoScript:
double ON_VectorAngle(ON_3dVector v0, ON_3fVector v1)
{
double angle = ON_UNSET_VALUE;
if (
v0.IsValid()
&& v1.IsValid()
&& !v0.IsZero()
&& !v1.IsZero()
)
{
v0.Unitize();
v1.Unitize();
double dot = RHINO_CLAMP(ON_DotProduct(v0, v1), -1.0, 1.0);
angle = acos(dot);
}
return angle;
}
– Dale
Thanks Dale!!
In my test, the acos(dot) sometimes returns Nan. Is that the reason you do RHINO_CLAMP? Isn’t it ensured that dot products always fit within -1.0-1.0?
It might be very useful to to know that the vector dot product is very closely related to the trigonometric functions, namely the cosine:
If \hat{u} and \hat{v} are normal vectors (unit vectors), their dot product is simply equal to \cos(\theta), since:
You can thus get the vector angle by calculating the inverse cosine of their dot product.
@dale Is the clamping just a precaution? I’m asking because the dot product of two unit vectors should at least theoretically always be between -1 and 1.
that was what I was trying to say…
Ah, I must have misread. I’m still wondering why the dot product of two normal vectors can be NaN though?
Maybe slightly off from -1 or 1? Anyway added the clamp and it works now.
I’ve dug a little through the opennurbs project and I think it might rather be related to vector normalization.
Yes the normalization doesn’t ensure that the length is one there is a 2E-16 error.
The probability of occurrence of length > 1 is around 7%.
error unitize.gh (7.9 KB)
Thanks for the demonstration, Laurent.
oh, really…