# Calculating speed from angle of turn

This topic is 2936 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi!
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

##### Share on other sites
As a crude first attempt you could do something like:

At any moment you know the linear distance from P->G
You know the angle between vectors PD and PG
You know the angular rate allowable at a given linear velocity.
So, you can do
TimeToCompleteAngularTurn = AngleToTurn / MaxAngularRateAllowedAtOurCurrentLinearSpeed
TimeToArriveAtG = PG.length() / Linear Speed

If the time taken to rotate to face point G is greater than the time to arrive there at the current speed, your arc would overshoot, and you have to slow down.
This is crude because in reality the distance from P->G is not a straight line, but I think it might be a close enough approximation for what you want to do.

##### Share on other sites
Further thought:

Given a max (current) turn rate of "PHI" in deg/s and a velocity "V".
The time, "t", to complete an entire 360 turn is (360 deg / PHI)
The circumferential distance traveled is V*t.
Circumference is 2*PI*r
so r = can be calculated from V*360 / 2*PI*PHI

So now you have a circle of radius "r"
It's center point will be "r" units away from "P" the current location of your tank, perpendicular from it's velocity vector (towards the side that point "G" is on).
Now you have a circle of radius "r" centered at "O", with a chord created by the line described by points "P" and "G"
Find the length of this chord. If that chord length is greater than the distance from P-G, then your radius of turn is too shallow and you will overshoot point "G".

• ### Game Developer Survey

We are looking for qualified game developers to participate in a 10-minute online survey. Qualified participants will be offered a \$15 incentive for your time and insights. Click here to start!

• 13
• 30
• 9
• 16
• 12