Skip to content
Advertisement

Formula to calculate time needed for a ball to reach destination where the ball’s x y is updated in a time loop

I am coding a simulation of ball movement. I have an updateBall function which runs every 100 miliseconds to update the location of the ball.

How is the formula to find out the time in miliseconds needed to reach a given target coordinate? For example, given target x=100 y=200 the time needed to reach is approximately 5300ms.

Below is the relevant code snippet,

        function calcDirection(a, b, c, d)
        { return 180 * Math.atan2(d - b, c - a) / Math.PI };

        let ball = {x: 0, y: 0} 

        let targetX = 100;
        let targetY = 200;

        let velocity = 0.05;
        let friction = 0.0003;

        let direction = calcDirection(ball.x,ball.y,targetX,targetY); //63.43494882292201

        let dx = targetX - ball.x;
        let dy = targetY - ball.y;
        let distance = Math.sqrt(dx*dx + dy*dy); //223.60679774997897

        // runs every 100ms
        function updateBall(){
            if (velocity > 0) {
                let pixelsPerLoop = velocity * 100;
                
                ball.x += pixelsPerLoop * Math.cos(Math.PI/180 * direction);
                ball.y += pixelsPerLoop * Math.sin(Math.PI/180 * direction);
                velocity -= friction; 
            }
        }

    //answer: ( v0 (+/-) sqrt( v0^2 - 2.0*friction*dist ) )/(friction)
    let v0 = velocity * 100;
    let fric = friction * 100;
    let p = Math.pow(v0, 2);
    let q = 2.0 * fric * distance;
    let r = p - q;
    let s = Math.sqrt(r);
    let t = ( v0 - s )/(fric);

    // test run for loop times
    let loop = Math.floor(t);
    for (let i = 0; i < loop; i++)
        updateBall();
            
        document.getElementById('result').innerHTML = 'loop ' + loop + ', ball.x = ' + ball.x + ' ball.y = ' + ball.y; 
<p id="result"></p>

Advertisement

Answer

My math is a bit rusty so if I am not mistaken it should be like this:

v(t) = v0 - friction*t // speed
s(t)  = Integral(v(t))  // position or signed traveled distance if start position is zero
-------------------------------
s(t)  = v0*t - 0.5*friction*t^2 // s(t) = dist (distance to target)
dist  = v0*t - 0.5*friction*t^2
0.5*friction*t^2 - v0*t  + dist = 0
-----------------------------------
t = ( v0 (+/-) sqrt( v0^2 - 2.0*friction*dist ) )/(friction)

where t is time and dist is the distance from start to target.

so you got 2 solutions for t so use the one that makes sense (non negative). If there is no such one it means your ball never gets to your target.

Btw once you want to add stuff like gravity and other force fields or obstacles then you should change your math/physics to Newton D’Alembert integration instead of using direction vector to convert your problem to 1D as that is rather limiting.

[Edit2]

Do not forget to use compatible units as you use 0.1 sec interval for update and also you multiply speed by 100 so:

friction = 0.0003/0.1 = 0.003 m/s^2
v0 = 0.05*100/0.1         = 50.0 m/s
dist = sqrt(100^2 + 200^2) = 223.6068 m

t = ( v0 (+/-) sqrt( v0^2 - 2.0*friction*dist ) )/(friction)
t = ( 50 (+/-) sqrt( 2500 - 2.0*0.003*223.6068 ) )/(0.003)
t = ( 50 (+/-) sqrt( 2500 - 1.3416408 ) )/(0.003)
t = ( 50 (+/-) sqrt( 2498.6583592 ) )/(0.003)
t = ( 50 (+/-) 49.9566 )/(0.003)
t1 = 33328.8603075022
t2 = 4.47273608634165

so you reach the target in 4.47 sec … Here values of your simulation ported to C++:

t     v       x       y
0.0   5.000   2.236   4.472
0.1   4.999   4.472   8.944
0.2   4.999   6.708  13.416
0.3   4.999   8.943  17.887
0.4   4.999  11.179  22.358
0.5   4.998  13.414  26.829
0.6   4.998  15.650  31.299
0.7   4.998  17.885  35.770
0.8   4.997  20.120  40.240
0.9   4.997  22.355  44.709
1.0   4.997  24.589  49.179
1.1   4.996  26.824  53.648
1.2   4.996  29.058  58.117
1.3   4.996  31.293  62.585
1.4   4.996  33.527  67.054
1.5   4.995  35.761  71.522
1.6   4.995  37.995  75.990
1.7   4.995  40.229  80.457
1.8   4.994  42.462  84.925
1.9   4.994  44.696  89.392
2.0   4.994  46.929  93.859
2.1   4.993  49.163  98.325
2.2   4.993  51.396 102.791
2.3   4.993  53.629 107.257
2.4   4.993  55.861 111.723
2.5   4.992  58.094 116.188
2.6   4.992  60.327 120.654
2.7   4.992  62.559 125.118
2.8   4.991  64.792 129.583
2.9   4.991  67.024 134.047
3.0   4.991  69.256 138.511
3.1   4.990  71.488 142.975
3.2   4.990  73.719 147.439
3.3   4.990  75.951 151.902
3.4   4.990  78.183 156.365
3.5   4.989  80.414 160.828
3.6   4.989  82.645 165.290
3.7   4.989  84.876 169.753
3.8   4.988  87.107 174.215
3.9   4.988  89.338 178.676
4.0   4.988  91.569 183.138
4.1   4.987  93.799 187.599
4.2   4.987  96.030 192.060
4.3   4.987  98.260 196.520
4.4   4.987 100.490 200.981

As you can see your simulation reaches the target slightly before 4.5 sec However yours 5.3 sec result is way too far off so there still must be something fishy.

Also Real friction behaves differently and it scales up actual speed instead so it would by applied like this:

v *= 1.0-friction*dt*v^2;

where dt is the interval you update with so dt=0.1 however then the above equations will no longer work as it changes the v(t) function too.

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement