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.