Back in [Newsletter Issue No. 126], I provided an [article] about the mathematics of projectile motion in 2D space. This information is useful if you want to write a [Liberty BASIC] program to, say, track the path of a basketball as it is shot toward the basket, or shot toward the concession stand, which would be the case if I launched one from three-point range.
In this article, I will talk about projectile motion in 3D space. I will get right into the programming, and leave out any derivations. I think it will be more useful than the [2D article] despite the fact that we advance from 2D space to 3D space.
Let's start by establishing a system of coordinates in our 3D space, as shown in the figure below. I prefer to use the Y axis as the vertical axis, although some people like to use Z as vertical.
Next, let's place a cannon in our space. In the figure, the cannon will be represented as a thick blue line. The butt end of the cannon will be fixed at the origin of our space, and the shaft of the cannon will extend down the x-axis. The length of the cannon will be stored in the variable LengthCannon.
Next, rotate the shaft of the cannon away from the x-axis, and toward the z-axis as shown in the figure below. In this article, I will call this type of rotation a "swivel", as in "Swivel it clockwise, Jim-Bob!". The swivel angle in degrees can be represented by the variable swivldegs, while the same swivel angle in radians can be represented by the variable swivlrads. The relationship between these two variables is given below:
pi = 3.14159 swivlrads = (swivldegs / 360) * 2 * pi
Next, rotate the cannon upward away from the x-z plane. In this article, I will call this type of rotation a "tilt", as in "Tilt that sucker up, T-boy!". In the figure below, the blue cannon is shown tilted upward, while the projection of the cannon onto the x-z plane will be represented by the light gray line, which looks similar to a shadow. The tilt angle in degrees can be represented by the variable tiltdegs, while the same tilt angle in radians can be represented by the variable tiltrads. Also, note that we will identify the coordinates of the cannon tip as tipx, tipy, and tipz.
The y-coordinate of the cannon tip can be found using the following:
tiltrads = (tiltdegs / 360) * 2 * pi tipy = LengthCannon * sin(tiltrads)
The length of the projection of the shaft of the cannon onto the x-z plane is found using the following equation:
projection = LengthCannon * cos(tiltrads)
The x- and z-coordinates of the cannon tip can be found using the following:
tipx = projection * cos(swivlrads) tipz = projection * sin(swivlrads)
With these simple equations complete, we've now located the tip of the cannon in space.
To find the "x-component" of the cannon shaft in space, we subtract the x-coordinate of the cannon butt from the x-coordinate of the cannon tip. We will do the same for the other two component directions.
compx = (tipx - 0) compy = (tipy - 0) compz = (tipz - 0)
The "direction cosines" of the cannon are the component lengths of the cannon divided by the full length of the shaft of the cannon:
directioncosinex = (compx / LengthCannon) directioncosiney = (compy / LengthCannon) directioncosinez = (compz / LengthCannon)
The direction cosines are important because as the cannonball travels through space, it will have a velocity in the x direction, a velocity in the y direction, and a velocity in the z direction. The direction cosines help us calculate these three "component velocities".
The muzzle velocity of the cannonball is the speed of the cannonball at the instant it leaves the barrell of the cannon, without regard to the cannonball's direction. The cannonball's direction of course, depends on the tilt and swivel of the cannon. We can also refer to the muzzle velocity as the "initial velocity" because we want to track the path of the cannonball beginning at the moment that the cannon is fired.
Recall above that the shaft of the cannon had "component lengths" in the x-, y- and z-directions. Likewise, the cannonball's initial velocity has initial "component velocities" in the x-, y- and z-directions. These initial component velocities are proportional to the direction cosines given above. See the figure below for a picture of the initial velocity and the component velocities. Notice that the component velocities are parallel to the three axes.
Here's how we find the three component velocities. Let's start by storing the muzzle velocity in the variable muzzvel, and assigning it the value 125. Then, let's store the initial component velocities in the variables compvelx, compvely, and compvelz.
muzzvel = 125 compvelx = (directioncosinex * muzzvel) compvely = (directioncosiney * muzzvel) compvelz = (directioncosinez * muzzvel)
That was a very big step. Now we almost have enough information to track the ball through space.
The objective in the programming of projectiles is to find the position in space of the projectile at any time, t. To do that, the only part of the system that we lack is the effect of gravity.
If you recall from reading the [article] on projectile motion in 2D space, the vertical and horizontal components of velocity are essentially independent. Gravity has an effect on the vertical component of velocity, but has no effect on the horizontal component of velocity. The value of gravity is usually taken as -32.2 feet/second^2. Gravity, which is an acceleration, usually is given a negative sign because projectiles accelerate downward...even when they are traveling upward!
At any time, t, let's assign the x-, y-, and z-coordinates of the ball to the following variables: ballx, bally, and ballz. Without further delay, here are the three equations that give the positon of the ball at any time t:
g = -32.2 t = 0.4 ballx = tipx + (compvelx * t) bally = tipy + (compvely * t) + (1/2)*g*t^2 ballz = tipz + (compvelx * t)
Friends, that's it!
The following short [Liberty BASIC] program puts all of the above programming together in order to track the position of a cannonball every 4/10ths of a second.
'Set pi, g, and length of the cannon... pi = 3.14159 'mmmmmm...pi g = -32.2 'Set the value of gravity, -32.2 feet/second^2 LengthCannon = 65 'The length of the cannon barrell is 65 feet. 'Set the swivel angle and the tilt angle... swivldegs = 38 'Swivel angle in degrees swivlrads = (swivldegs/360) * 2 * pi 'Swivel angle converted to radians tiltdegs = 56 'Tilt angle in degrees tiltrads = (tiltdegs/360) * 2 * pi 'Tilt angle converted to radians 'Find the coordinates of the tip of the cannon... tipy = LengthCannon * sin(tiltrads) 'y-coordinate of the cannon tip projection = LengthCannon * cos(tiltrads) 'the projection of the barrell onto the x-z plane tipx = projection * cos(swivlrads) 'x-coordinate of the cannon tip tipz = projection * sin(swivlrads) 'z-coordinate of the cannon tip 'Find the component lengths of the cannon barrell... compx = (tipx - 0) 'x-component of the cannon length compy = (tipy - 0) 'y-component of the cannon length compz = (tipz - 0) 'z-component of the cannon length 'Find the direction cosines of the cannon barrell in space... directioncosinex = (compx / LengthCannon) directioncosiney = (compy / LengthCannon) directioncosinez = (compz / LengthCannon) 'Set the muzzle velocity of the cannonball, which is the 'initial velocity of the cannonball without regard to direction. 'Then, find the components of the cannonball velocity in the 'x-, y- and z-directions... muzzvel = 125 compvelx = (directioncosinex * muzzvel) compvely = (directioncosiney * muzzvel) compvelz = (directioncosinez * muzzvel) 'Finally, find the location of the cannonball in space every '4/10ths of a second for the first 6.8 seconds after the 'cannonball is fired... print "Position of cannonball in space" print "-------------------------------" for i = 1 to 18 t = (i-1)*0.40 ballx = tipx + (compvelx * t) bally = tipy + (compvely * t) + (1/2)*g*t^2 ballz = tipz + (compvelx * t) print "t= "; using("##.##", t); print " ballx= "; using("####.##", ballx); print " bally= "; using("####.##", bally); print " ballz= "; using("####.##", ballz) next i print " " input "To quit, press any key, then RETURN "; AAA$ end
The program given above will produce the output given below. Take note of the y-coordinate of he cannonball over time. At time = 0 seconds, the cannonball is at the tip of he cannon, and the y-coordinate of the cannonball is 53.89 feet. Then, at about 3.2 seconds, the cannonball reaches the apex of its flight with a y-coordinate of about 220 feet. Then it begins dropping back to earth, and shows a y-coordinate of 14.10 feet at time = 6.80 seconds.
Position of cannonball in space ------------------------------- t= 0.00 ballx= 28.64 bally= 53.89 ballz= 22.38 t= 0.40 ballx= 50.67 bally= 92.76 ballz= 44.41 t= 0.80 ballx= 72.71 bally= 126.49 ballz= 66.44 t= 1.20 ballx= 94.74 bally= 155.06 ballz= 88.48 t= 1.60 ballx= 116.77 bally= 178.48 ballz= 110.51 t= 2.00 ballx= 138.80 bally= 196.75 ballz= 132.54 t= 2.40 ballx= 160.84 bally= 209.86 ballz= 154.57 t= 2.80 ballx= 182.87 bally= 217.83 ballz= 176.61 t= 3.20 ballx= 204.90 bally= 220.64 ballz= 198.64 t= 3.60 ballx= 226.94 bally= 218.30 ballz= 220.67 t= 4.00 ballx= 248.97 bally= 210.81 ballz= 242.70 t= 4.40 ballx= 271.00 bally= 198.16 ballz= 264.74 t= 4.80 ballx= 293.03 bally= 180.37 ballz= 286.77 t= 5.20 ballx= 315.07 bally= 157.42 ballz= 308.80 t= 5.60 ballx= 337.10 bally= 129.32 ballz= 330.83 t= 6.00 ballx= 359.13 bally= 96.07 ballz= 352.87 t= 6.40 ballx= 381.16 bally= 57.66 ballz= 374.90 t= 6.80 ballx= 403.20 bally= 14.10 ballz= 396.93 To quit, press any key, then RETURN
In the archive accompanying this newsletter, nl130.zip, I'm also including a [Liberty BASIC] program called Artillery 3D. A screenshot of Artillery 3D is provided on the right.
In this program, the user fires a cannon from the Southwest corner of an artillery grid. The purpose of the game is to hit the spiders that reside in the artillery grid. The user adjusts the swivel, the tilt and the muzzle velocity of the cannon in order to "walk" his artillery shots closer to the targets.
I've made custom controls to operate the tilt, the swivel and the muzzle velocity of the cannon. The swivel and tilt controls are rotational sliders. Click your mouse within the blue circle of the slider, and drag the needle to a new angular positon. As you move the controls, you can see the cannon barrell move in real time. The muzzle velocity control is a linear slider.
In the upper-left corner of the application, eight buttons are provided to change the view onto the artillery field. Each button represents a different camera position. So, if you want to see the artillery field from the NorthEast corner, press the NE button.
Under the Options menu, the user will find access to a "Game Control Settings" panel. This panel will allow you to set the animation speed, the height of the camera, and the camera zoom.
Artillery 3D is released as open source.
--- Tom Nally