4

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.

logidelic
  • 1,525
  • 15
  • 42
  • Have you tried using their example: https://github.com/gheja/trilateration.js/blob/master/example.html ? – nsx Dec 03 '15 at 01:41
  • I have tried it and it works. As I mention in the question, I've tried a few examples (some from real-world data) and some seem to work. I'm just trying to understand why my simple example in the question isn't working. I guess that either there's something I don't understand about trilateration, or the algorithm used by the trilateration.js function is faulty. – logidelic Dec 03 '15 at 14:10
  • Take a look at this question from Stack Overflow: http://stackoverflow.com/questions/16176656/trilateration-and-locating-the-point-x-y-z – nsx Dec 03 '15 at 19:06
  • There is also this Octave code that you can try to run as a testing/verification method: https://github.com/lin4r/trilat – nsx Dec 03 '15 at 19:27

2 Answers2

6

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);
Gábor Héja
  • 458
  • 7
  • 17
4

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.

Community
  • 1
  • 1
dtudury
  • 593
  • 3
  • 15