DRAWING CIRCLES

Drawing Hollow Circles

If you know some basic trigonometry, you should already know how to draw a circle. However, some of us don't know, so I'll go over it here.

To draw a circle, we need to know two things - it's centre and it's radius (and color).

When turning in a circle, we are turning through an angle of 360 degrees. Half a circle is 180 degrees, and a quarter is 90 degrees. However, we will be drawing using another measurement, called radians. 360 degrees is equal to 2ã radians (2 * Pi).

To get the coordinates of the point on a circle at a given angle, you multiply the radius by the cosine of the angle to get the X offset, and multiply the radius by the sine of the angle to get the Y offset. Notice I said offset rather than coordinate. This is because we want to calculare the offset of the point from the centre.

Therefore, the formulas used to calculate the coordinate of any point on the circle with centre at (xc,yc) and with a radius of R are:

X = CX + (R * COS(A))

Y = YC + (R * SIN(A))

To draw the entire circle, we create a loop which moves through the angles from 0 to 2ã radians, calculating and plotting the coordiantes on the circle using the above formula.

However, if we loop from 0 to 2ã ,which is about 6.28, in steps of 1, we only end up with 7 points on our circle, which isn't a full circle.

To make our circle solid, we loop through in increments of less than 1. The smaller the increments, the more points drawn and thus the more solid appearing the edge.

Below is a basic routine to draw a circle centred at (XC,YC) with radius R and colour C. This routine uses a step value of ã/180 to give 360 steps in total. (This is in pseudocode).

FOR A = 0 TO 2 * PI STEP PI/180
X = XC + (R * COS(A))
Y = YC + (R * SIN(A))
PLOTPIXEL(X,Y,C)
NEXT A

This routine works perfectly, but lets examine it for a minute. A is a floating point number. So are X and Y. As we know from previous experience, floating point numbers slow things down majorly. So lets look at how we can remove them and improve our routine.

There are 2 parts to optimizing this routine. Firstly, we can precalculate our sin and cos values and store them in an array. However, because we are using radians, this means we are expressing the angle in floating point numbers as well, and we can have floating-point array elements. (eg, if we have an array numbers(5), we can have numbers(0), numbers(1), numbers(2), numbers(3), numbers(4), numbers(5), but we can't have numbers(3.232) ).

Therefore we need to express our angles in whole numbers, which helps remove another floating point number from the loop.

Degrees are whole numbers, so it makes sense to express our angle in degrees, so we will create 2 arrays, one called COSARRAY and one alled SINARRAY to hold the value for all 360 degrees of our circle. Here is the pseudocode routine to do this:

FOR A = 0 TO 360
RADIANS = A * PI / 180
COSARRAY(A) = COS(RADIANS)
SINARRAY(A) = SIN(RADIANS)
NEXT A

As you can see we created a RADIANS variable to convert our angle A in degrees to the same angle in radians. This is necessary cause COS and SIN functions require radians.

So now our drawing routine becomes:

FOR A = 0 TO 360
X = XC + (R * COSARRAY(A))
Y = YC + (R * SINARRAY(A))
PLOTPIXEL(X,Y,C)
NEXT A

Now this is much better. Our angles are integers, and our sin and cos values are precalculated. However, our sin and cos values are still floating point values between -1 and 1. To speed up our routine even further, we need to modify this to make them integers. Following is a pseudocode algorithm to implement this to our routine to create our sin and cos arrays:

FOR A = 0 TO 360
RADIANS = A * PI / 360
COSARRAY(A) = INT(COS(A) * 100)
SINARRAY(A) = INT(SIN(A) * 100)
NEXT A

Once again we create our sin and cos arrays, but this time we multiply each cos and sin value my 100 and then take the integer portion (ie discard th decimal places). We now have the values in our arrays as integers which fall in the range of -100 to 100. Now to calculate the position on the circle, we divide the sin and cos values by 100. So now our drawing routine is:

FOR A = 0 TO 360
X = XC + (( R * COSARRAY(A)) / 100)
Y = YC + ((R * SINARRAY(A)) / 100)
PLOT(X,Y,C)
NEXT A

This time we are multiplying R by the cos or sin value, and then we divide the result by 100. Mathematically, it doesn't matter if we divide the cos value by 100 first and then multiply by R, but from the point of view of how the computer calculates it, this is an important difference.

Although we end up with a floating point result, the calculations are done using integers, which is much faster.

Drawing Filled Circles

Two draw our circle filled, we can simple draw the circle using vertical or horizontal lines. I will show you how to draw one using vertical lines. I will give out the code to drawing with horizontal lines to ppl who ask. By now you may have realized that if you compare the sin and cos values above and below the X axis, you will have noticed that

sin(i) = -sin(360-i)

Which means for any given point along the x axis within the circle, the point above and below the X axis are the same distance from the X axis. So, to draw our filled circle we onle need to make our loop run from 0 degrees to 180 degrees, calculate the sin value,multiply by radius to get the height (we'll call it h), and then draw a vertical line from +h to -h. If the circle is not centred at (0,0,) then for a circle centred at (CX,CY) you draw your line from (CX,CY+h) TO (CX,CY-h). Simple!

Download the source code and example program here.

Back