[Back to EGAVGA SWAG index] [Back to Main SWAG index] [Original]
{
> I am trying to learn how to, and do, scaling and rotaing of images. I
> can put the image on a extrnal page and then I would like to do stuff
> with it. Please help.
Scaling, rotation, shearing, translations etc are all simple affine
transformations. I assume you have the math, no?
Anyhow to sum it up:
Shearing
Qx = Px + G*Py
Qy = Py + H*Px
Where: Q = new point.
P = old point.
G = x shear factor
H = y shear factor
H & G are decimal numbers normally, here's an interesting demo of
a shear - it almost looks like 3-d rotation, but it's definitely not.
Btw you need somesort of fast graphics unit that is 1 based (ie 1,1 is
the top point - or rewrite the routines). Personally I'm using x320x240
by Sean Palmer, but I've added a bunch of stuff to it..
}
Program Shearing;
Uses Crt,x320x240; { by John Stephenson, 1995 }
{ Almost looks like rotation, eh? It's NOT! :-) It's just that the triangle }
{ when sheared goes down to 0, creating the effects that it is being }
{ rotated, pretty neat, eh? }
Type
tPoint = record
x,y: word;
end;
tTriangle = record
color: byte;
a,b,c: tPoint;
end;
Procedure DrawTriangle(var tri: tTriangle);
begin
with tri do begin
line(a.x,a.y,b.x,b.y,color);
line(b.x,b.y,c.x,c.y,color);
line(c.x,c.y,a.x,a.y,color);
end;
end;
Procedure ShearPoint(var xold,yold,x,y: word; xshear,yshear: Real);
Begin
x := xOld+round(yOld*xShear);
y := yOld+round(xOld*yShear);
End;
Procedure ShearTriangle(var tri,stri: tTriangle; xshear,yshear: real);
Begin
with tri.a do ShearPoint(x,y,stri.a.x,stri.a.y,xshear,yshear);
with tri.b do ShearPoint(x,y,stri.b.x,stri.b.y,xshear,yshear);
with tri.c do ShearPoint(x,y,stri.c.x,stri.c.y,xshear,yshear);
End;
Var
oldsTri,sTri,Tri: tTriangle;
yshear,xshear,xdir,ydir: real;
loop: byte;
Begin
graphbegin;
Setcolor(0,0,0,0);
For loop := 1 to 127 do setcolor(loop,255-loop div 2,0,loop div 2);
For loop := 128 to 255 do setcolor(loop,loop div 2,0,255-loop div 2);
with tri do begin
a.x := 5;
a.y := 30;
b.x := 30;
b.y := 1;
c.x := 50;
c.y := 30;
color := 1;
end;
stri := tri;
oldstri := stri;
xshear := 0;
yshear := 0;
ydir := 0.05;
xdir := 0.05;
repeat
cycle(1,255,1);
xshear := xshear+xdir;
yshear := yshear+ydir;
if (xshear > 4) or (xshear <= 0) then xdir := -xdir;
if (yshear > 4) or (yshear <= 0) then ydir := -ydir;
oldstri := stri;
sheartriangle(Tri,sTri,xshear,yshear);
{ Delete the old one }
oldstri.color := 0;
retrace;
drawtriangle(oldsTri);
{ Make the new one }
drawtriangle(sTri);
until keypressed;
readkey;
graphend;
textattr := lightgray;
clrscr;
textattr := lightcyan;
writeln('Shearing demo, by John Stephenson');
End.
{
Rotations are interesting.. basically the general idea is:
Qx := (Px * cos theta) - (Py * sin theta);
Qy := (Px * sin theta) + (Py * cos theta);
Now Q and P are the same for shearing, etc. Theta if you don't know is
how many degrees you want to rotate it by. In Pascal cos & sin use something
called radians. There are 2pi (you've heard of 2*pi*r to calculate the
circumference, right? It's based on that) radians in a circle, contrasted
to 360 degrees in a circle. The begining point is at (radius,0) (middle
left side) - and that's where the point of 0 radians starts for Pascal.
Btw does anyone know what GRAD means? On my scientific calculator I have
RAD, DEG, and GRAD. I don't get GRAD...
Here's a simple program to illustrate:
}
Program Rotation;
Uses Crt,x320x240; { by John Stephenson, 1995 }
Type
tPoint = record
x,y: integer;
end;
tTriangle = record
color: byte;
a,b,c: tPoint;
end;
Procedure DrawTriangle(var tri: tTriangle);
begin
with tri do begin
line(a.x,a.y,b.x,b.y,color);
line(b.x,b.y,c.x,c.y,color);
line(c.x,c.y,a.x,a.y,color);
end;
end;
Procedure RotatePoint(var oldx,oldy,x,y,aroundx,aroundy: integer; rad: real);
Begin
x := aroundx+round(oldx*cos(rad) - oldy*sin(rad));
y := aroundy+round(oldx*sin(rad) + oldy*cos(rad));
End;
Procedure RotateTriangle(var tri,rtri: tTriangle; ax,ay: integer; rad: real);
{ Rotate triangle "tri" into "rTri" around "ax","ay" "rad" radians }
Begin
with tri.a do rotatepoint(x,y,rTri.a.x,rTri.a.y,ax,ay,rad);
with tri.b do rotatepoint(x,y,rTri.b.x,rTri.b.y,ax,ay,rad);
with tri.c do rotatepoint(x,y,rTri.c.x,rTri.c.y,ax,ay,rad);
End;
Var
oldsTri,sTri,Tri: tTriangle;
rad: real;
loop: byte;
Begin
graphbegin;
Setcolor(0,0,0,0);
For loop := 1 to 127 do setcolor(loop,255-loop div 2,0,loop div 2);
For loop := 128 to 255 do setcolor(loop,loop div 2,0,255-loop div 2);
with tri do begin
a.x := 5;
a.y := 30;
b.x := 30;
b.y := 1;
c.x := 50;
c.y := 30;
color := 1;
end;
stri := tri;
oldstri := stri;
rad := 0;
repeat
cycle(1,255,1);
rad := rad + 0.05;
if rad > 2*pi then rad := 0;
oldstri := stri;
RotateTriangle(tri,stri,xmid,ymid,rad);
{ Delete the old one }
oldstri.color := 0;
retrace;
drawtriangle(oldsTri);
{ Make the new one }
drawtriangle(sTri);
until keypressed;
readkey;
graphend;
textattr := lightgray;
clrscr;
textattr := lightcyan;
writeln('Rotation demo, by John Stephenson');
End.
{
To translate something it's pretty easy.. ie just:
Qx = Px + h
Qy = Py + g
Where h, and g are the directions.. simple idea.
Lets see.. there's a whole bunch of affine and inverse affine
transformations that are worth taking a look at. If you haven't taken
atleast grade 12 or OAC math learn the basics of Cosine, Sine, and
Tangent (or if you have, skip that).. then pick up a computer graphics
book (hopefully for Pascal) :)
We've gotta remember this is a pascal programming echo, and not a math
echo :) Hopefully this has helped out a bit.. Basically remember when
you're rotating an image, all you're -really- doing is applying the
rotation formulae to each pixel, and same with shearing.
}
[Back to EGAVGA SWAG index] [Back to Main SWAG index] [Original]