FAQ
Cover
\
Build
\
Source
\
Bugs
\
Reference
\
Libraries
\
Tools
The bugs database has moved
here
.
Bug 1316 : PVector.angleDistance() returns NaN in 1.0.6
Last modified: 2009-11-22 09:45
P
roject:
processing
trash
Version:
unspecified
Co
m
ponent:
android
book
core
libraries
pde
reference
tools
web
Status:
RESOLVED
Resolution:
FIXED -
Pr
i
ority:
P2
Severity:
normal
Platform
All
O
S:
All
Windows
Mac OS
Linux
Other
Reporter:
Dan Bernier
Assigned To:
fry
Attachment
Type
Created
Size
Actions
Description
: Opened: 2009-08-31 10:36
Processing version 1.0.3
MS Vista, Dell Latitude D820
Based on this discussion:
http://processing.org/discourse/yabb2/YaBB.pl?num=1244554381/0#0
When calculating the angle between equal vectors, Processing often returns
NaN, and it seems to be a rounding error -- internally, it uses
PVector.mag(), which casts its result to a float. Leaving it as a double
eliminates the problem, and returns a number very close to zero (the
expected result).
Some code that demonstrates the problem, and the fix:
void setup() {
// some offending vectors
PVector[] vs = new PVector[4];
vs[0] = new PVector(-1, -1);
vs[1] = new PVector(1 , -1);
vs[2] = new PVector(1 , 1);
vs[3] = new PVector(-1, 1);
for (int i = 0; i < vs.length; i++) {
println(vs[i] + "\t default: " + PVector.angleBetween(vs[i], vs[i]));
println(vs[i] + "\t doubles: " + angleBetween(vs[i], vs[i]));
println();
}
}
double mag(PVector v) {
return Math.sqrt(v.x*v.x + v.y*v.y);
}
float angleBetween(PVector v1, PVector v2) {
double dot = v1.dot(v2);
float theta = (float) Math.acos(dot / (mag(v1) * mag(v2)));
return theta;
}
Additional Comment
#1 From fry 2009-08-31 12:10
k, here's the implementation that uses doubles for calculation:
static public float angleBetween(PVector v1, PVector v2) {
double dot = v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
double v1mag = Math.sqrt(v1.x * v1.x + v1.y * v1.y + v1.z * v1.z);
double v2mag = Math.sqrt(v2.x * v2.x + v2.y * v2.y + v2.z * v2.z);
return (float) Math.acos(dot / (v1mag * v2mag));
}
and it's been updated in svn for the next release of processing.
Additional Comment
#2 From nervoussystem 2009-11-18 14:16
I noticed that this can still be a problem with the native Math.acos method in java
when dealing with vectors very close to parallel regardless of float versus double
arithmetic. I got around it by adding a check for a dot product close to -1 or 1
(normalized) and rounding it off.
I'm not advocated adding such a check into processing, but it is useful for people to
be aware of the potentially difficult to track down error.
-Jesse
(In reply to
comment #1
)
>
>
>
> Additional
Comment #1
From
> fry
> 2009-08-31 12:10
>
> <!--
> addReplyLink(1); //-->[reply]
>
>
>
>
> k, here's the implementation that uses doubles for calculation:
>
> static public float angleBetween(PVector v1, PVector v2) {
> double dot = v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
> double v1mag = Math.sqrt(v1.x * v1.x + v1.y * v1.y + v1.z * v1.z);
> double v2mag = Math.sqrt(v2.x * v2.x + v2.y * v2.y + v2.z * v2.z);
> return (float) Math.acos(dot / (v1mag * v2mag));
> }
>
> and it's been updated in svn for the next release of processing.
>
>
Additional Comment
#3 From fry 2009-11-22 09:45
That's a reference issue, I've filed
bug #1375
to address it.