Don Hickather Justin Mauzey 04/11/06 Abstract: This project involving linear algebra and discreet mathematics to predict the path a projectile will follow through a star field, with a graphical representation of this data. Programmed in Python with the use of the numeric, random, math, and Tkinter libraries. Meant to fulfill final project for MATH 201 – Linear Algebra. Also has implementation of applied physics as well as calculus techniques. The Conceptual Ideas behind this game: I played an old video game in the late eighties and early nineties called Vectwars. This program was probably made in the early sixties, however research indicates that it was around in the late sixties or early seventies. The game was relatively simple, it took place in a two dimensional star field. The game allowed one to control a ship that was confronted by multiple opponent ships. The only control one had over the ship was to launch a projectile. The projectile’s inputs were velocity and launch angle. The gravity of the stars in the star field tried to pull the projectile towards them. The trick was to get their gravity to hook the shot into one of the opponents. I’ve thought about this game numerous times over the years, even tried recreating it when I was in Junior High but failed. My math skills and critical thinking abilities where not strong enough to accomplish the task. When faced with a project dealing with vectors I thought it would be an interesting project to revisit. There are at least two ways to solve this problem: one way is to find a continuous equation that represents the path the projectile will take with multiple gravitational forces acting upon the body, the other solution was to do it as a non-continuous equation in discrete time intervals. The second method is only an approximation, so error can be calculated. If I have time in the future I will revisit this problem. In order to solve the problem of what forces are acting on a projectile I had to use applied physics. Since I chose the discreet method approximation, I needed to evaluate the forces in stages. When I pictured this process I thought of a flip page animation scene that I would make in real time. The idea sounded simple enough but the math that goes in to it becomes increasingly difficult as the number of stars increases. The ability of a computer to crunch this information is utilized. The initial way I set up this problem was such that I had three variables: the velocity of my projectile, the position of the projectile relative to the stars and the opponent’s ships, and the direction of my projectile’s path relative to a reference angle. Assumptions Made: The stars and ships are fixed objects. The density of each star is a constant. A star’s gravitational pull is proportional to its mass according to Newton’s Laws of Attraction. The ship’s mass is insignificant compared to that of the stars so its force vector is not calculated. Computations: Setting up a free body diagram for the projectile using a three star example to calculate the resultant force. Calculate the forces acting on the object by the stars: Mm Label them Fgm1, Fgm2, and Fgm3. Where Fg G 2 r M = mass of the star m = mass of projectile G = the gravitational constant r = distance from the projectile to the star Since ‘r’ is a distance, a vector is constructed and the norm of that vector is substituted into the Fg function for ‘r.’ In order for this to work correctly the unit vector had to be multiplied in to the function as well to make the resulting force pull in the correct direction. GM n m v n F gn * 2 vn vn The equation above calculates the force acting between two bodies. Since there are multiple stars that are acting upon the projectile, Fgn will have to be calculated for all stars. The individual forces Fgm1, Fgm2, and Fgm3, will then be added together and a resultant force will be calculated. The resultant will be the overall net force acting upon the n projectile, F final F gn , where n is the number of stars. Once the resultant force is 1 known the acceleration of the projectile is calculated using F = ma, solving for ‘a’ Using: v(t ) v(t 1) at ; this will calculate the new velocity based upon the old a F final m velocity and the final resultant acceleration. However it does not tell how far the 2 projectile will travel in a straight line. Using: x(t ) x(t 1) v(t ) * t (1 / 2) * a * t this vector quantity is the next point to graph and from which the next set of calculations will be based off on. Theory to Reality: With the mechanics laid out it came time to make this project become reality. After some research and consulting the Python language was chosen. Python is an interpreted language, meaning it does not have to be compiled to run. It has a wide rand of compiled libraries, to ease computation on the program. It also has efficient garbage cleanup, which help prevent memory leaks. An example of preventing this would be: Programming in Python: curPos = 3 curPos = curPos + 2 Programming in C: new oldPos = 3 new curPos = oldPos + 2 delete oldPos new oldPos = curPos delete curPos Two line versus five lines. It allows for a shorter program as well as a more natural flow of writing the program. In a simple example such as this it’s not as apparent as adding vectors to arrays and such. By the end of my program it became much more apparent how useful this feature is. Through all of my experience in programming I had never dealt with a GUI before. Python’s default GUI is TK based off from TCL. The creator of the Python language did it as an under graduate project to prove that thirty percent of all programming languages were what he called ‘Sugar Coated Syntax’ and were not needed. In Python there is no ‘Then’ keyword or block statement syntax because it’s inferred in an ‘If’ command that something is done. Due to this fact indent level notation is critical. I am becoming more comfortable with the mechanics of the language itself. Like everything else familiarity comes with understanding and practice. The highlights of implementation of linear algebra in the program uses vectors, transforms, scalars, rotations, and operators such as the norm and dot products. The program: The program consists of three parts: a view, a model, and a controller. The view is what is actually visible to the human eye. The inputs from the view have to go through the controller before making it to the model. When data is entered in to the view, it is just raw data that has to be interpreted. The model wants vector quantities for its calculations, so the purpose of the controller is to change the input values from the view in to floating point numbers and construct a two by one matrix out of the data before passing the information to the model. The model does the calculations based on the physics listed above and outputs a two by one matrix. The matrix then needs to be reinterpreted and made in to integers for graphing purposes. A computer’s display is only able to graph pixels at predetermined integer locations. So the new point to graph needs to be rounded to whole numbers. The view does take care of some things such as an initial transform and scaling. In TK the point (0,0) is located in the upper left hand corner of the window and as you go right the ‘x’ value increases, however as you go down the ‘y’ axis the values of ‘y’ gets larger. In order to reposition the (0,0) coordinate to the lower left hand corner and force the display into the ‘first quadrant’ from a mathematical view, a transform matrix was used. At the same time of implementation I have it scale the window as well. The physical dimensions of the window are 800 × 600 pixels but one can graph any size window and it will scale to the initial area. The rotation of the ship is actually a property of the ship itself. When the fire button is pressed the view erases the ship and passes the angle of launch and the ships old position back to the ship. The ship in turn runs its old coordinates through a translation matrix moving the center of the ship to the origin. The Ship then converts the angle in to radians, and runs the numbers through a rotation matrix. Then the new rotated points get fed back in to the translation matrix and passed back to the view. The view then redraws the ship. This is the only time the model talks directly to the view, all other communications go through the controller. In the old Vectwars a projectile was able to loop around the screen. The ‘x’ maximum and ‘x’ minimum are the same points, when graphed they are the same points on the surface a cylinder. The ‘y’ minimum and ‘y’ maximum share the same set of points as well. When the two orthogonal cylinders are graphed in a three dimensional space the resulting shape is that of a donut, called a torus. Implementation of the torus function went well. The point of implementing this is that if the projectile leaves the bottom of the star field it will reenter the top of the star field with the same ‘x’ value, causing the projectile to loop around the screen. Other uses of linear algebra are in the physics engine, listed above. Implementation of unit vectors to determine the direction of my forces. An array in the Python language is basically the same the same thing as a matrix. In Python you can edit the dimensions of a matrix on the fly. Python also allows you to reference information from a matrix from the bottom up with a negative reference as well as a standard positive reference. An example would be A(-1, : ) would reference the last row and all columns, this allowed me to add my projectiles points into a matrix and access the last one for my next set of calculations but also store them for future analysis. In the torus function when the projectile looped it was necessary to reset the line to a new point, resetting the line. I could have created a matrix of matrices but chose to keep them independent, the down fall to this is that a single shot can be comprised of more than one line but it allowed for easier error calculations. Trying to evaluate the error in my projectiles trajectory is a more difficult process. The limit as Δt approaches zero is going to be the true function that represents the projectile’s trajectory. Shortening the time interval and comparing the corresponding points caused the program to crash when the lines differed in length, which was just about every time. Comparing the end points from the two different lines with the same initial conditions but different time intervals gave an idea of the error but not a very accurate representation of the error. Unable to solve this part of the problem, I chose to store the points for future calculations. The most important application aspect I took from this endeavor was the accuracy versus time of the simulation. The program can become more accurate but the sacrifice is speed, and visa versa, the program can run faster but it becomes less accurate. This is due to how many times it reevaluates the problem in the simulated timing. If the time interval becomes large enough the projectile can shoot right through a star or an opponent before the intersect routine is reevaluated. So the question gets raised how accurate should the simulation be. Analyzing the problem in order of magnitudes, there is very little difference between a time increment of 0.01 and 0.1 but a huge difference between 0.1 and 1.0. The time increment chosen for the program was 0.1 because it was ten times faster than 0.01 and had little visible error. Concluding Statements: This program has been the most challenging and rewarding thing I have encountered in college so far. This is the first real life application I have been able to apply such a large skill set to solve a problem. It took knowledge from physics, calculus, linear algebra, and programming to accomplish. I always wanted to make computer games for a living and making it this far feels good. This is my fist step to accomplishing that goal. As it stands there are a few things I want to finish on the program, but I think I will wait until my skill set is even stronger. I tried the error analysis but was unable to quantitatively produce results since it requires the usage of discrete mathematics. Last time I tried to undertake this project I failed. This time around I didn’t fail but I didn’t fully succeed. I don’t feel bad about it because this idea is more developed than last time I walked away from it, I will just come back to it as time and skills permit. Justin Mauzey 05/19/06