2014-08-29 3 views
1

enter image description hereточности смягчение Javascript

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

Что было бы лучшим способом уменьшить ошибки округления для моего приложения? У меня есть куб в том, что СЛЕДУЕТ быть орбитой вокруг большой массы. Куб получает значительное количество орбитального момента на каждой орбите и, в конечном счете, достигнет скорости вылета без какого-либо вмешательства.

Мне нужен легкий метод, чтобы предотвратить это.

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

Функции для моей физики здесь:

function physPosition(object, delta){ 
// Update Position 
object.position.x += (object.velocity.x * delta) + (0.5*object.acceleration.x* (Math.pow(delta,2))); 
object.position.y += (object.velocity.y * delta) + (0.5*object.acceleration.y*(Math.pow(delta,2))); 
object.position.z += (object.velocity.z * delta) + (0.5*object.acceleration.z*(Math.pow(delta,2))); 

// Update Velocity (acceleration) 
object.velocity.x += object.acceleration.x * delta; 
object.velocity.y += object.acceleration.y * delta; 
object.velocity.z += object.acceleration.z * delta; 

// Update Velocity (gravity) 
object.velocity.x += object.gravity.x * delta; 
object.velocity.y += object.gravity.y * delta; 
object.velocity.z += object.gravity.z * delta; 

// Update Rotation 
object.rotation.x += object.spin.x * delta; 
object.rotation.y += object.spin.y * delta; 
object.rotation.z += object.spin.z * delta; 
} 

function physGravity(a, b){ var grav = new THREE.Vector3(0, 0, 0); grav = grav.subVectors(a.position, b.position); var r = grav.lengthSq(); var A = (G)*(b.mass)/(r); grav = grav.normalize(); grav.multiplyScalar(-A); a.gravity = grav; }

+0

Лучший способ справиться с накопленными ошибками imo - описать путь с математическими уравнениями, вместо этого вычисляя новые значения снова и снова. –

+0

Не могу вспомнить свою математику. Можете ли вы разместить соответствующие формулы? Если у вас есть параметрическая формула, как предлагает Дерек, у вас не будет этой проблемы, поэтому я предполагаю, что вы используете инкрементный расчет 'dx' и' dy'? – Amadan

+0

Я добавил соответствующий код. Он также вычисляет гравитационное притяжение в каждой физической структуре. –

ответ

2

Вы пытаетесь сделать численное интегрирование уравнений движения. Это одно действительное решение - другое - вычислить аналитическое решение уравнений движения, как предложил Дерек. Дело в том, что вам нужен лучший интегратор, чем решение, которое вы используете сейчас. Вы должны попытаться узнать о numerical integration. В частности, я бы рекомендовал Runge-Kutta methods, так как их легко реализовать и использовать.

Вы также можете найти библиотеку JavaScript, которая содержит методы цифровой интеграции, и использовать их, а не использовать свои собственные. Существует пример here с методом Рунге-Кутты четвертого порядка, а Numeric JavaScript library содержит интегратор Dormand-Prince под названием dopri.

+0

Я посмотрю, спасибо, спасибо! –

0

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

Реализовать свою собственную арифметику, всегда сохраняя числитель и знаменатель отдельно и делясь только тогда, когда вам абсолютно необходимо, чтобы вычислить координаты точки. Это должно: повысить точность, поскольку у вас удваивается доступное количество бит; Кроме того, ошибка с плавающей запятой происходит в основном из вещей, которые не представляются в базе 2, но у вас будут такие же целые числа, как и JavaScript. Вам может потребоваться время от времени нормализовать числитель и знаменатель, поскольку они угрожают выйти из диапазона, что приведет к повторной ошибке, но реже, чем к каждому подразделению, как вы делаете с простой арифметикой с плавающей запятой.

Очевидно, что это также замедлит вас, но JavaScript довольно быстро вычисляется.

+0

Я действительно делаю вычисления гравитации в каждом кадре: 'function physGravity (a, b) { \t var grav = new THREE.Vector3 (0, 0, 0); \t grav = grav.subVectors (a.position, b.position); \t var r = grav.lengthSq(); \t var A = (G) * (b.mass)/(r); \t grav = grav.normalize(); \t grav.multiplyScalar (-A); \t a.gravity = grav; } '}' Код должен иметь возможность обрабатывать любой объект, который я помещал в любом месте, поэтому для создания определенных параметров потребуется создание какой-то эвристической линейной регрессии. Это звучит весело, и я могу попробовать это позже. –

Смежные вопросы