Это проблема, с которой я столкнулся при попытке реализовать игру с использованием движка LÖVE, который охватывает box2d со сценариями Lua.
Цель проста: объект, похожий на башню (вид сверху, в 2D-окружении), должен сориентироваться так, чтобы он указывал на цель.
Турель находится в координатах x,y, а цель – в tx, ty. Мы можем считать, что x, y фиксированы, но tx, ty имеют тенденцию меняться от одного момента к другому (т. е. они будут курсором мыши).
Башня имеет ротор, который может прикладывать вращательную силу (крутящий момент) в любой момент по часовой стрелке или против часовой стрелки. Величина этой силы имеет верхний предел, называемый maxTorque.
Башня также имеет определенную инерцию вращения, которая действует для углового движения так же, как масса действует для линейного движения. Никакого трения нет, поэтому турель будет продолжать вращаться, если у нее есть угловая скорость.
У башни есть небольшая функция ИИ, которая переоценивает ее ориентацию, чтобы убедиться, что она указывает правильное направление, и активирует поворотное устройство. Это происходит каждые dt (~ 60 раз в секунду). Это выглядит так прямо сейчас:
function Turret:update(dt)
local x,y = self:getPositon()
local tx,ty = self:getTarget()
local maxTorque = self:getMaxTorque() -- max force of the turret rotor
local inertia = self:getInertia() -- the rotational inertia
local w = self:getAngularVelocity() -- current angular velocity of the turret
local angle = self:getAngle() -- the angle the turret is facing currently
-- the angle of the like that links the turret center with the target
local targetAngle = math.atan2(oy-y,ox-x)
local differenceAngle = _normalizeAngle(targetAngle - angle)
if(differenceAngle <= math.pi) then -- counter-clockwise is the shortest path
self:applyTorque(maxTorque)
else -- clockwise is the shortest path
self:applyTorque(-maxTorque)
end
end
... это не удается. Позвольте мне объяснить с двумя иллюстративными ситуациями:
- Башня «колеблется» вокруг целевого угла.
- Если цель находится «прямо за турелью, чуть по часовой стрелке», турель начнет применять крутящие моменты по часовой стрелке и будет продолжать применять их до момента, когда она превысит угол цели. В этот момент он начнет прикладывать крутящие моменты в противоположном направлении. Но он приобретет значительную угловую скорость, поэтому какое-то время будет двигаться по часовой стрелке... пока цель не окажется "сразу позади, но немного против часовой стрелки". И снова начнется. Таким образом, башня будет колебаться или даже ходить по кругу.
Я думаю, что моя башня должна начать применять крутящий момент в «противоположном направлении кратчайшего пути» до того, как она достигнет заданного угла (как автомобиль, тормозящий перед остановкой).
Интуитивно я думаю, что турель должна «начинать применять крутящий момент в направлении, противоположном кратчайшему пути, когда она находится примерно на полпути к цели». Моя интуиция подсказывает мне, что это как-то связано с угловой скоростью. А еще есть тот факт, что цель подвижна - я не знаю, следует ли мне это как-то учитывать или просто игнорировать.
Как рассчитать, когда башня должна "начать торможение"?