Trong bối cảnh câu hỏi của bạn, http://nodewar.com/ , có một vài cân nhắc cụ thể cho giải pháp của bạn:
- Bạn có tốc độ góc tối đa (thấp) và đủ mô-men xoắn cực đại để đạt được nó trong thời gian rất ngắn.
- Máy bay không người lái và mục tiêu của bạn đều có vận tốc và gia tốc bên ngoài không liên quan đến lực đẩy (trọng lực rất nhiều).
- Mục tiêu mong muốn của bạn thay đổi thường xuyên đến mức cố gắng nhắm hoàn hảo sẽ là một sự lãng phí. Bạn nên cố gắng để gần gũi, và sửa nó mọi khung hình.
Những phương pháp này là những gì tôi xác định để làm việc để đạt được gia tốc mong muốn.
Tăng tốc, không phải vận tốc
Bởi vì bạn đã có một vận tốc nhất định và mục tiêu của bạn đang di chuyển, bạn không cần lực đẩy về một điểm. Bạn cần lực đẩy để thay đổi vận tốc của bạn đến mức cần thiết. Điều này có nghĩa là tàu của bạn cần hướng không phải là nơi nó sẽ đi, mà theo hướng mà nó sẽ tăng tốc.
// 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)
);
Hướng về phía bên phải
Bạn có một vectơ gia tốc, bây giờ bạn muốn áp dụng nó. Xác định khoảng cách bạn cần xoay. Tôi có thể đã sử dụng nhiều bước hơn yêu cầu ở đây, nhưng tọa độ quay làm tôi bối rối và tôi nghĩ rằng giá trị xoay vòng của tàu chưa được khai thác là một lỗi trong 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;
}
Một công thức đơn giản. Không có hại trong việc xoay mọi lúc, vì vậy đừng bận tâm áp dụng các giá trị mô-men xoắn một phần. Nếu bạn cần một sự điều chỉnh nhỏ về tốc độ góc, bạn có thể đưa ra quyết định này nhiều lần trong một giây.
if (traj_correction > 0){
torque = 1;
} else if (traj_correction < 0){
torque = -1;
}
Một công thức ít đơn giản hơn. Sẽ đến một điểm mà bạn không muốn tiếp tục rẽ, bởi vì cuối cùng bạn muốn dừng lại. May mắn thay, nắp tốc độ góc đó có nghĩa là bạn có thể nhanh chóng giảm tốc độ từ tốc độ góc tối đa xuống không. Bạn chỉ cần tính toán khi làm như vậy.
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;
}
Sau khi điều chỉnh mã ở trên cho phù hợp với nhu cầu của bạn, tàu của bạn sẽ nhanh chóng và chính xác xoay theo bất kỳ góc nào bạn đưa ra để nhắm mục tiêu.
Tốc độ tăng tốc
Vậy, khi nào cần đẩy? Một lần nữa, sự thay đổi nhanh chóng của mục tiêu và các yếu tố khác tạo ra khó khăn lớn trong việc giải quyết một giải pháp chính xác. Đừng cố gắng.
// 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;
}
}
Đối với những trường hợp bạn cần lực đẩy một phần, bạn có thể một lần nữa dựa vào thực tế là bạn có thể chọn lực đẩy từ 0 đến 1 nhiều lần trong một giây. Điều này cung cấp cho bạn một lực đẩy một phần hiệu quả mà không thay đổi giá trị thực tế.
Chúc may mắn!