Ready. Aim. FIRE!
If you've ever programmed a game, then you know that physics is critical to realistic play.No, I am not going to explain how to build a physics engine. I just started with the basics.
How to Launch Things
Whether it is catapults, tanks or worms with slingshots, the most important thing is: whatever goes up must come down... specifically in a parabolic trajectory.
Now, computers are smart, but they're also dumb. It would be nice if we could just tell it a speed and an angle and have it determine everything else. OR give it an x,y coordinate and have it calculate the speed and angle. But computers don't solve algebra equations unless we tell them how. They just plug-n-chug input and give output.
That means we have to do the algebra ourselves. *Sigh*
Programming basic kinematics is the easy part. We provide the initial position, speed, angle and time since "launch" and we can determine the speed, direction and position. Do this 60 times a second and we can animate it. If you need a refresher on the big four, I recommend Khan Academy.
The only real challenge making this app was solving the algebra to adjust the angle of launch based on a selected (arbitrary) target. If you plug the final position into the big four and solve for the angle, you get something pretty ugly. A few trigonometric identities and a quadratic formula later we get this code:
//global declarations var g = -9.80665; var time = 0; //time var v0 = 10;//initial velocity (muzzle) var theta = Math.PI/4;//trajectory angle var x0 = 0;//initial position var y0 = 0; var target = {"X":0,"y":0,"active":false}; //x and y are the coordinates that were clicked by the user function defineTrajectory(x,y){ tanTheta1 = quadraticFormula(g*x*x/(2*v0*v0),x,-(y-y0)+(g*x*x/(2*v0*v0)),1); tanTheta2 = quadraticFormula(g*x*x/(2*v0*v0),x,-(y-y0)+(g*x*x/(2*v0*v0)),-1); //two solutions, so we pick positive first if (tanTheta1 > 0) theta = Math.atan(tanTheta1); else theta = Math.atan(tanTheta2); //this updates the visual layout to reflect the angle $('#angle').val(theta*180/Math.PI); //this tells us where to draw the big red target target.x = x; target.y = y; target.active = true; //then we calculate the rest of the trajectory //using the big four and then draw the scene calcValues(); drawScene(); drawTrajectory(); } function quadraticFormula(a,b,c,sign){ if (b*b-(4*a*c) < 0) return false;//imaginary solution return (-b+(sign*Math.sqrt(b*b-(4*a*c))))/(2*a); }
What happens if there isn't enough speed to reach the selected point, no matter the angle? I'll leave that for someone else to decide. On to the next project! Orbital trajectories!
0 comments: