我正在用Javascript进行汽车模拟,并且我正在使用该网站来帮助我进行物理研究:http://www.asawicki.info/Mirror/Car%20Physics%20for%20Games/Car%20Physics%20for%20Games.html
模拟的当前进度可以在我的网站上看到: https://cloudynet.tk/projects/car-sim/code.html
我遇到的问题是汽车转向物理学。我设法使低速转向正常工作,但是高速转向(引入了侧向力)很难实现。我了解滑移角如何影响横向力,但在我的仿真中,它的效果不是很好。我想知道横向力的实现是正确的还是代码有问题?另外,我不太了解纵向力和横向力是影响单个速度矢量还是分成两个“方向”矢量。
这是我当前的物理功能(可以在网站上查看整个代码):
applyPhysics() {
// Get car direction vector
let direction = new Vector(1, 0);
direction = Vector.rotate(direction, this.carAngle);
// LONGITUDINAL FORCES
// Traction forces
let tractionForce = direction.copy(); // Traction force (engine power)
if (this.engineForce) {
tractionForce.mult(this.engineForce);
}
else if (this.brakingForce) {
tractionForce.mult(-this.brakingForce);
}
// Frictional forces
let dragForce = this.velocity.copy(); // Air resistance force
dragForce.mult(this.velocity.getMag())
dragForce.mult(-this.drag);
let rollingResistanceForce = this.velocity.copy(); // Rolling resistance force (friction with ground)
rollingResistanceForce.mult(-this.rrDrag);
let netLongitudinalForce = tractionForce.copy(); // Total longitudinal force
netLongitudinalForce.add(dragForce)
netLongitudinalForce.add(rollingResistanceForce);
// Calculate acceleration
this.acceleration = netLongitudinalForce.copy();
this.acceleration.div(this.mass);
if (this.acceleration.getMag() < 0.001)
this.acceleration = new Vector();
// Calculate velocity
let accelerationDelta = this.acceleration.copy();
accelerationDelta.mult(dt);
this.velocity.add(accelerationDelta);
this.velDir = this.velocity.getDir();
this.sideslipAngle = this.carAngle - this.velDir; // Calculate side slip angle
if (this.speed > 20) { // High speed-turning
// LATERAL FORCES
let peakSlipAngle = 5;
// Calculate slip angle for back wheel
var c = this.wheels.baseline/2;
var omegaC = this.angularVelocity*c;
var longV = Math.cos(this.carAngle) * this.velocity.getMag();
var latV = Math.sin(this.carAngle) * this.velocity.getMag();
this.wheels.back.slipAngle = Math.atan(((latV - omegaC)/Math.abs(longV)) || 0);
var backSlipDeg = deg(this.wheels.back.slipAngle)
this.wheels.back.lateralForce = 5000*Math.sign(this.wheels.back.slipAngle);
if (backSlipDeg < peakSlipAngle && backSlipDeg > -peakSlipAngle) {
this.wheels.back.lateralForce = 5000*backSlipDeg/peakSlipAngle;
} else {
this.wheels.back.lateralForce = 5000*(1-((Math.abs(backSlipDeg)-peakSlipAngle)/500))*Math.sign(this.wheels.back.slipAngle);
}
// Calculate slip angle for front wheel
var b = this.wheels.baseline/2;
var omegaB = this.angularVelocity*b;
var longV = Math.cos(this.wheels.front.slipAngle) * this.velocity.getMag();
var latV = Math.sin(this.wheels.front.slipAngle) * this.velocity.getMag();
this.wheels.front.slipAngle = Math.atan((((latV - omegaB)/Math.abs(longV)) || 0)-this.steeringAngle*Math.sign(longV));
var frontSlipDeg = deg(this.wheels.front.slipAngle);
this.wheels.front.lateralForce = 5000*Math.sign(this.wheels.front.slipAngle);
if (frontSlipDeg < peakSlipAngle && frontSlipDeg > -peakSlipAngle) {
this.wheels.front.lateralForce = 5000*frontSlipDeg/peakSlipAngle;
} else {
this.wheels.front.lateralForce = 5000*(1-((Math.abs(frontSlipDeg)-peakSlipAngle)/500))*Math.sign(this.wheels.front.slipAngle);
}
// Calculate cornering force
this.corneringForce = this.wheels.back.lateralForce + Math.cos(this.steeringAngle) * this.wheels.front.lateralForce;
// Calculate centripetal force
this.centripetalForce = this.mass * (this.velocity.getMag() ** 2) / this.wheels.baseline/Math.sin(this.steeringAngle);
var lateralDirection = new Vector(0, -1);
lateralDirection = Vector.rotate(lateralDirection, this.carAngle);
let lateralForce = lateralDirection.copy();
lateralForce.mult(this.corneringForce);
this.latAcceleration = lateralForce.copy();
this.latAcceleration.div(this.mass);
if (this.latAcceleration.getMag() < 0.001)
this.latAcceleration = new Vector();
let latAccelerationDelta = this.latAcceleration.copy();
latAccelerationDelta.mult(dt);
this.latVelocity.add(latAccelerationDelta);
// Calculate position
let latVelocityDelta = this.latVelocity.copy();
latVelocityDelta.mult(dt);
this.pos.add(latVelocityDelta);
} else {
this.velocity = Vector.rotate(this.velocity, this.carAngle - this.velDir); // Correct velocity based on car orientation
}
// Calculate position
let velocityDelta = this.velocity.copy();
velocityDelta.mult(dt);
this.pos.add(velocityDelta);
// Calculate speed
this.speed = this.velocity.getMag();
}