질문의 맥락에 비추어 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;
}
덜 간단한 공식. 당신이 결국 멈추기를 원하기 때문에 계속 돌리고 싶지 않은 지점이 올 것입니다. 다행스럽게도, 각속도 캡은 최대 각속도에서 0으로 빠르게 감속 할 수 있음을 의미합니다. 그렇게 할 때만 계산하면됩니다.
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 사이의 추력을 선택할 수 있다는 사실에 의존 할 수 있습니다. 이것은 실제 값을 변경하지 않고 효과적인 부분 추력을 제공합니다.
행운을 빕니다!