使用力

时间:2015-06-30 07:38:34

标签: 3d gravity orbit

我在一个游戏引擎中有一个3d对象A和B.物体A是行星,具有无限质量,不移动。 我有一个半径常数,它定义了一个固定的轨道球体(我希望objectb位于它的边缘的球体)。 并且物体B受到来自其他物体的聚集的随机力的作用,因此已经存在作用于它的力。 如何使物体B与物体B保持相同的距离(保持球体的半径)? 我知道雅各比方程有一些复杂的计算,但我试图避免这种情况。 目前我在做:

gravity_vector = planetcentercoordinate - objectBposition

distance_number = size(gravity_vector) - >只是两个物体的距离

IF distance_number> radius THEN gravity_vector = - gravity_vector - >如果物体通过球体轨道进入行星核心,则反转力

force = gravity_vector

如果我这样做的话,物体会按照意图进入轨道球体的方向,但它只是反弹太多...... 还有另一种简单的方法可以做到这一点,或者如果距离较小可能会对力进行校正?

1 个答案:

答案 0 :(得分:1)

Javascript中的一个例子(为简洁起见省略了一些部分):我有一个CelestialBody函数(一个"类"),它返回一个表示空间中的物体的对象(行星,星球)等等......)

function CelestialBody(mass, velocity, mesh){

    this.forceBetween = function(body){
        var squareDistance = this.squareDistanceFrom(body);
        var force = Constants.G * (this.mass * body.mass) / squareDistance;
        return force;
    };

    this.addForceContribution = function(body){
        var forceMagnitude = this.forceBetween(body);
        var distance = this.distanceFrom(body);
        var xDiff = body.getPosition().x - this.getPosition().x;
        var yDiff = body.getPosition().y - this.getPosition().y;
        var zDiff = body.getPosition().z - this.getPosition().z;

        var xRatio = xDiff / distance;
        var yRatio = yDiff / distance;
        var zRatio = zDiff / distance;

        var fx = forceMagnitude * xRatio;
        var fy = forceMagnitude * yRatio;
        var fz = forceMagnitude * zRatio;

        var forceVector = new THREE.Vector3(fx, fy, fz);

        this.acceleration.add(forceVector.divideScalar(this.mass));
    };

    this.updatePosition = function(delta){
        if(!delta){
            delta = Constants.DEFAULT_TIME_DELTA; // just to make debugging possible
        }
        this.velocity = this.velocity.add(this.acceleration.multiplyScalar(delta));
        var tempVelocity = this.velocity.clone();
        var nextPosition = this.getPosition().clone(); 
        nextPosition.add( tempVelocity.multiplyScalar(delta) );

        this.mesh.position.x = nextPosition.x;
        this.mesh.position.y = nextPosition.y;
        this.mesh.position.z = nextPosition.z;

        this.acceleration = new THREE.Vector3(0, 0, 0);
    };
}

在主游戏循环中,每一步,每个身体,我都会考虑任何其他身体的重力贡献并相应地更新位置:

for (var i = 0; i < celestialBodies.length; i++) {
        for (var j = 0; j < celestialBodies.length; j++) {
            if (celestialBodies[i] === celestialBodies[j]) {
                continue;
            }

            celestialBodies[i].addForceContribution(celestialBodies[j]);
        }
    }

    for (var i = 0; i < celestialBodies.length; i++) {
        celestialBodies[i].updatePosition();

        // check if the body is gone too far: if so, marks it for removal
        if (celestialBodies[i].getPosition().distanceTo(new THREE.Vector3(0, 0, 0)) > Constants.REMOVAL_DISTANCE_THRESHOLD) {
            celestialBodies[i].markedForRemoval = true;
        }
    }

完整代码为here,结果为here