Bug in Vector angle_between
-
I don't know if anyone has noticed the problem, but there seems to be a bug in the function
angle_between
for vectors with small length.Consider the following code
v1 = X_AXIS.clone v2 = X_AXIS.reverse.clone v1.length = 0.1.mm v2.length = 0.1.mm v1.angle_between v2
The result is 1.5707..., that is PI / 2, and neither close to 0 nor to PI
So, as a rule of thumb, it is recommended to normalize the vectors before invoking the
angle_between
method.Note that the result is correct is the vector length is 1.mm.
Fredo
-
it sort of does not surprise me since SU does not seem to like to work below mm lengths very well. It is unfortunate though and good to note. I'm sure I've got scripts that could in theory stumble on this. Thanks for the heads up Fredo.
Chris
-
@unknownuser said:
Note that the result is correct is the vector length is 1.mm
The cutoff appears to be (works at or above):
vec.length = 0.03162316231623162**... inches
which is:
0.803228322832283228...** mm -
@unknownuser said:
So, as a rule of thumb, it is recommended to normalize the vectors before invoking the
angle_between
method.If v1 is a unit vector, then the cutoff for v2 is 0.001 inches, which is Sketchup's internal tolerance.
-
@dan rathbun said:
@unknownuser said:
So, as a rule of thumb, it is recommended to normalize the vectors before invoking the
angle_between
method.If v1 is a unit vector, then the cutoff for v2 is 0.001 inches, which is Sketchup's internal tolerance.
I would imagine that SU would normalize the vectors first before computing the angle, so that it's independent of the size. And why return PI / 2 and not 0?
Fredo
-
@dan rathbun said:
@unknownuser said:
Note that the result is correct is the vector length is..
The cutoff appears to be (works at or above):
vec.length = 0.03162316231623162**...** inchesActually, I think the cutoff is more like the rounded value, of the square root of Sketchup's internal tolerance (0.001) ie:
(0.001)**(1/2.0)
>>0.0316227766016838
[table=bg1 table1:34jvzu3e][thead:34jvzu3e][tr=:34jvzu3e][th=1:34jvzu3e]So the general rule is:[/th:34jvzu3e][/tr:34jvzu3e][/thead:34jvzu3e][tbody:34jvzu3e][tr=bg2:34jvzu3e][td=1,:34jvzu3e]If the product of the lengths of the two vectors, is less than that of Sketchup's internal tolerance (0.001"), the angle returned by angle_between is
Math::PI/2
[(Math::PI/2).radians.round
= 90 deg,]
instead of
Math::PI
[(Math::PI).radians.round
**= 180 degrees.]**[/td:34jvzu3e][/tr:34jvzu3e][/tbody:34jvzu3e][/table:34jvzu3e]
viz:
v1.length = 0.03162278 v2.length = 0.03162278 v1.angle_between(v2)
>>3.14159265358979
v1.angle_between(v2).radians
>>180 %(#000000)[# degrees]
@unknownuser said:
I would imagine that SU would normalize the vectors first before computing the angle, so that it's independent of the size.
AGREED !! At first i could not imagine why the length would have anything to do with it, but then seeing how a square root is involved, they are likely using pythagorean trigonometry.
@unknownuser said:
And why return PI / 2 and not 0?
That's funny also, PI/2 radians is 90 degrees. Perhaps they choose a known 'reference' vector (say the X-axis) and find the angle between it an v1. Then choose another 'reference' vector 90 degrees from the first (the Y-axis), and compute the angle between it and v2. If there's a bug in there (say half of the algorithm craps out,) that may be why you wind up with 90.
now your inline fix, in code is:
v1.normalize.angle_between(v2.normalize)
or
v1.normalize.angle_between([array].normalize)
Advertisement