目标很简单:一个炮塔状物体(从上面看,处于2D环境中)需要定位自己,使其指向一个目标。
炮塔位于x、y坐标上,目标位于tx、ty上。我们可以认为x、y是固定的,但tx、ty往往会因时间而变化(例如鼠标光标)。
炮塔有一个转子,可以在任何时刻施加旋转力矩,顺时针或逆时针。该力矩的大小有一个上限,称为maxTorque。
炮塔还有一定的旋转惯量,对于角动量的运动起到与质量对于线性运动的作用相同的作用。没有任何形式的摩擦力,因此如果具有角速度,则炮塔将继续旋转。
炮塔有一个小型AI函数,重新评估其方向以验证其是否指向正确的方向,并激活旋转器。这发生在每个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
......它失败了。让我用两个例子来解释一下:
- 炮塔在目标角度周围“振荡”。
- 如果目标“就在炮塔的右后方,稍微顺时针”,则炮塔将开始施加顺时针扭矩,并继续施加,直到超过目标角度的瞬间。此时它将开始朝相反方向施加扭矩。但是它已经获得了很大的角速度,因此它会继续顺时针旋转一段时间……直到目标变成“稍微逆时针”的位置。然后它又会重新开始。因此,炮塔将振荡甚至绕圈。
我认为我的炮塔应该在达到目标角度之前开始施加“最短路径的相反方向”的扭矩(就像汽车在停止之前刹车)。
直觉告诉我,当炮塔到达目标的一半时,它应该“开始施加最短路径相反方向的扭矩”。我的直觉告诉我这与角速度有关。然后还有一个事实,即目标是移动的-我不知道是否应该以某种方式考虑它,还是只需忽略它。
我如何计算炮塔必须“开始刹车”的时间?