So I have this mathproblem that's been bugging me.
I'm writing the pathing code for a tank, that is, an entity which cannot turn on spot, but rather needs to rotate to his target while moving.
Up unitl now I've been using some code as described in this article and it has done me well (sorta). A problem has occured however, which has led me to
rewrite the movement-code. Previously I calculated the turns and stretches beforehand, but now I want to do it while driving.
Every time I update i find the direction toward the current pathnode, and the direction I'm currently facing. Since I know the rotationspeed of the tank, i limit the
new direction by interpolating between the current direction and the target direction, using the max rotation as t.
Like this:
function Tank:get_path_direction(dt)
local old_pos = self.position:unbox()
local forward = self.target_dir:unbox()
local current_path_node = self.path[self.path_index]:unbox()
local to_next = current_path_node - old_pos
local dir_to_next = Vector3.normalize(to_next)
local dp = Vector3.dot(forward, dir_to_next)
local backing = false
if dp < 0 then -- backing
backing = true
forward = -forward
dp = Vector3.dot(forward, dir_to_next)
end
local angle = math.acos(dp)
local path_dir = Vector3.zero()
local rotation_speed = self.rotation_speed
local rotation_this_frame = rotation_speed * dt
if math.abs(dp) < 0.995 then
if angle < rotation_this_frame then -- if the angle is less than our maximum rotation this frame
path_dir = dir_to_next
else
local alpha = rotation_this_frame / angle
path_dir = vector_slerp(forward, dir_to_next, alpha)
end
else
path_dir = dir_to_next
end
if Vector3.length(to_next) < 0.1 then
path_dir = path_dir * 0.1
self.path_index = self.path_index + 1
if self.path_index > #self.path then
self:abort()
end
end
if path then
if Vector3.distance(old_pos, self.path[#self.path]:unbox()) < self.target_radius then
self:abort()
return Vector3.zero(), false
end
end
return path_dir, backing
end
This works fine. I would however like to limit the speed to the steepness of the curve. The tank has got to slow down for steeper curves and so on.
I have illustrated the problem like this:
Where P is the starting-point, d is the starting direction of the tank, and G is the goal point.
After moving and rotating for a number of frames i'm heading in the right direction, thus I have no need to keep rotating.
The problem is finding the length of the curve beforehand so I know what my speedlimit is.
Any ideas?
Thanks
/Christoffer