Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Algorithm for following the path with a certain inertia

I’m trying to develop a game.

image demonstrating concept

I have a starting point with and starting vector (blue), next I draw on screen the path (black) which I want to follow with a certain inertia, or limited angle and step each turn that should result a red line.

Do you have any tips on how to program such algorithm?

like image 515
orko Avatar asked Oct 11 '22 09:10

orko


2 Answers

You can just create a differential scheme, i.e. model speed and coordinate of the source point at discrete moments in time. Say you fix some dt = 0.1 sec for example, starting speed is given by blue vector as v0. We start at x0. Say y[j] are the points of the black path.

Let x1 = x0 + v1 * dt, where v1 = v0 + (y[k(x0)+1] - x0) * f(abs(y[k(x0)+1] - x_0)). Where
k(x0) is the index of the nearest to x0 point among y[j],
f(x) is a function characterizing the 'force' pulling your trajectory to that of the defined path. It defined for nonnegative xes only.

This models pulling your trajectory to the next point in the defined path to that closest to current modeled position on the trajectory.

A good example of f(x) could be one modeling the gravitational force: f(x) = K/(x * x), where K should be adjusted experimentally to be giving natural desired results.

Then x2 = x1 + v2 * dt, where v2 = v1 + (y[k(x1) + 1] - x1) * f(abs(y[k(x1) + 1] - x_1)) and so on:

x[n+1] = x[n] + v[n+1] * dt, where v[n+1] = v[n] + (y[k(x[n]) + 1] - x[n]) * f(abs(y[k(x[n])+1] - x[n]))...

You'll have to adjust dt and K here. dt should be small enough for the trajectory to be smooth. Bigger K makes trajectory more close to defined precisely, smaller K makes it more relaxed.

Edit now actually when I thought a little bit, I understand that selection of the force function f was not good, as gravitational force allows space velocities, i.e. ability for your trajectory to fly away from the desired one infinitely if the initial speed is too big. So you should construct another function, possibly just something along the lines of f(x) = K x or f(x) = K x ^ alpha, where alpha > 0. You see, this scheme is quite general, so you should experiment.

like image 123
unkulunkulu Avatar answered Oct 12 '22 22:10

unkulunkulu


Another option would be to do something like this...

  1. Compute the average value of k points in the target path
     to get (<x>,<y>).
  2, Compte the angle between the most recent point in the path
     and (<x>,<y>) and turn that way; if the angle is too big,
     turn as hard as possible.
  3. Recompute (<x>,<y>) for the next set of k elements by sliding
     the window by 1; repeat step 2.

This could make for fairly appropriate behavior. I'd walk through an example, but this it would be fairly tedious. Note that this is similar to the method unkulunkulu outlines, but a little different in terms of an approach.

like image 38
Patrick87 Avatar answered Oct 12 '22 23:10

Patrick87