Самая быстрая гипотенуза в javascript?

Я видел несколько вопросов о моделировании и анимации в javascript, которые часто включают вычисление гипотенузы:

hypot = Math.sqrt(x*x + y*y);

поскольку декартовые координаты являются оружием выбора в большинстве этих двигателей, эти вычисления необходимы для поиска расстояния между парами точек и т. д. Таким образом, любое ускорение в расчете гипотенузы может быть большим подспорьем для многих проектов.

С этой целью вы можете увидеть более быстрый метод, чем простой реализация выше? Я нашел приближение, которое было немного быстрее в Chrome, но оказалось намного медленнее в Firefox, на основе эта аппроксимационная функция в Суперколлайдере.

Edit 2015-08-15: я переключил принятый ответ на математику.гипотеза Одна; я подозреваю, что прагматический подход в настоящее время будет использовать математику.гипотеза или синтезированная функция гипотезы, если она недоступна, и сравнить с квадратом (в ответе sch) , если этого достаточно и Математика.функции не доступны.

4 ответов


в ECMAScript ES6 вы можете использовать математика.гипот:

// ES5 support

Math.hypot = Math.hypot || function(x, y){ return Math.sqrt(x*x + y*y) }

var x = 3, y = 4;

document.write(Math.hypot(x, y))

редактировать: вы можете запускать этот тест на пустой вкладке, 2 миллиона операций с обоими методами, результаты очень хорошие, это на 24% быстрее.

var i, tmp, x = 55, y = 66, end, ini = performance.now();

// Math.sqrt operation
i = 0;
ini = performance.now();
tmp = 0;
while(i++ < 2000000){
    tmp += Math.sqrt(x*x + y*y)
}
end = performance.now();
console.log(tmp, "Math.sqrt operation: " + (end - ini) + " ms");

// Math.hypot

i = 0;
ini = performance.now();
tmp = 0;
while(i++ < 2000000){
    tmp += Math.hypot(x, y)
}
end = performance.now();

console.log(tmp, "Math.hypot: " + (end - ini) + " ms");

Примечание: в этом тесте используется ES6 математика.гипот.

enter image description here


часто вам не нужно вычислять квадратный корень и hypot^2 = x*x + y*y достаточно. Это имеет место, например, если вы хотите сравнить расстояния и не нужны фактические значения.


важный момент, который многие не знают:

hypot = Math.sqrt(x*x + y*y);

это работает в теории, но на практике это может не получиться. Если x настолько велик что X * x переполняется, код будет производить бесконечный результат.

вот как вычислить sqrt(xx + yy) без риска переполнения.

max = maximum(|x|, |y|)
min = minimum(|x|, |y|)
r = min / max
return max*sqrt(1 + r*r)

ссылка и полный текст: Джон Д. Кук - http://www.johndcook.com/blog/2010/06/02/whats-so-hard-about-finding-a-hypotenuse/


вы можете посмотреть на равенство x и y. Если равны, вы можете вычислить гипотенузу как (x + y)/sqrt(2) здесь sqrt(2) - константа.

таким образом, этот метод можно использовать для случая, когда x = y. Для других случаев его можно использовать с максимальной неточностью ~41%. Это большая ошибка. Но когда вы указываете допустимые пределы ошибок, вы можете использовать этот метод. Например, если определить допустимую ошибку до 5% , Вы можете получить это b должен быть между 0.515*a и 1.942*a.

поэтому, если вам не нужна идеальная неточность ваших вычислений, вы можете улучшить производительность вычислений с диапазоном значений.

по аналогии вы можете посмотреть на равенство x или y to zero. И с некоторой точностью рассчитайте гипотенузу более быстро для этого случая.

С. П., Я читал об этом в одной русские статьи.