質問のコンテキストhttp://nodewar.com/に照らして、ソリューションにはいくつかの特定の考慮事項があります。
- (低い)最大角速度と、非常に短い時間でそれに到達するのに十分な最大トルクがあります。
- ドローンとターゲットには、推力とは関係のない速度と外部加速度があります(重力が豊富です)。
- 目的のターゲットは頻繁に変更されるため、完璧に狙うことは無駄です。近づいて、フレームごとに修正する必要があります。
これらの方法は、私が望ましい加速に到達するために働くと決めたものです。
速度ではなく加速
すでに一定の速度があり、ターゲットが動いているので、ポイントに向かって推力をかける必要はありません。速度を本来の速度に変更するには、推力が必要です。これは、船がどこに向かっているかではなく、加速する方向を向いている必要があることを意味します。
// My target velocity is for maintaining a circular orbit. Yours may differ.
// Earlier, I calculated total gravity and the perpendicular direction.
// You may wish to subtract gravity from your total, rather than match it.
var targetVel = o.lib.vec.times(lateralDir, targetVelMag);
var targetAccel = lv.sum(
o.lib.vec.diff(targetVel, o.me.vel),
o.lib.vec.times(gravity, 1 / o.me.mass)
);
右向きのステアリング
加速度ベクトルがあるので、それを適用します。回転する必要がある距離を決定します。ここでは必要以上に多くのステップを使用した可能性がありますが、回転座標に混乱が生じ、キャップされていない船の回転値はとにかくAPIのバグだと思います。
// convert acceleration to an angle
var polar = o.lib.vec.toPolar(targetAccel);
var traj = polar[1];
// constrain the angle to +/-2PI, because the ship's rotation is not limited
// by default
var fixed_rot = o.lib.ang.rescale(o.me.rot);
// limit the correction to be +/-1PI
var traj_correction = traj - fixed_rot;
if (traj_correction > (Math.PI)){
traj_correction = (2 * Math.PI) - traj_correction;
} else if (traj_correction < (-1 * Math.PI)){
traj_correction = (2 * Math.PI) + traj_correction;
}
単純な式。常に回しても害はないので、部分的なトルク値を適用する手間をかけないでください。角速度の小さな補正が必要な場合は、とにかくこの決定を毎秒何回も行う必要があります。
if (traj_correction > 0){
torque = 1;
} else if (traj_correction < 0){
torque = -1;
}
それほど単純ではない式。最終的に停止したいので、方向転換を続けたくない点があります。幸いにも、その角速度の上限は、最大角速度からゼロまで急速に減速できることを意味します。計算する必要があるのは、いつ計算するかだけです。
var max_a_accel = c.MAX_TORQUE / o.me.m_i;
var a_deccel_time = Math.abs(o.me.a_vel) / max_a_accel;
// the same math as linear acceleration, now in angles.
var stopping_angle = 0.5 * max_a_accel * a_deccel_time * a_deccel_time;
if (stopping_angle >= Math.abs(traj_correction)){
// slowdown required. Reverse torque
torque *= -1;
}
上記のコードを微調整してニーズに合わせた後、ターゲットに向けた角度に応じて、船をすばやく正確に回転させる必要があります。
ラミング速度
それで、いつ突き出すのですか?繰り返しになりますが、ターゲットやその他の要因が急速に変化すると、正確な解決策を解決することが非常に困難になります。しようとしないでください。
// if the heading is close to the final value, thrust.
if (Math.abs(traj_correction ) < 0.02) { // about 1 degree
if (true
// some logical test, in case you don't want to accelerate past
// a maximum speed, or some such. Not required for your stated purpose.
){
thrust = 1;
}
}
部分的な推力が必要なケースでは、毎秒0から1の推力を何度も選択できるという事実を信頼できます。これにより、実際の値を変えることなく、効果的な部分推力が得られます。
幸運を!