Question

I was in need of a little math help that I can't seem to find the answer to, any links to documentation would be greatly appreciated.

Heres my situation, I have no idea where I am in this maze, but I need to move around and find my way back to the start. I was thinking of implementing a waypoint list of places i've been offset from my start at 0,0. This is a 2D cartesian plane.

I've been given 2 properties, my translation speed from 0-1 and my rotation speed from -1 to 1. -1 is very left and +1 is very right. These are speed and not angles so thats where my problem lies. If I'm given 0 as a translation speed and 0.2 I will continually turn to my right at a slow speed.

How do I figure out the offsets given these 2 variables? I can store it every time I take a 'step'.

I just need to figure out the offsets in x and y terms given the translations and rotation speeds. And the rotation to get to those points.

Any help is appreciated.

Was it helpful?

Solution

Your question is unclear on a couple of points, so I have to make some assumptions:

  1. During each time interval, translation speed and rotational velocity are constant.
  2. You know the values of these variables in every time interval (and you know rotational velocity in usable units, like radians per second, not just "very left").
  3. You know initial heading.
  4. You can maintain enough precision that roundoff error is not a problem.

Given that, there is an exact solution. First the easy part:

delta_angle = omega * delta_t

Where omega is the angular velocity. The distance traveled (maybe along a curve) is

dist = speed * delta_t

and the radius of the curve is

radius = dist / delta_angle

(This gets huge when angular velocity is near zero-- we'll deal with that in a moment.) If angle (at the beginning of the interval) is zero, defined as pointing in the +x direction, then the translation in the interval is easy, and we'll call it deta_x_0 and delta_y_0:

delta_x_0 = radius * sin(delta_angle)
delta_y_0 = radius * (1 - cos(delta_angle))

Since we want to be able to deal with very small delta_angle and very large radius, we'll expand sin and cos, and use this only when angular velocity is close to zero:

dx0 = r * sin(da)     = (dist/da) * [ da - da^3/3! + da^5/5! - ...]
                     =  dist     * [  1 - da^2/3! + da^4/5! - ...]

dy0 = r * (1-cos(da)) = (dist/da) * [ da^2/2! - da^4/4! + da^6/6! - ...]
                     =  dist     * [   da/2! - da^3/4! + da^5/6! - ...]

But angle generally isn't equal to zero, so we have to rotate these displacements:

dx = cos(angle) * dx0 - sin(angle) * dy0
dy = sin(angle) * dx0 - cos(angle) * dy0

OTHER TIPS

You could do it in two stages. First work out the change of direction to get a new direction vector and then secondly work out the new position using this new direction. Something like

angle = angle + omega * delta_t;

const double d_x = cos( angle );
const double d_y = sin( angle );

x = x + d_x * delta_t * v;
y = y + d_y * delta_t * v;

where you store your current angle out at each step. ( d_x, d_y ) is the current direction vector and omega is the rotation speed that you have. delta_t is obviously your timestep and v is your speed.

This may be too naive to split it up into two distinct stages. I'm not sure I haven't really thought it through too much and haven't tested it but if it works let me know!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top