I'm trying to do 3D trilateration in Javascript using https://github.com/gheja/trilateration.js and it seems to be working. However, certain simple cases should be yielding solutions but they are not. For example:
var p1 = {x:69, y:0, r:69, z:0}
var p2 = {x:0, y:50, r:50, z:0};
var p3 = {x:0, y:80, r:80, z:0};
trilaterate(p1, p2, p3, false)
This seems like a ridiculously simple example that should yield a solution at x:0,y:0, but instead the function tells me that there is no solution. Am I misunderstanding something about trilateration or is there an error in the function?
Any help would be appreciated.
Yes, it was actually a bug in the library, thanks @logidelic for finding it and @dtudury for tracking it down.
I have fixed it now by zeroing the value if it is near to zero:
b = sqr(p1.r) - sqr(x) - sqr(y);
if (Math.abs(b) < 0.0000000001)
{
b = 0;
}
z = Math.sqrt(b);
it looks like it's an issue with the repo you found.
specifically if you look at this line https://github.com/gheja/trilateration.js/blob/master/trilateration.js#L111 and log out the values it's using to calculate z = Math.sqrt(sqr(p1.r) - sqr(x) - sqr(y));
:
sqr(p1.r): 4761
-sqr(x) - sqr(y): -4761.000000000017
sqr(p1.r) - sqr(x) - sqr(y): -0.000000000017
z: Math.sqrt(-0.000000000017)
therefore: z: NaN
it's just a feature of floats (Is floating point math broken?). If you change the order of your arguments (trilaterate(p1, p3, p2, false)
) you get 2 values that are very close to the right answer.
Really your test should be a special case; the intersection of your first 2 spheres is a single point. You might consider forking the repo and testing for just barely touching spheres if this is an expected use case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With