Javascript精度缓解

Javascript精度缓解,javascript,three.js,game-physics,orbital-mechanics,Javascript,Three.js,Game Physics,Orbital Mechanics,我知道javascript舍入错误是相当棘手的,但我想得到一些建议 对于我的应用程序,减少舍入错误的最佳方法是什么?我有一个立方体,在一个大质量的轨道上。立方体在每一个轨道上都会获得大量的轨道动量,最终会在没有任何干预的情况下达到逃逸速度 我需要一个轻量级的方法来防止这种情况发生 我最好的办法是尝试并找到一种方法来修正我的数字,还是我最好使用基于逻辑假设的纠错方法,对其进行某种程度的篡改并将其放回原位 我的物理功能如下: function physPosition(object, delta){

我知道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; 
}
函数物理重力(a,b){
var grav=新的三个向量3(0,0,0);
重力=重力子向量(a位置,b位置);
var r=总长度sq();
var A=(G)*(b.质量)/(r);
grav=grav.normalize();
重力多重刻度(-A);
a、 重力=重力;

}

您正在尝试对运动方程进行数值积分。这是一个有效的解决方案——另一个是计算运动方程的解析解,正如德里克所建议的那样。问题是,您需要一个比您现在使用的解决方案更好的积分器。你应该试着去了解。我特别推荐,因为它们易于实现和使用


您还可以找到包含数值积分方法的JavaScript库,并使用这些方法,而不是实现自己的方法。有一个四阶Runge-Kutta方法的例子,其中包含一个名为
dopri

的休眠Prince积分器,而Derek的评论很有意义——如果可以的话,将所有函数参数化,而不是差分——有时你不能真正做到这一点,或者不容易做到。对于您的代码,另一种可能性(不确定现实程度)是尝试自己使用分数来降低错误,而不是依赖浮点运算,因为您没有任何不利于分数的公式(如平方根)

实现您自己的分数运算,始终保持分子和分母分开,并且仅在绝对需要时进行除法以计算点的坐标。这应该:提高精度,因为您的可用位数是原来的两倍;此外,浮点错误主要来自于在Base2中不可表示的内容,但您将拥有JavaScript所允许的尽可能多的整数。您可能需要不时地规范化分子和分母,因为它们可能会超出范围,这将重新引入一些错误,但不像使用普通浮点算法那样频繁地在每个除法中进行


显然,它也会让你慢一点,但JavaScript的计算速度相当快。

我处理累积错误的最好方法是用数学方程描述路径,而不是一遍遍地计算新值。记不起我的数学了。你能发布相关的公式吗?如果你有一个参数公式,就像德里克建议的那样,你就不会有这个问题,所以我假设你有一些
dx
dy
增量计算?我添加了相关的代码。它还计算每一物理帧的引力。我实际上在每一帧进行引力计算:
函数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.multilyscalar(-A);A.gravity=grav;}
代码需要能够处理我放在任何地方的任何对象,因此生成特定参数需要进行某种启发式线性回归。这听起来是一个有趣的挑战,我以后可能会试试。