cookertron
cookertron

Reputation: 198

Slowing to a stop using a set distance and time

I'm not a great maths person but I had a little go at solving this problem myself using python.

What I'm trying to achieve is a one dimensional point starting at position 0 that travels to a random position that's less than equal to 720. If the point travels to the maximum distance of 720 then it will take 0.5secs. The point also needs to slow to a stop within that time and random position.

This is what I've done so far, but obviously it's wrong.

fps = 60
maxx = 720

x = 0 
px = rnd(0, maxx)
t = fps * (px / maxx)
s = 2.0 * px / (t * (t - 1))
v = s * t

while v > 0:
  x += v
  v -= s

print (x)

If px = 360 then the result of x is 384.82758620689657 when it should be 360.

Thank you for your help.

Upvotes: 0

Views: 83

Answers (1)

Alexandr Shurigin
Alexandr Shurigin

Reputation: 3981

Ok, it seems like you are interested in some sort of "moving animation" what is called in CSS usually "easing".

I've found a few examples with multiple easings & their implementations & created some base source code where you can try it with X coords output :)

It looks great to me! Play with it :)

from random import randint


# check more easings at websites:
# https://gist.github.com/th0ma5w/9883420
# https://easings.net/en#easeOutQuad
def easeInQuad(t, b, c, d):
    t /= d
    return c * t * t + b


fps = 60
maxx = 720
px = randint(0, maxx)
t = fps * (px / maxx)

print('Going to x={}'.format(px))
points = []
for i in range(int(t) + 1):
    points.append(str(round(easeInQuad(i, 0, px, t))))

# Just make sure we stop at teh destination fixel
if points[-1] != str(px):
    points[-1] = str(px)

print('X coords per frame tick: {}'.format(", ".join(points)))

Outputs

Going to x=409
X coords per frame tick: 0, 0, 1, 3, 6, 9, 13, 17, 23, 29, 35, 43, 51, 60, 69, 79, 90, 102, 114, 127, 141, 155, 170, 186, 203, 220, 238, 257, 276, 296, 317, 338, 361, 383, 409

Check more easing types (math formulas) and their python analogs at

Example with easeOutQuint

The requested solution #2 :)

from random import randint


# check more easings at websites:
# https://gist.github.com/th0ma5w/9883420
# https://easings.net/en#easeOutQuad
def easeOutQuint(t, b, c, d):
    t /= d
    t -= 1
    return c * (t * t * t * t * t + 1) + b


fps = 60
maxx = 720
px = randint(0, maxx)
t = fps * (px / maxx)

print('Going to x={}'.format(px))
points = []
for i in range(int(t) + 1):
    points.append(str(round(easeOutQuint(i, 0, px, t))))

# Just make sure we stop at teh destination fixel
if points[-1] != str(px):
    points[-1] = str(px)

print('X coords per frame tick: {}'.format(", ".join(points)))

Outputs

# > python test.py
Going to x=703
X coords per frame tick: 0, 58, 112, 162, 209, 253, 293, 331, 366, 398, 427, 454, 480, 502, 524, 543, 560, 576, 591, 604, 616, 627, 636, 645, 653, 659, 666, 671, 676, 680, 684, 687, 689, 692, 694, 696, 697, 698, 699, 700, 701, 701, 702, 702, 702, 703, 703, 703, 703, 703, 703, 703, 703, 703, 703, 703, 703, 703, 703

Upvotes: 1

Related Questions