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…