实验内容:
显示一个飞机:(飞机各顶点的坐标存放在数组中)
(1)按比例缩小或放大.缩放比例由键盘输入,缩放的参考点由用户确定;
(2)旋转.由键盘输入旋转角度和旋转中心;
第一个是比例变换
#include <graphics.h>
#include <stdio.h>
#include <conio.h>
#include <math.h>
int f[20][2] = {285,70,310,100,310,185,430,240,440,260,310,225,310,355,285,375,335,390,340,405,285,395,230,405,235,390,285,375,260,355,260,225,130,260,140,240,260,185,260,100};
int b;
float k;
int n = 20;
int a[20][2];
//f[20][2]中存放的是飞机的关键点
void DDALine( int x0,int y0,int x1,int y1 )
{
//DDA画直线算法
int dx,dy,epsl,k;
float x,y,xIncre,yIncre;
dx = x1 - x0;
dy = y1 - y0;
x = x0;
y = y0;
if( abs(dx) > abs(dy) )
epsl = abs(dx);
else
epsl = abs(dy);
xIncre = (float)dx / (float)epsl;
yIncre = (float)dy / (float)epsl;
for( k = 0; k <= epsl; k++ )
{
putpixel((int)(x+0.5),(int)(y+0.5),RED);
x += xIncre;
y += yIncre;
}
}
void Draw()
{
int i,j,p,q;
int gdriver = DETECT,gmode;
printf("请输入参考点(X,Y):\n");
scanf("%d %d",&p,&q);
printf( "请输入放大倍数(缩小0.5倍也是可以的):" );
scanf( "%f",&k );
//这里没设计缩小选项,但是放大0.5倍也是可以的
//不设计缩小选项是为了减小代码量
for( i = 0; i < n; i++ )
{
//a[i][0]中存的是x
//a[i][1]中存的是y
//以下两行是通过书上的矩阵公式计算的
a[i][0] = ((f[i][0] - p) * k) + p;
a[i][1] = ((f[i][1] - q) * k) + q;
}
initgraph( 960,540 );
for( j = 0; j < 1000; j++ )
for( i = 0; i < 1000; i++ )
putpixel( i,j,WHITE );//首先生成一个960*540大小的窗口,并置成白色
for( i = 0; i < n - 1; i++ )
//DDA画直线,首先将飞机的点顺时针按序连成线
DDALine( a[i][0],a[i][1],a[i+1][0],a[i+1][1] );
DDALine( a[0][0],a[0][1],a[n-1][0],a[n-1][1] );
}
void change()
{
//动态填充算法
//不是自己写的
int i,j,k,s,dx,dy,temp;
int x0,y0,x1,y1,x2,y2;
for( i = 0; i < n; i++ )
{
if( i == n - 1 )
{
x0 = a[i][0];
y0 = a[i][1];
x1 = a[0][0];
y1 = a[0][1];
}
else
{
x0 = a[i][0];
y0 = a[i][1];
x1 = a[i+1][0];
y1 = a[i+1][1];
}
dx = x0 - x1;
dy = y0 - y1;
if( y0 > y1 )
{
temp = x0;
x0 = x1;
x1 = temp;
temp = y0;
y0 = y1;
y1 = temp;
}
for( j = y0; j < y1; j++ )
{
s = int( (j - y0) * dx / dy ) + x0;//求交点坐标
for( k = s; k < 1000; k++ )
{
if( getpixel( k,j ) == WHITE )
putpixel( k,j,BLACK );
else if( getpixel(k,j) == BLACK )
putpixel( k,j,WHITE );
else
putpixel( k,j,RED );
}
}
}
}
int main()
{
Draw();
change();
getch();
return 0;
}
下面的一个是旋转变换
#include <graphics.h>
#include <stdio.h>
#include <conio.h>
#include <math.h>
int f[20][2] = {285,70,310,100,310,185,430,240,440,260,310,225,310,355,285,375,335,390,340,405,285,395,230,405,235,390,285,375,260,355,260,225,130,260,140,240,260,185,260,100};
int b;
int n = 20;
int a[20][2];
float k;
//f[20][2]中存放的是飞机的关键点
void DDALine( int x0,int y0,int x1,int y1 )
{
//DDA画直线算法
int dx,dy,epsl,k;
float x,y,xIncre,yIncre;
dx = x1 - x0;
dy = y1 - y0;
x = x0;
y = y0;
if( abs(dx) > abs(dy) )
epsl = abs(dx);
else
epsl = abs(dy);
xIncre = (float)dx / (float)epsl;
yIncre = (float)dy / (float)epsl;
for( k = 0; k <= epsl; k++ )
{
putpixel((int)(x+0.5),(int)(y+0.5),RED);
x += xIncre;
y += yIncre;
}
}
void Draw()
{
int i,j,d,p,q;
int gdriver = DETECT,gmode;
printf("请输入旋转度数:\n");
scanf("%d",&d);
printf("请输入旋转中心:\n");
scanf("%d %d",&p,&q);
for( i = 0; i < n; i++ )
{
//a[i][0]中存的是x
//a[i][1]中存的是y
//以下两行是通过书上的矩阵公式计算的
a[i][0] = (f[i][0] - p) * cos(d*1.0) - (f[i][1] - q) * sin(d*1.0) + p;
a[i][1] = (f[i][0] - p) * sin(d*1.0) + (f[i][1] - q) * cos(d*1.0) + q;
}
initgraph( 960,540 );
for( j = 0; j < 1000; j++ )
for( i = 0; i < 1000; i++ )
putpixel( i,j,WHITE );//首先生成一个960*540大小的窗口,并置成白色
for( i = 0; i < n - 1; i++ )
//DDA画直线,首先将飞机的点顺时针按序连成线
DDALine( a[i][0],a[i][1],a[i+1][0],a[i+1][1] );
DDALine( a[0][0],a[0][1],a[n-1][0],a[n-1][1] );
}
void change()
{
int i,j,k,s,dx,dy,temp;
int x0,y0,x1,y1,x2,y2;
for( i = 0; i < n; i++ )
{
if( i == n - 1 )
{
x0 = a[i][0];
y0 = a[i][1];
x1 = a[0][0];
y1 = a[0][1];
}
else
{
x0 = a[i][0];
y0 = a[i][1];
x1 = a[i+1][0];
y1 = a[i+1][1];
}
dx = x0 - x1;
dy = y0 - y1;
if( y0 > y1 )
{
temp = x0;
x0 = x1;
x1 = temp;
temp = y0;
y0 = y1;
y1 = temp;
}
for( j = y0; j < y1; j++ )
{
s = int( (j - y0) * dx / dy ) + x0;//求交点坐标
for( k = s; k < 1000; k++ )
{
if( getpixel( k,j ) == WHITE )
putpixel( k,j,BLACK );
else if( getpixel(k,j) == BLACK )
putpixel( k,j,WHITE );
else
putpixel( k,j,RED );
}
}
}
}
int main()
{
Draw();
change();
getch();
return 0;
}