[Home]
[Edit this page]
[Recent Changes]
[Special Pages]
[Help]
DenTut3-Pas
[To be edited]
Greetings! This is the third part of the VGA Trainer series! Sorry it took so long to get out, but I had a running battle with the traffic department for three days to get my car registered, and then the MailBox went down. Ahh, well, life stinks. Anyway, today will do some things vital to most programs : Lines and circles.
Watch out for next week's part : Virtual screens. The easy way to eliminate flicker, "doubled sprites", and subjecting the user to watch you building your screen. Almost every ASPHYXIA demo has used a virtual screen (with the exception of the SilkyDemo), so this is one to watch out for. I will also show you how to put all of these loose procedures into units.
You probably know circles drawn with the degrees at these points :
... anyway, Pascal doesn't work that way ... it
works with radians instead of degrees. (You can convert radians to degrees,
but I'm not going to go into that now. Note though that in pascal, the
circle goes like this :
Even so, we can still use the famous equations to draw our circle ... (You derive the following by using the theorem of our good friend Pythagoras)
)
The first thing you need to do is pass what you want the line to look like to your line procedure. What I have done is said that x1,y1 is the first point on the screen, and x2,y2 is the second point. We also pass the color to the procedure. (Remember the screens top left hand corner is (0,0); see Part 1)
To find the length of the line, we say the following :
If neither the x's or y's have a zero difference, I calculate the X and Y slopes, using the following two equations :
Now, there are two ways of drawing the lines :
Line and circle routines may seem like fairly trivial things, but they are a vital component of many programs, and you may like to look up other methods of drawing them in books in the library (I know that here at the varsity they have books for doing this kind of stuff all over the place) A good line routine to look out for is the Bressenhams line routine ... there is a Bressenhams circle routine too ... I have documentaiton for them if anybody is interested, they are by far some of the fastest routines you will use.
[Edit this page] [Page history] [What links here] [Discuss this topic] [Printer Friendly]
DenTut3-Pas
[To be edited]
ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸
³ W E L C O M E ³
³ To the VGA Trainer Program ³ ³
³ By ³ ³
³ DENTHOR of ASPHYXIA ³ ³ ³
ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ; ³ ³
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
--==[ PART 3 ]==--
- Introduction
Greetings! This is the third part of the VGA Trainer series! Sorry it took so long to get out, but I had a running battle with the traffic department for three days to get my car registered, and then the MailBox went down. Ahh, well, life stinks. Anyway, today will do some things vital to most programs : Lines and circles.
Watch out for next week's part : Virtual screens. The easy way to eliminate flicker, "doubled sprites", and subjecting the user to watch you building your screen. Almost every ASPHYXIA demo has used a virtual screen (with the exception of the SilkyDemo), so this is one to watch out for. I will also show you how to put all of these loose procedures into units.
- Circle Algorithim
You probably know circles drawn with the degrees at these points :
0
ÜÛ|ÛÜ
ÛÛÛ|ÛÛÛ
270 ----+---- 90
ÛÛÛ|ÛÛÛ
ßÛ|Ûß
180
Sorry about my ASCI
270
ÜÛ|ÛÜ
ÛÛÛ|ÛÛÛ
180 ----+---- 0
ÛÛÛ|ÛÛÛ
ßÛ|Ûß
90
Even so, we can still use the famous equations to draw our circle ... (You derive the following by using the theorem of our good friend Pythagoras)
Sin (deg) = Y/R
Cos (deg) = X/R
(This is standard 8(?) maths ... if you haven't reached that level yet,
take this to your dad, or if you get stuck leave me a message and I'll
do a bit of basic Trig with you. I aim to please
Where Y = your Y-coord
X = your X-coord
R = your radius (the size of your circle)
deg = the degree
To simplify matters, we rewrite the equation to get our X and Y values :
Y = R*Sin(deg)
X = R*Cos(deg)
This obviousy is perfect for us, because it gives us our X and Y co-ords
to put into our putpixel routine (see Part 1). Because the Sin and Cos
functions return a Real value, we use a round function to transform it
into an Integer.
Procedure Circle (oX,oY,rad:integer;Col:Byte);
VAR deg:real;
X,Y:integer;
BEGIN
deg:=0;
repeat
X:=round(rad*COS (deg));
Y:=round(rad*sin (deg));
putpixel (x+ox,y+oy,Col);
deg:=deg+0.005;
until (deg>6.4);
END;
In the above example, the smaller the amount that deg is increased by,
the closer the pixels in the circle will be, but the slower the procedure.
0.005 seem to be best for the 320x200 screen. NOTE : ASPHYXIA does not use
this particular circle algorithm, ours is in assembly language, but this
one should be fast enough for most. If it isn't, give us the stuff you are
using it for and we'll give you ours.- Line algorithms
The first thing you need to do is pass what you want the line to look like to your line procedure. What I have done is said that x1,y1 is the first point on the screen, and x2,y2 is the second point. We also pass the color to the procedure. (Remember the screens top left hand corner is (0,0); see Part 1)
Ie. o (X1,Y1)
ooooooooo
ooooooooo
oooooooo (X2,Y2)
Again, sorry about my drawings To find the length of the line, we say the following :
XLength = ABS (x1-x2)
YLength = ABS (y1-y2)
The ABS function means that whatever the result, it will give you an
absolute, or posotive, answer. At this stage I set a variable stating
wheter the difference between the two x's are negative, zero or posotive.
(I do the same for the y's) If the difference is zero, I just use a loop
keeping the two with the zero difference posotive, then exit.If neither the x's or y's have a zero difference, I calculate the X and Y slopes, using the following two equations :
Xslope = Xlength / Ylength
Yslope = Ylength / Xlength
As you can see, the slopes are real numbers.
NOTE : XSlope = 1 / YSlopeNow, there are two ways of drawing the lines :
X = XSlope * Y
Y = YSlope * X
The question is, which one to use? if you use the wrong one, your line
will look like this :
o
o
o
Instead of this :
ooo
ooo
ooo
Well, the solution is as follows :
*\``|``/*
***\|/***
----+----
***/|\***
*/``|``\*
If the slope angle is in the area of the stars (*) then use the first
equation, if it is in the other section (`) then use the second one.
What you do is you calculate the variable on the left hand side by
putting the variable on the right hand side in a loop and solving. Below
is our finished line routine :
Procedure Line (x1,y1,x2,y2:integer;col:byte);
VAR x,y,xlength,ylength,dx,dy:integer;
xslope,yslope:real;
BEGIN
xlength:=abs (x1-x2);
if (x1-x2)<0 then dx:=-1;
if (x1-x2)=0 then dx:=0;
if (x1-x2)>0 then dx:=+1;
ylength:=abs (y1-y2);
if (y1-y2)<0 then dy:=-1;
if (y1-y2)=0 then dy:=0;
if (y1-y2)>0 then dy:=+1;
if (dy=0) then BEGIN
if dx<0 then for x:=x1 to x2 do
putpixel (x,y1,col);
if dx>0 then for x:=x2 to x1 do
putpixel (x,y1,col);
exit;
END;
if (dx=0) then BEGIN
if dy<0 then for y:=y1 to y2 do
putpixel (x1,y,col);
if dy>0 then for y:=y2 to y1 do
putpixel (x1,y,col);
exit;
END;
xslope:=xlength/ylength;
yslope:=ylength/xlength;
if (yslope/xslope<1) and (yslope/xslope>-1) then BEGIN
if dx<0 then for x:=x1 to x2 do BEGIN
y:= round (yslope*x);
putpixel (x,y,col);
END;
if dx>0 then for x:=x2 to x1 do BEGIN
y:= round (yslope*x);
putpixel (x,y,col);
END;
END
ELSE
BEGIN
if dy<0 then for y:=y1 to y2 do BEGIN
x:= round (xslope*y);
putpixel (x,y,col);
END;
if dy>0 then for y:=y2 to y1 do BEGIN
x:= round (xslope*y);
putpixel (x,y,col);
END;
END;
END;
Quite big, isn't it? Here is a much shorter way of doing much the same
thing :
function sgn(a:real):integer;
begin
if a>0 then sgn:=+1;
if a<0 then sgn:=-1;
if a=0 then sgn:=0;
end;
procedure line(a,b,c,d,col:integer);
var u,s,v,d1x,d1y,d2x,d2y,m,n:real;
i:integer;
begin
u:= c - a;
v:= d - b;
d1x:= SGN(u);
d1y:= SGN(v);
d2x:= SGN(u);
d2y:= 0;
m:= ABS(u);
n := ABS(v);
IF NOT (M>N) then
BEGIN
d2x := 0 ;
d2y := SGN(v);
m := ABS(v);
n := ABS(u);
END;
s := INT(m / 2);
FOR i := 0 TO round(m) DO
BEGIN
putpixel(a,b,col);
s := s + n;
IF not (s<m) THEN
BEGIN
s := s - m;
a:= a +round(d1x);
b := b + round(d1y);
END
ELSE
BEGIN
a := a + round(d2x);
b := b + round(d2y);
END;
end;
END;
This routine is very fast, and should meet almost all of your requirements
(ASPHYXIA used it for quite a while before we made our new one.)
In the end program, both the new line routine and the circle routine are
tested. A few of the procedures of the first parts are also used.Line and circle routines may seem like fairly trivial things, but they are a vital component of many programs, and you may like to look up other methods of drawing them in books in the library (I know that here at the varsity they have books for doing this kind of stuff all over the place) A good line routine to look out for is the Bressenhams line routine ... there is a Bressenhams circle routine too ... I have documentaiton for them if anybody is interested, they are by far some of the fastest routines you will use.
- In closing
[ "What does it do?" she asks.
"It's a computer," he replies.
"Yes, dear, but what does it do?"
"It ..er.. computes! It's a computer."
"What does it compute?"
"What? Er? Um. Numbers! Yes, numbers!" He smiles
worriedly.
"Why?"
"Why? Well ..um.. why?" He starts to sweat.
"I mean, is it just something to dust around, or does
it actually do something useful?"
"Um...you can call other computers with it!" Hope lights
up his eyes. "So you can get programs from other computers!"
"I see. Tell me, what do these programs do?"
"Do? I don't think I fol..."
"I see. They compute. Numbers. For no particular reason." He
withers under her gaze.
"Yes, but..."
She smiles, and he trails off, defeated. She takes another look
at the thing. "Although," she says, with a strange look in
her eyes. He looks up, an insane look of hope on his
face. "Does it come in pink?" she asks.
]
- Grant Smith
Tue 27 July, 1993
9:35 pm.
See you next time,
- Denthor
[Edit this page] [Page history] [What links here] [Discuss this topic] [Printer Friendly]
