Трехмерная трилатерация в Javascript

Я пытаюсь выполнить трехмерную трилатерацию в Javascript, используя https://github.com/gheja/trilateration.js и вроде работает. Однако некоторые простые случаи должны давать решения, но это не так. Например:

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)

Это кажется смехотворно простым примером, который должен давать решение в точке x:0,y:0, но вместо этого функция сообщает мне, что решения нет. Я что-то не понимаю в трилатерации или в функции ошибка?

Любая помощь будет оценена по достоинству.


person logidelic    schedule 03.12.2015    source источник
comment
Пробовали ли вы использовать их пример: github.com/gheja/trilateration.js /blob/master/example.html ?   -  person リカルド    schedule 03.12.2015
comment
Я попробовал это, и это работает. Как я упоминаю в вопросе, я пробовал несколько примеров (некоторые из реальных данных), и некоторые из них, похоже, работают. Я просто пытаюсь понять, почему мой простой пример в вопросе не работает. Я предполагаю, что либо я чего-то не понимаю в трилатерации, либо алгоритм, используемый функцией trilateration.js, неисправен.   -  person logidelic    schedule 03.12.2015
comment
Взгляните на этот вопрос из переполнения стека: stackoverflow.com/questions/16176656/   -  person リカルド    schedule 03.12.2015
comment
Существует также этот код Octave, который вы можете попробовать запустить в качестве метода тестирования/проверки: github.com/lin4r/trilat   -  person リカルド    schedule 03.12.2015


Ответы (2)


Да, на самом деле это была ошибка в библиотеке, спасибо @logidelic за ее обнаружение и @dtudury за ее отслеживание.

Я исправил это сейчас, обнулив значение, если оно близко к нулю:

b = sqr(p1.r) - sqr(x) - sqr(y);

if (Math.abs(b) < 0.0000000001)
{
    b = 0;
}

z = Math.sqrt(b);
person Gábor Héja    schedule 28.07.2016

похоже, это проблема с репо, которое вы нашли.

особенно если вы посмотрите на эту строку https://github.com/gheja/trilateration.js/blob/master/trilateration.js#L111 и зарегистрируйте значения, которые он использует для расчета 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

это просто особенность поплавков (Разрушена ли математика с плавающей запятой?). Если вы измените порядок ваших аргументов (trilaterate(p1, p3, p2, false)), вы получите 2 значения, которые очень близки к правильному ответу.

На самом деле ваш тест должен быть особым случаем; пересечение ваших первых двух сфер является одной точкой. Вы можете подумать о разветвлении репозитория и тестировании еле-еле касающихся сфер, если это ожидаемый вариант использования.

person dtudury    schedule 07.12.2015