Как я могу масштабировать двухмерный вектор вращения без триггерных функций? - PullRequest
0 голосов
/ 04 января 2019

У меня есть нормализованный 2D-вектор, который я использую для поворота других 2D-векторов.В одном случае он указывает «вращение» (или «угловой момент») и используется для поворота «ориентации» простого многоугольника.Мой векторный класс содержит этот метод:

rotateByXY(x, y) {
  let rotX = x * this.x - y * this.y;
  let rotY = y * this.x + x * this.y;
  this.x = rotX;
  this.y = rotY;
}

Пока что все это эффективно и не использует никаких триггеров.

Однако я хочу, чтобы «вращение» со временем затухало.Это означает, что угол вращения должен стремиться к нулю.И здесь я в растерянности относительно того, как сделать это без дорогих триггеров, как это:

let angle = Math.atan2(spin.y, spin.x);
angle *= SPIN_DECAY;
spin = new Vector2D(Math.cos(angle), Math.sin(angle));

Есть ли лучший / более быстрый способ сделать это?

1 Ответ

0 голосов
/ 21 января 2019

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

Для x, близких к нулю, следующие идентификаторы имеют значение :

cos(x) = 1 - (x^2)/2! + (x^4)/4! - (x^6)/6! + ...
sin(x) = x - (x^3)/3! + (x^5)/5! - (x^7)/7! + ...
atan(x) = x - (x^3)/3 + (x^5)/5 - (x^7)/7 + ...

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

cos(x) = 1 - (x^2)/2

с ошибкой порядка x^3 (на самом деле x^4, так как термин с x^3 в любом случае равен нулю).

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

...