Article View: rec.games.programmer
Article #1636Bitmap rotation & scaling solution
From: Kristof Roomp
Date: Thu, 19 Nov 1992 19:07
Date: Thu, 19 Nov 1992 19:07
156 lines
4661 bytes
4661 bytes
hey guys!
while dreaming my way through linear algebra, I suddenly realized that
linear transformations could be quite handy in rotating, scaling, etc. of
bitmaps. here's a quicky version of my idea.... it should be possible to
make it use integer arithmetic with little trouble (ie. a LOT faster). I
just wanted to make clear what the program was doing...
here ya go...
typedef struct
{
double a,b,c,d;
} MATRIX22;
// initializes a transform matrix.
void initmatrix(MATRIX *m)
{
m->a=1; m->b=0; m->c=0; m->d=1;
}
// multiplies two matrices. resu stored in m1.
void matrixmul(MATRIX22 *m1,MATRIX22 *m2)
{
MATRIX22 m3;
m3.a=m1->a*m2->a + m1->b*m2->c;
m3.b=m1->a*m2->b + m1->b*m2->d;
m3.c=m1->c*m2->a + m1->d*m2->c;
m3.d=m1->c*m2->b + m1->d*m2->d;
*m1=m3;
}
// scales x axis by factor
void ScaleX(MATRIX22 *m,double factor)
{
MATRIX22 m2;
m2.a=factor; m2.b=0;
m2.c=0; m2.d=1;
matrixmul(m,&m2);
}
// scales y axis by factor
void ScaleY(MATRIX22 *m,double factor)
{
MATRIX22 m2;
m2.a=1; m2.b=0;
m2.c=0; m2.d=factor;
matrixmul(m,&m2);
}
// rotates counterclockwise by angle
void Rotate(MATRIX22 *m,double angle)
{
MATRIX22 m2;
m2.a=cos(angle); m2.b=-sin(angle);
m2.c=sin(angle); m2.d=cos(angle);
matrixmul(m,&m2);
}
// reflects about a line through the origin of angle angle
void Reflect(MATRIX22 *m,double angle)
{
MATRIX22 m2;
m2.a=cos(2*angle); m2.b=sin(2*angle);
m2.c=sin(2*angle); m2.d=-cos(2*angle);
matrixmul(m,&m2);
}
// notice you can perform as many of the above transformation as you want
// on the matrix before passing it to LinearTransform. you might rotate,
// scale, and rotate again... all done in one swoop.
// very inefficient linear transform from one bitmap to another
// lots of optimization possible, though.
#define min(a,b) ( (a<b) ? a : b )
#define max(a,b) ( (a>b) ? a : b )
void LinearTransform(HBITMAP source,HBITMAP target,int xorg,int yorg,
int xtarg,int ytarg,MATRIX22 *m)
{
double a,b,c,d,ai,bi,ci,di,det;
int x1,y1,x2,y2,x3,y3,x4,y4,minx,miny,maxx,maxy,x,y,xp,yp;
a=m->a; b=m->b; c=m->c; d=m->d;
det=a*d-b*c;
if (det==0)
Error("LinearTransform: a non-invertible transform matrix");
ai=d/det; bi=-b/det; ci=-c/det; di=a/det;
x1=-xorg*a + -yorg*b;
y1=-xorg*c + -yorg*d;
x2=(source->xsize-xorg)*a + -yorg*b;
y2=(source->xsize-xorg)*c + -yorg*d;
x3=-xorg*a + (source->ysize-yorg)*b;
y3=-xorg*c + (source->ysize-yorg)*d;
x4=(source->xsize-xorg)*a + (source->ysize-yorg)*b;
y4=(source->xsize-xorg)*c + (source->ysize-yorg)*d;
minx=min(x1,min(x2,min(x3,x4) ) );
maxx=max(x1,max(x2,max(x3,x4) ) );
miny=min(y1,min(y2,min(y3,y4) ) );
maxy=max(y1,max(y2,max(y3,y4) ) );
for (y=miny;y<=maxy;y++)
{
for(x=minx;x<=maxx;x++)
{
xp=x*ai + y*bi;
yp=x*ci + y*di;
DrawPixel(target,x+xtarg,y+ytarg,
GetPixel(source,xp+xorg,yp+yorg));
}
}
}
void main(void)
{
MATRIX22 m;
// set up graphics et al.
initmatrix(&m);
ScaleX(&m,2); // make x twice as big
Rotate(&m,1.04719); // rotate bitmap by pi/3 (60 degrees)
ScaleY(&m,2); // make y twice as big
Reflect(&m,0.7853); // reflect about a line with an angle of pi/4
(45 degrees)
LinearTransform(source,target,source->xsize/2,source->ysize/2,
get->xsize/2,target->ysize/2,&m);
// transform source to target (origin is at the center of both
// bitmaps
// continue program...
}
thats it... see if you can come up with some clever integer arithmetic to
speed up the process...
Technical Details
Message-ID:
<krisr.722200021@cue>Path:
arc1-ca.pugleaf.net!sparky!uunet!cs.utexas.edu!zaphod.mps.ohio-state.edu!caen!destroyer!cs.ubc.ca!news.UVic.CA!softwords!cue!krisrShow Full Headers
Complete Article Headers
Newsgroups: rec.games.programmer Path: arc1-ca.pugleaf.net!sparky!uunet!cs.utexas.edu!zaphod.mps.ohio-state.edu!caen!destroyer!cs.ubc.ca!news.UVic.CA!softwords!cue!krisr From: krisr@cue.bc.ca (Kristof Roomp) Subject: Bitmap rotation & scaling solution Message-ID: <krisr.722200021@cue> Summary: How to use a linear xfrom to rotate & scale bitmaps Keywords: graphics bitmap Sender: news@softwords.bc.ca (CNews) Nntp-Posting-Host: cue.bc.ca Organization: Softwords Research International Ltd., Victoria, B.C., Canada Date: 19 Nov 92 19:07:01 GMT Lines: 156