*** GRAPHICS ROTATION (2D), by Alex Warren ***********************************
Many people seem to want to know how to rotate 2D graphics, and in this
article I'll show you how to do it using fairly simple trigonometry.
An important rule for rotation is the following:
In this rather bad ASCIIart circle of radius 1, point X is at (1,0) and O is
the origin at (0,0):
*****
**  **
*  *
*_____O____X
*  *
*  *
**  **
*****
If we rotate X by A degrees/radians anticlockwise, trigonometry tells us that
it will end up at point (COS(A),SIN(A)), which is how we rotate point X.
This is fine if you just want to draw a circle without using the CIRCLE
command perhaps, but it's a bit more complex if you want to use it for
rotation.
The following program will rotate any graphic or text that you put into it 
the explanation of how it works comes after the program. Run it first though
and see that it does indeed work.
DEFINT AZ
CONST pi! = 3.141593
' Define coordinates of box to rotate here, with (0,0) at the centre of the
' screen. BOXX1 = left coor, BOXX2 = right coor, BOXY1 = top coor,
' BOXY2= bottom coor, ie rectangle defined by (BOXX1, BOXY1)(BOXX2, BOXY2)
CONST BOXX1 = 12
CONST BOXX2 = 12
CONST BOXY1 = 12
CONST BOXY2 = 12
DIM r!(BOXX1 TO BOXX2, BOXY1 TO BOXY2)
DIM a!(BOXX1 TO BOXX2, BOXY1 TO BOXY2)
DIM p(BOXX1 TO BOXX2, BOXY1 TO BOXY2)
FOR x = BOXX1 TO BOXX2
FOR y = BOXY1 TO BOXY2
r!(x, y) = SQR((x ^ 2) + (y ^ 2))
IF x < 0 THEN r!(x, y) = r!(x, y)
IF x = 0 THEN a!(x, y) = (pi / 4) ELSE a!(x, y) = ATN(y / x)
NEXT y
NEXT x
SCREEN 7
WINDOW (160, 100)(160, 100) ' We set the coordinate system of the screen so
' that the point (0,0) is in the centre of the
' screen.
' *** INSERT DRAWING CODE HERE, ETC. ***
LINE (12, 12)(12, 12), 15, B
LINE (11, 11)(11, 11), 12, B
LINE (12, 12)(12, 12), 13
LINE (12, 12)(12, 12), 14
' *** END OF DRAWING CODE ***
FOR x = BOXX1 TO BOXX2
FOR y = BOXY1 TO BOXY2
p(x, y) = POINT(x, y)
NEXT y
NEXT x
a$ = INPUT$(1)
' Rotation code here. Note that angles are in RADIANS where 2ã rads=360ø
' (Characters in above comment may show incorrectly under Windows, it should
' read 2pi rads=360 degrees)
curpage = 0
DO
FOR angle! = 0 TO 2 * pi! STEP .1
SCREEN 7, , curpage, 1  curpage
CLS
FOR x = BOXX1 TO BOXX2
FOR y = BOXY1 TO BOXY2
newx = COS(angle! + a!(x, y)) * r!(x, y)
newy = SIN(angle! + a!(x, y)) * r!(x, y)
PSET (newx, newy), p(x, y)
NEXT y
NEXT x
curpage = 1  curpage
NEXT angle!
LOOP UNTIL INKEY$ = CHR$(27)
So how does this program use the above rule to rotate graphics? Well, it has
to split up the entire graphic into circles and work out the angle of each
point subtended at the centre of the circle. Sounds complicated? OK, here it
is another way, using an example point P. The point (0,0) is O.

P 
_______O______


The coordinates of point P are (4,2) in this example. We can work out which
circle P is in by finding the distance between P and the point O (hence the
radius of the circle). We can do this using Pythagoras' Theorem, which will
tell us that the radius of the circle R is SQR((X^2)+(Y^2)).
Next we need to work out P's angle in its circle, otherwise all points in the
same circle would end up being plotted to the same point. We can work out P's
angle using a!(x, y) = ATN(y / x). The function ATN in BASIC returns the
inverse TAN, ie the same result as pressing 
 1
tan 
 on a calculator.
This will tell us the angle "A" of the point "P", in radians:
P
\
\
\A
 (1,0)
So we work out the values R (radius) and A (angle) of each point BEFORE we
rotate, and then we can use them during our rotation loop, like this:
newx = COS(angle! + a!(x, y)) * r!(x, y)
newy = SIN(angle! + a!(x, y)) * r!(x, y)
This uses the (COS(A),SIN(A)) rule above, with A being the angle of rotation
added to the angle of the point P. The coordinate obtained is then multiplied
by the radius of P's circle.
We then work out the values of newx and newy for each point in our rotation
area, and plot newx and newy. We can use a FOR loop or similar to animate the
rotation, as in the program above.

* EDITOR'S NOTE:
* This article was originally printed in Peter Cooper's BASIX Fanzine,
* Issue #9 from October 1997. This issue was edited by Alex Warren.