I’m trying to develop a game.
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?
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))
. Wherek(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 x
es 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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With