计算机图形学实验-几何图形的比例和旋转变换

实验内容:

显示一个飞机:(飞机各顶点的坐标存放在数组中)

(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;
}


  • 5
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值