# Is there a fast way to trilaterate a point?

I have a point in 2D or 3D space at an unknown coordinate, $p_0$, and I'd like to determine its position using distances from known coordinates $(p_1, p_2, p_3)$. Beyond using Reduce, what is a fast method of doing this in Mathematica, particularly for the two-dimensional case? Is there some built-in function for this?

Also, how can I get an output in coordinate form without any string processing? For example, to parse the output from Reduce, I need to convert the output to a string, infer where the actual coordinate values are, and extract them, which is an awful way to go about doing things.

Here's an implementation with Solve:

PostOne = {10, 10};
PostTwo = {10, 0};
PostThree = {0, 0};

PointToLocalize = {x0, y0};

D1 = 0;
D2 = 10;
D3 = 200^(1/2);

Solve[EuclideanDistance[PointToLocalize, PostOne] == D1 &&
EuclideanDistance[PointToLocalize, PostTwo] == D2 &&
EuclideanDistance[PointToLocalize, PostThree] == D3, {x0, y0}]


Now that the string processing issues have been resolved, is Solve or Reduce really the most efficient way to do this for $10^6$ or $10^7$ or so points?

-
Could you post what you have tried so far? –  s0rce Apr 15 '13 at 1:27
@s0rce Sure thing. –  Telomer Apr 15 '13 at 1:29
@s0rce I've switched Reduce to Solve, and provided specific numeric values. It works, but I still have to string process the answer, and I feel there might be a better way? –  Telomer Apr 15 '13 at 1:33
For the result you can use the following" {x,y}/.solution. If you use Reduce you can do the following: {x,y}/.(Rule@@@List@@solution). –  Spawn1701D Apr 15 '13 at 1:34
–  s0rce Apr 15 '13 at 1:37
show 6 more comments

## 1 Answer

In two dimensions, we can reformulate your problem as finding the intersection point of three circles with given centers and radii.

To ease things, you can first form the radical line of two of your three circles, and then find the intersection of that line with the third circle. This will return two solutions, which means we need to do some postprocessing to pick out the one you actually want.

Here's how to go about it:

pts = {x, y} /. Solve[{2 (PostTwo - PostOne).{x, y} +
PostOne.PostOne - PostTwo.PostTwo == D1^2 - D2^2,
#.# &[{x, y} - PostThree] == D3^2}, {x, y}, Reals];

Select[pts, And @@ MapThread[Function[{c, r}, EuclideanDistance[#, c] == r],
{{PostOne, PostTwo, PostThree}, {D1, D2, D3}}] &] // First


which yields the result {10, 10} in your particular case.

-
Thanks and nicely done. –  Telomer Apr 15 '13 at 5:11
add comment