Blitz2D Intermediates: Polar coordinates and simple vector graphics
by James Mintram

Polar Coords vs. Cartesian and Simple Vector graphics (My Way!!) Warning: This tutorial is my first release and I haven’t been able to get anyone to proof read it properly yet – all of the code in this tutorial has not been fully tested yet, but I am in the processing of doing that. I am also in the processes of writing the attached code, but I am a very busy man! I have tried to make everything as correct and easy to understand as I can but if there’s anything wrong or explained badly please let me know, and I will change it ASAP. (My email address is at the bottom of the page)

Hi, this is my first article so I will attempt to make it reasonably interesting, I will be discussing 2 important coordinate systems, Polar and Cartesian and some uses for the former. What I will not be doing is writing a whole game, I will however provide small snippets of code showing what I am trying to describe. I will show you how to draw simple vector graphics, such as those seen in classic games like asteroids!
No a lot of you will probably not know what on earth Polar coordinates are so I will give a brief explanation of Cartesian coordinates and then compare them to Polar and hopefully the differences between the 2 should be enough for you to understand Polar!! Most of the time, when coding away at your 2d game, you are using Cartesian coordinates, that is using a 2d screen of a set size plotting things onto it much like a graph (although you have flipped the Y axis about the X compared to traditional maths). You have 1 point called the origin which is coordinate 0,0 and everything is plotted from this point, i.e. a pixel at point 8,8 would be 8 pixels along the x axis from the origin and 8 pixels up the y axis (using standard math axis).


Now this seems all very good, but there are some cases when other coordinate systems need to be used, and one of the cases I use them is for rendering vector graphics (I don’t know if anyone else does!).
Polar coordinates work by using vector quantities from the origin, so everything starts from 0,0 as in Cartesian coordinates but that’s about all that is the same. Now a Cartesian coordinate is made up of an x position on the x axis and a y position on the y axis, a Polar coordinate is made up of an angle, and a distance from the origin.
So lets say we want to plot a point A=90 and D=10 using Polar coordinates, we would plot it 90 degrees from the vertical and then 10 pixels out at that angle. So that point would be the same as plotting 10,0 using Cartesian coordinates.

Its all very well using Polar coordinates, but when everything is drawn to the screen using Cartesian coordinates they become useless without being able to convert them from Polar to Cartesian. This is pretty simple using sin and cos to compute the x position and y position of each coordinate based on its angle, then multiply it by a distance factor – the larger the factor to further away from the origin the point will be. Maths:
	X = cos ( angle ) * distance
	Y = sin ( angle ) * distance
Now how will this relate to drawing vector graphics you may ask, well if we store all the information about a graphic using Polar coordinates it is extremely easy to do the most common transformations to the shape, for example rotating and scaling by simply adding a modifier to one of the coordinates before converting from Polar to Cartesian. So if we wanted to rotate the graphic by 90(1/2 pi) degrees we would simple add 90(1/2 pi) to all of the angle angles. Maths:
	X = cos ( angle + rotation ) * distance
	Y = sin ( angle + rotation ) * distance
And to scale we would multiply the distance by a scale factor. Maths:
	X = cos ( angle + rotation ) * ( distance * scale )
	Y = sin ( angle + rotation ) * ( distance * scale )
When programming with the trigonometry functions (sin, cos etc…) a lot of processing power is needed, to make this better lookup tables can be used. A lookup table is basically a table which holds the correct output for the function at the index at which is equal to the input.


The only disadvantage of this method is if you want to take the sin and cos of non whole values, workarounds can be used but I'm not going to explain them here!! So for drawing vector graphics you will need to do the following. Store all of the points for the graphic in Polar coordinate form in a list, then be able to scale/rotate the vector graphic and finally convert the Polar coordinates into Cartesian coordinates and draw the appropriate shapes on the screen. So to store all of the Polar coordinates in a list I will be using, yep you guessed it – types!! So here is a very simple structure for a Polar coordinate:


We will also need a container, to hold all of the Polar_coord’s for a specific shape:


And we will want also want some lookup tables to speed up the conversion from Polar to Cartesian:
	Dim sin_table ( 360 )
	Dim cos_table ( 360 )
Now that is the minimum number of data structures required to hold our information ( apart from the sin/cos tables ) Here is some code which will rotate and scale a particular vector_shape:
	Function transform ( shape.vector_shape, rotation, scale )
	
		Shape\rotation = rotation
		Shape\scale = scale
	End function
And finally the code to convert from Polar to vector:


Now when it comes to drawing vector graphics, you need to be carefull in how you draw them, every line needs to be drawn in the correct order for example, if you drew the lines from point 1 to 3 to 2 to 4 in the diagram below you wouldn’t end up with a square!
The ordering needs to be done when you create all of the Polar_coordinates for the vector graphic, so you will need to think carefully when creating them, alternatively you could write your own simple vector graphic designer which would allow the easy creation of simple vector graphics and then export them to a list of Polar coordinates in the correct order! Below I am going to explain the beginnings to a simple asteroid clone, so I will write all of the base vector graphics code, and a simple space ship object which can be controlled and then the rest is up to you if you want to finish the game! List of everything that needs to be done:
  • Write vector graphics control system
  • Create ship object and control functions
  • Design ship vector graphic and write code to create it
  • Write input code to control ship
We have already covered the most important aspects or task 1 with the code shown above, the rest of the code can be viewed in the attached example code, so we now move onto the second task. For the ship I will use a type, simply because it seems to be the most logical choice to allow flexibility in the code for the future, so the type will look like this:


For now we can simply use a global variable to hold the reference to the ship object that we will be using:


Now we need some control functions, I will make these as flexible as possible, to allow for easy extensibility later, so first off is the movement function. For the movement of to work properly we will need to keep a record of its speed and angle, the angle we already have stored within its graphic information but if we used this then we would have to assume that the ship is pointing in the direction that we are moving which if you have played asteroids you know isn’t always the case. Function move_ship ( a_ship.ship ) A_ship\x_pos = a_ship\x_pos + cos ( a_ship\angle ) * a_ship\speed A_ship\y_pos = a_ship\y_pos + cos ( a_ship\angle ) * a_ship\speed ;this here will reduce the speed of the ship at a logarithmic rate, so when the accelerator is not pressed it slows down A_ship\speed = a_ship\speed * 0.6 End function And that’s it! I have used a function parameter even though we are using a global variable for the ship, so that the function can be used to move any ship around including enemy ships if desired.


Now this function simply deals damage to a ship and when the ships health is below 1 it calls the function to remove the ship from play, if the ship is the players ship then it the dead_ship function will deal with player lives etc. That is all the control functions I am going to write for this game, you can add your own now you can see how the basic structure of these control functions work. Now we need to design our ship, how does this look?
If that’s not up to your standards then you can create your own!! What we need to do now is define a centre point for which
the whole ship is going to rotate around, which I think choosing the centre of the ship is a good idea. We then need to decide on angles and distances from the centre to each point in the shape, there are 4 points to the shape. The easiest way to work out he angles and lengths manually is to draw it to scale on a piece of paper, then use a protractor and ruler to measure the appropriate lengths and angles of the shape. So point 1 might be [0, 10] (0 degrees, by 10 pixels in that direction), 2 could be [120, 10] 3 = [180, 5] etc (Which are going to be the values I use for my ship) and that is all the data we need for our ship. The next thing that needs to be done is writing the code to create the ship which is pretty simple and can be viewed with the attached sample but I will describe in pseudo code what needs to be done.


You can write your own functions to do this, but in the attached code I have simple done it all by hand to keep the demo as simple as possible to follow. And that’s pretty much everything we need apart from the main loop , a function to handle keyboard input and a function to actually draw the ship. All the keyboard input function will read input from the keyboard and update the ships speed and angle values. The main loop will be in control of looking after the screen, calling all of the ship and game control functions.


The drawing function:


And finally the input processing function:


Now I have left out a lot of code, because I feel the point of a tutorial is to explain what the article is about, and not spend most of it with code for things that aren’t to do with the tutorial but you can find out everything not explained in this tutorial in the code. I hope that this tutorial is even slightly helpful, and I would like any feedback good/bad/questions whatever as I would like to improve it as much as possible. Thank you for reading. James My email address is jamesmintram@aol.com (yes I know, don’t laugh!)


For a printable copy of this article, please click HERE.


This site is Copyright© 2000-2004, BlitzCoder. All rights reserved.