* Lưu ý: bài viết chỉ đưa ra ý tưởng, vẫn còn bug trong implement :D
Mô phỏng tên quĩ đạo tên lửa bay theo một mục tiêu:
Các thuộc tính của tên lửa:
phi
giới hạn cho trước. (không vượt quá phi_max
)Có thể thấy, hai yếu tố quan trọng ảnh hưởng tới việc đưa ra quyết định góc là vận tốc tên lửa và vị trí tương đối giữa tên lửa với target. Hai yếu tố này có thể biểu diễn thông qua:
frameDistance = distance / v
Trong đó:
Việc điều khiển tên lửa có thể biểu diễn thông qua hàm:
phi = f(alpha, frameDistance)
Có nhiều cách để chọn hàm f, và fuzzy là một phương pháp có thể được áp dụng tốt trong bài toán này.
Gọi m = max_phi
(*) Lưu ý: bảng tra fuzzy trên chỉ mang tính chất minh họa, cần kiểm tra, optimize trong điều kiện thực tế.
Bằng việc nội suy các giá trị từ bảng trên, ta có thể chọn một góc điều khiển tên lửa phù hợp
Demo được thực hiện bởi engine: http://www.giderosmobile.com/
distance = math.sqrt( ((misslePosX - targetPosX)^2) + ((misslePosY - targetPosY)^2) )
frameDistance = distance/gMissle.v
alpha = math.atan2(targetPosX - misslePosX, targetPosY - misslePosY)*180/3.14159 - 180 - gMissle.angle
Note: thực hiện trừ 180 vì hệ trục tọa độ máy tính y hướng xuống, ngược với hệ trục descarte
Ví dụ:
alpha = 42 độ
frameDistance = 70 pixels
Nội suy theo dòng và cột, dựa trên giá trị 3 ô: (4, 1) --> lut_o, (4, 2) --> lut_l, (5, 1) --> lut_b
Nội suy (tuyến tính) theo alpha:
phi_C = (alpha - lut_l)*(lut_o - lut_l) / (45 - 25)
Nội suy (tuyến tính) theo frameDistance:
phi_R = (frameDistance - lut_o)*(lut_d - lut_o) / (120 - 60)
Chọn phi theo min(phi_C, phi_R)
(Demo bằng LUA - Gideros)
local phi = math.min(phi_R, phi_C)
local rad = -gMissle.angle*3.14159/180
gMissle.angle = gMissle.angle - phi
local s = math.sin(rad)
local c = -math.cos(rad)
local dx, dy = gMissle.v*s, gMissle.v*c
gMissle:setPosition(misslePosX + dx, misslePosY + dy)
gMissle:setRotation(-gMissle.angle)
(dùng -gMissle.angle khi cập nhật góc xoay vì gideros có góc xoay ngược)
* Lưu ý: trong demo vẫn còn bug :D