www.pudn.com > snowtiger.rar > snowtiger.C
#include "stdio.h"
#include "stdlib.h"
#include "graphics.h"
#include "conio.h"
#include "math.h"
/*int circle_sign=0; */ /*全局变量,当是选择对圆做变换时,即circle_sign=1,在调用函数时就执行变换矩阵*/
#define PI 3.1415926
#define TT 1
#define F 0
#define round(a) (int)(a+0.5)
#define MAX 100
typedef enum {FALSE,TRUE}Boolean;
typedef struct {
int x;
int y;
}Point;
typedef struct {
int PolygonNum;
Point verteces[MAX];
}Polygon;
void planar_change()
{
void Bresenham_Line(int ,int ,int ,int ,int);
void Bresenham_Circle(int,int,int);
/*界面输入参数*/
int _X0,_Y0; /*原点坐标*/
int input1,input2,selected1,selected2;
int selected1_sign[4];
/*程序中用到的循环指针*/
int i,j;
/*变换矩阵及参数*/
int a,b,c,d,p,q,l,m,s;
double radian,degree;
int input3,symmetry_sign;
int input4,level_cut_sign;
int T[3][3];
/*直线变换用到的参数*/
int x0, y0, x1, y1, color;
int P[2][3],Pt[2][3];
int temp0,temp1;
/*圆变换用到的参数*/
int P1[3],Pt1[3];
int temp3;
int height,width; /*屏幕的最大高度和宽度*/
int x,y,delta,delta1,delta2,direction;
int driver,mode,r;
int r0;
/*多边形的参数*/
int acme,input5,k;
int _temp[8],_color[8];
int P2[8][3];
int Pt2[8][3];
height=getmaxx();width=getmaxy();
height=height>>1;width=width>>1;
start:
selected1_sign[0]=0;
selected1_sign[1]=0;
selected1_sign[2]=0;
selected1_sign[3]=0;
printf("Select the graphics which you want transform!\n");
printf("***************************************************************************\n");
printf("* 1,beeline *");
printf("\n");
printf("* 2,circle *");
printf("\n");
printf("* 3,ellipse *");
printf("\n");
printf("* 4,polygon *");
printf("\n");
printf("* 0,exit program! *");
printf("\n");
printf("***************************************************************************\n");
printf("\n");
scanf("%d",&input1);
if(input1>=0 && input1<=4)selected1=input1;
else
{
printf("you chose the random graphics!\n");
selected1=rand()%4+1;
}
switch(selected1)
{
case 0: return;
case 1: /*变化直线*/
/*clrscr();*/ /*清屏*/
selected1_sign[0]=1;
printf("the location of beeline before changed!\n");
/*调用画线的函数*/
printf("Please the x coordinate of the first point :");
scanf("%d",&x0);
printf("The y coordinate of the first point please:");
scanf("%d",&y0);
printf("The x coordinate of the second point:");
scanf("%d",&x1);
printf("The y coordinate of the second point:");
scanf("%d",&y1);
printf("The Color of the Line :");
scanf("%d",&color);
driver=DETECT;
mode=0;
initgraph(&driver,&mode,"");
setgraphmode(getgraphmode());
outtextxy(10, 10, "before changed!");
Bresenham_Line(x0,y0,x1,y1,color);
settextjustify(CENTER_TEXT, CENTER_TEXT);
outtextxy(width, height, "output Circle after trasform !,Press any key to return");
getch();
restorecrtmode();
break;
case 2: /*变换圆,即属于曲线*/
selected1_sign[1]=1;
printf("Input the radius of the circle! also the value of r0:\n");
scanf("%d",&r0);
printf("the location of circle before changed!\n");
printf("Input the coordinate of origin about _X0\n");
scanf("%d",&_X0);
printf("Input the coordinate of origin about _Y0\n");
scanf("%d",&_Y0);
getch();
Bresenham_Circle(r0,_X0,_Y0);
break; /*circle*/
case 3: break; /*ellipse*/
case 4:
selected1_sign[3]=1;
printf("Input the number of acme(acme>3&&acme<8)! ");
scanf("%d",&input5);
while(input5<3 || input5>8)
{
printf("acme should be greater than 3 and less than 8!\n");
printf("Input the number of acme again!\n");
scanf("%d",&input5);
}
acme=input5;
for(i=0;i=0 && input2<=5)selected2=input2;
else selected2=rand()%5+1;
/*clrscr();*/ /*清屏*/
switch(selected2)
{
case 0: goto start;
case 1: /* 平移变换*/
printf("Input the value of l:");
scanf("%d",&l);
printf("Input the value of m:");
scanf("%d",&m);
T[2][0]=l;
T[2][1]=m;
break;
case 2: /*比例变换*/
printf("Input the value of a:");
scanf("%d",&a);
printf("Input the value of b:");
scanf("%d",&b);
T[0][0]=a;
T[1][1]=b;
break;
case 3: /*旋转变换*/
printf("Input the degree of θthat you want circumvolve (θ>0 means anticlockwise,θ<0 means deasil )\n");
scanf("%f",°ree);
radian=degree*PI/180;
T[0][0]=(int)cos(radian);
T[0][1]=(int)sin(radian);
T[1][0]=-(int)sin(radian);
T[1][1]=(int)cos(radian);
break;
case 4:/*对称变换*/
printf("*******************************************************************\n");
printf("* 1,symmetry about X *");
printf("\n");
printf("* 2,symmetry about Y *");
printf("\n");
printf("* 3,symmetry about origin *");
printf("\n");
printf("* 4,symmetry about Y=X *");
printf("\n");
printf("* 5,symmetry about Y=-X *");
printf("\n");
printf("*******************************************************************\n");
printf("\n");
printf("Input the transform you want!Select transform mode!");
scanf("%d",&input3);
if(input3>=1 && input3<=5)symmetry_sign=input3;
else symmetry_sign=rand()%5+1;
switch(symmetry_sign)
{
case 1:T[1][1]=-1;
break;
case 2:T[0][0]=-1;
break;
case 3:T[0][0]=-1;
T[1][1]=-1;
break;
case 4: T[0][0]=0;
T[1][1]=0;
T[0][1]=1;
T[1][0]=1;
break;
case 5: T[0][0]=0;
T[1][1]=0;
T[0][1]=-1;
T[1][0]=-1;
break;
}/*switch_2*/
break;
/*错切变换*/
case 5:
printf("*******************************************************************\n");
printf("* 1,the direction of X *");
printf("\n");
printf("* 2,the direction of Y *");
printf("\n");
printf("* 3,the direction of X&Y *");
printf("\n");
printf("*******************************************************************\n");
printf("\n");
printf("Input the transform you want!Select transform mode!");
scanf("%d",&input4);
if(input4>=1 && input4<=3)level_cut_sign=input4;
else level_cut_sign=rand()%3+1;
switch(level_cut_sign)
{
case 1:
printf("Input the value of c(about X)\n");
scanf("%d",&c);
T[1][0]=c;
break;
case 2: printf("Input the value of b(about Y)\n");
scanf("%d",&b);
T[0][1]=b;
break;
case 3: printf("Input the value of c(about X)\n");
scanf("%d",&c);
printf("Input the value of b(about Y)\n");
scanf("%d",&b);
T[1][0]=c;
T[0][1]=b;
break;
}/*switch_2*/
break;
}/*switch_1*/
/*做矩阵的乘法,先判断是对什么图形做变换,用selected1_sign[]*/
if(selected1_sign[0]==1) /*若是直线*/
{
P[0][0]=x0;
P[0][1]=y0;
P[1][0]=x1;
P[1][1]=y1;
for(j=0;j<3;j++)
{
temp0=0;
temp1=0;
for(i=0;i<3;i++)
{
temp0+=P[0][i]*T[i][j];
temp1+=P[1][i]*T[i][j];
}/*for_2*/
Pt[0][j]=temp0;
Pt[1][j]=temp1;
}/*for_1*/
x0=Pt[0][0];
y0=Pt[0][1];
x1=Pt[1][0];
y1=Pt[1][1];
driver=DETECT;
mode=0;
initgraph(&driver,&mode,"");
setgraphmode(getgraphmode());
outtextxy(10, 10, "transform as follows!");
Bresenham_Line(x0,y0,x1,y1,color);
settextjustify(CENTER_TEXT, CENTER_TEXT);
outtextxy(width, height+100, "output beeline after trasform !,Press any key to return");
getch();
restorecrtmode();
goto contiue;
}/*if_1*/
else if(selected1_sign[1]==1) /*若是圆*/
{
printf("changed as follow!\n");
getch();
driver=DETECT;
mode=0;
initgraph(&driver,&mode,"");
setgraphmode(getgraphmode());
/*---------------------------------------------------------------------*/
for(i=0;i=0)
{
P1[0]=x;
P1[1]=y;
for(j=0;j<3;j++)
{
temp3=0;
for(i=0;i<3;i++)
{
temp3+=P1[i]*T[i][j];
}/*for_2*/
Pt1[j]=temp3;
}/*for_1*/
putpixel(Pt1[0]+_X0,Pt1[1]+_Y0-2*T[2][1],RED);
putpixel(-Pt1[0]+_X0+2*T[2][0],Pt1[1]+_Y0-2*T[2][1],GREEN);
putpixel(Pt1[0]+_X0,-Pt1[1]+_Y0,WHITE);
putpixel(-Pt1[0]+_X0+2*T[2][0],-Pt1[1]+_Y0,YELLOW);
if(delta<0)
{
delta1=2*(delta+y)-1;
if(delta1<=0)direction=1;
else direction=2;
}/*if_2*/
else if(delta>0)
{
delta2=2*(delta-x)-1;
if(delta2<=0)direction=2;
else direction=3;
}/*if_2*/
else direction=2;
switch(direction)
{
case 1:x++;
delta+=2*x+1;
break;
case 2:x++;
y--;
delta+=2*(x-y+1);
break;
case 3:y--;
delta+=(-2*y+1);
break;
}/*switch*/
}/*while*/
settextjustify(CENTER_TEXT, CENTER_TEXT);
outtextxy(width, height+100, "output Circle after trasform !,Press any key to return");
getch();
restorecrtmode();
goto contiue;
}/*if_1*/
/*若是多边形*/
else if(selected1_sign[3]==1)
{
for(j=0;j>1;width=width>>1;
printf("Please the x coordinate of the first point :");
scanf("%d",&_x0);
printf("The y coordinate of the first point please:");
scanf("%d",&_y0);
printf("The x coordinate of the second point:");
scanf("%d",&_x1);
printf("The y coordinate of the second point:");
scanf("%d",&_y1);
printf("The Color of the Line :");
scanf("%d",&_color);
setgraphmode(getgraphmode());
Bresenham_Line(_x0,_y0,_x1,_y1,_color);
settextjustify(CENTER_TEXT, CENTER_TEXT);
outtextxy(width, height-100, "output beeline completed!,Press any key to return");
getch();
restorecrtmode();
return;
}
void Bresenham_Line(int x0,int y0,int x1,int y1,int color)
{
/*------------------------从键盘输入初试值-----------------------------------------*/
int height,width; /*屏幕的最大高度和宽度*/
int dx,dy,d,d_less_zero,d_notless_zero;
int x,y,x_min,y_min,x_max,y_max,k,i,temp;
/*int gdriver=DETECT,gmode; */ /*图形接口初始化*/
/* initgraph(&gdriver,&gmode,"");*/
/*d是判别式,此时d=2d*dx,d_less_zero是d<0时d的增量,d_notless_zero是d>=0时d的增量 */
height=getmaxx();width=getmaxy();
height=height>>1;width=width>>1;
/*setgraphmode(getgraphmode());*/
/*---------------------------------------------------------------------*/
for(i=0;iy0?y0:y1; /*因为y是单步加1,画线从y_min开始*/
y_max=y1>y0?y1:y0; /*画线到y_max结束*/
for(i=y_min;i<=y_max;i++)
{
putpixel(x0+width,height-i,color);
/*getch();*/
}
return; /*画直线完成,从函数返回*/
}/*if_1*/
if(y0==y1)
{
x_min=x1>x0?x0:x1; /*因为y是单步加1,画线从y_min开始*/
x_max=x1>x0?x1:x0; /*画线到y_max结束*/
for(i=x_min;i<=x_max;i++)
{
putpixel(i+width,height-y0,color);
/*getch();*/
}
return; /*画直线完成,从函数返回*/
}/*if_1*/
/*------------------------------------------------------------------------*/
k=(y1-y0)/(x1-x0); /*k为斜率*/
if(k<=1&&k>=-1) /*如果斜率在-1和1之间,即x为最大位移方向*/
{
if(x0>x1) /*exchange,因为x每次单步加一,所以应该使x0=小的*/
{
temp=y0;y0=y1;y1=temp;
temp=x0;x0=x1;x1=temp;
}/*if_2*/
x=x0;y=y0;
dx=x1-x0;dy=y1-y0;
d=dx-2*dy; /*初始化判别式*/
d_less_zero=2*dx-2*dy;
d_notless_zero=-2*dy;
if(y00)
{
y--;
d+=d_notless_zero;
}/*if_2*/
else d+=d_less_zero;
}/*while_1*/
}/*else_1*/
}/*if_1*/
/*--------------------------------------------------------------------------*/
else /*即k<-1或者k>1的情况,y为最大位移方向*/
{
if(y0>y1) /*exchange,因为y每次单步加一,所以应该使y0=小的*/
{
temp=y0;y0=y1;y1=temp;
temp=x0;x0=x1;x1=temp;
}/*if_1*/
x=x0;y=y0;
dx=x1-x0;dy=y1-y0;
d=2*dx-dy; /*初始化判别式*/
d_less_zero=2*dx;
d_notless_zero=2*dx-2*dy;
if(x00)
{
x++;
d+=d_notless_zero;
}/*if_2*/
else d+=d_less_zero;
}/*while_1*/
}/*if_1*/
else /*即k<-1时*/
{
d=2*dx+dy; /*初始化判别式*/
d_less_zero=2*dx;
d_notless_zero=2*dx+2*dy;
while(y>1;_width=_width>>1;
setgraphmode(getgraphmode());
/*---------------------------------------------------------------------*/
for(i=0;i<_height*2+100;i++)putpixel(_width+50,i,15);
for(i=0;i<_width*2+200;i++)putpixel(i,_height-50,15);
/*---------------------------------------------------------------------*/
_height-=50;
_width+=50;
x=0;
y=r;
delta=2*(1-r);
while(y>=0)
{
putpixel(x+x_0,y+y_0,RED);
putpixel(-x+x_0,y+y_0,GREEN);
putpixel(x+x_0,-y+y_0,WHITE);
putpixel(-x+x_0,-y+y_0,YELLOW);
if(delta<0)
{
delta1=2*(delta+y)-1;
if(delta1<=0)direction=1;
else direction=2;
}
else if(delta>0)
{
delta2=2*(delta-x)-1;
if(delta2<=0)direction=2;
else direction=3;
}
else direction=2;
switch(direction)
{
case 1:x++;
delta+=2*x+1;
break;
case 2:x++;
y--;
delta+=2*(x-y+1);
break;
case 3:y--;
delta+=(-2*y+1);
break;
}/*switch*/
}/*while*/
settextjustify(CENTER_TEXT, CENTER_TEXT);
outtextxy(_width, _height-100, "output Circle completed!,Press any key to return");
getch();
restorecrtmode();
}/*Bresenham_Circle*/
void MidpointEllipse(int m,int n,int a,int b,int color);
void _ellipse()
{
int driver,mode,x,y,a,b,color;
driver=DETECT;
mode=0;
initgraph(&driver,&mode,"");
printf("Input coordinate of origin x:");
scanf("%d",&x);
printf("Input coordinate of origin y:");
scanf("%d",&y);
printf("Input the value of a:");
scanf("%d",&a);
printf("Input the value of b:");
scanf("%d",&b);
printf("The Color of the Ellipse:");
scanf("%d",&color);
MidpointEllipse(x,y,a,b,color);
getch();
}/*ellipse*/
void MidpointEllipse(m,n,a,b,color)
{
float x,y,d1,d2;
x=0;y=b;
d1=b*b+a*a*(-b+0.25);
putpixel(m+x,n+y,color);
putpixel(m+x,n-y,color);
putpixel(m-x,n+y,color);
putpixel(m-x,n-y,color);
getch();
while(b*b*(x+1)0)
{
if(d2<0)
{
d2+=b*b*(2*x+2)+a*a*(-2*y+3);
x++;
y--;
}
else
{
d2+=a*a*(-2*y+3);
y--;
}
putpixel(m+x,n+y,color);
putpixel(m+x,n-y,color);
putpixel(m-x,n+y,color);
putpixel(m-x,n-y,color);
getch();
}
}
void FillPolygonPbyP(Polygon *P,int polygonColor,int backgroundColor)
{int x,y;
int i;
int gdriver=DETECT,gmode;
int Height,Width;
Boolean IsInside(Polygon *,int,int);
initgraph(&gdriver,&gmode,"");
Height=getmaxy();
Width=getmaxx();
for(y=0;y<=Height;y++) /* Judge Point By Point */
for(x=0;x<=Width;x++)
if(IsInside(P,x,y))
putpixel(x,Height-y,polygonColor);
else
putpixel(x,Height-y,backgroundColor);
getch();
closegraph();
}
Boolean IsInside(Polygon *P,int x,int y)
{int i;
int sum=0; /* sum is used to record the Code of each edge */
int Coding(float,float,float,float,int,int);
Boolean IsInEdge(int,int,int,int,int,int);
/* Deal with the Points On the Polygon */
for(i=0;iPolygonNum;i++)
if(IsInEdge(P->verteces[i].x,P->verteces[i].y,P->verteces[i+1].x,
P->verteces[i+1].y,x,y))
return TRUE;
for(i=1;i<=P->PolygonNum;i++)
sum+=Coding(P->verteces[i-1].x,P->verteces[i-1].y,
P->verteces[i].x,P->verteces[i].y,x,y);
if(sum==0)
return FALSE;
else
return TRUE;
}
Boolean IsInEdge(int x0,int y0,int x1,int y1,int x,int y)
{
if(x0==x1&&x0==x) /* when it's a vertical line */
{if((y>=y0&&y<=y1)||(y<=y0&&y>=y1))return TRUE;}
else if((y-y0)*(x1-x0)==(x-x0)*(y1-y0))
{if((x>=x0&&x<=x1)||(x<=x0&&x>=x1))return TRUE;}
return FALSE;
}
int Coding(float x0,float y0,float x1,float y1,int x,int y)
{int code0, code1;
float MidPointx,MidPointy;
if(x0>x&&y0>=y)
code0=0;
else if(x0<=x&&y0>y)
code0=1;
else if(x0x&&y1>=y)
code1=0;
else if(x1<=x&&y1>y)
code1=1;
else if(x1PolygonNum);
for(i=0;iPolygonNum;i++)
{
printf("The x Coordinate Of the %d Vertex.\n",i);
scanf("%d",&P->verteces[i].x);
printf("The y Coordinate Of the %d Vertex.\n",i);
scanf("%d",&P->verteces[i].y);
}
printf("The Color Of the Plygon Area:\n");
scanf("%d",&Color);
printf("The BackGroundColor Of the Screen.\n");
scanf("%d",&bgColor);
P->verteces[i].x=P->verteces[0].x;
P->verteces[i].y=P->verteces[0].y;
FillPolygonPbyP(P,Color,bgColor);
}
int LBLineClipTest(float p,float q,float *umax,float *umin)
{
float r;
int Returnvalue=TT;
if(p<0.0) {
r=q/p;
if(r> *umin)Returnvalue=F;
else if(r> *umax) *umax=r;
}
else
if(p>0.0) {
r=q/p;
if(r< *umax)Returnvalue=F;
else if(r< *umin) *umin=r;
}
else
if(q<0.0)Returnvalue=F;
return(Returnvalue);
}
void Bresenhamline(int x0,int y0,int x1,int y1,int t)
{
int dx,dy,epsl,k,x_temp,y_temp;
float x,y,xin,yin;
dx=x1-x0;
dy=y1-y0;
x=(float)x0;
y=(float)y0;
if(abs(dx)>abs(dy))epsl=abs(dx);
else epsl=abs(dy);
xin=(float)dx/(float)epsl;
yin=(float)dy/(float)epsl;
for(k=0;k<=epsl;k++){
x_temp=(int)(x+0.5);
y_temp=(int)(y+0.5);
putpixel(320+x_temp,240-y_temp,t);
x+=xin;
y+=yin;
}
}
void LB_Line_Clip(float wxl,float wxr,float wyb,float wyt,float x1,float y1,float x2,float y2)
{
float max,min,deltax,deltay;
int i,j,x,y;
deltax=x2-x1;
max =0.0; min =1.0;
/*设置坐标轴*/
for(i=-320;i<=320;i++)
{
x=i;
y=0;
putpixel(x+320,240-y,7);
}
for(j=-240;j<=240;j++)
{
y=j;
x=0;
putpixel(x+320,240-y,7);
}
Bresenhamline(round(wxl),round(wyb),round(wxl),round(wyt),3);
Bresenhamline(round(wxl),round(wyb),round(wxr),round(wyb),3);
Bresenhamline(round(wxl),round(wyt),round(wxr),round(wyt),3);
Bresenhamline(round(wxr),round(wyb),round(wxr),round(wyt),3);
if(LBLineClipTest(-deltax,x1-wxl,&max,&min))
if(LBLineClipTest(deltax,wxr-x1,&max,&min))
{ deltay=y2-y1;
if(LBLineClipTest(-deltay,y1-wyb,&max,&min))
if(LBLineClipTest(deltay,wyt-y1,&max,&min))
{
if(min<1.0)
{
x2=x1+min*deltax;
y2=y1+min*deltay;
}/*if_3*/
if(max>0.0)
{
x1+=max*deltax;
y1+=max*deltay;
}/*if_3*/
Bresenhamline(round(x1),round(y1),round(x2),round(y2),4);
}/*if_2*/
}/*if_1*/
}/*LB_Line_Clip*/
void line_clip()
{
int driver,mode;
float _wxl,_wxr,_wyb,_wyt,_x1,_y1,_x2,_y2;
driver=DETECT;
mode=0;
initgraph(&driver,&mode,"");
printf("Input the left coordinate _wxl\n");
scanf("%f",&_wxl);
printf("Input the right coordinate _wxr\n");
scanf("%f",&_wxr);
printf("Input the above coordinate _wyt\n");
scanf("%f",&_wyt);
printf("Input the below coordinate _wyb\n");
scanf("%f",&_wyb);
setgraphmode(getgraphmode());
LB_Line_Clip(_wxl,_wxr,_wyb,_wyt,_x1,_y1,_x2,_y2);
settextjustify(CENTER_TEXT, CENTER_TEXT);
outtextxy(300,350 , "completed!");
restorecrtmode();
getch();
}
void main()
{
int _input,_select;
int driver=DETECT,mode;
driver=DETECT;
mode=0;
initgraph(&driver,&mode,"");
setgraphmode(getgraphmode());
settextjustify(CENTER_TEXT, CENTER_TEXT);
outtextxy(300,200 , " Welcome the usage");
outtextxy(290,220 , " designed by liuxuehu!");
outtextxy(290,230 , " number:0210340607");
outtextxy(500,400 , " 2005.1.9");
getch();
restorecrtmode();
contiue_input:
printf("***************************************************************************\n");
printf("* 1,create beeline *");
printf("\n");
printf("* 2,create circle *");
printf("\n");
printf("* 3,create ellipse *");
printf("\n");
printf("* 4,filling of polygon *");
printf("\n");
printf("* 5,basis transform of basis-graphics *");
printf("\n");
printf("* 6,line_clip *");
printf("\n");
printf("* 0,exit *");
printf("\n");
printf("***************************************************************************\n");
printf("\n");
printf(" Select the graphics which you want transform! \n");
scanf("%d",&_input);
while(_input>6||_input<0)
{
printf("you selected a wrong command! select again!\n");
goto contiue_input;
}
_select=_input;
switch(_select)
{
case 0:
setgraphmode(getgraphmode());
settextjustify(CENTER_TEXT, CENTER_TEXT);
outtextxy(300,200 , "thank usage!");
outtextxy(290,220 , " designed by liuxuehu!");
outtextxy(290,230 , " number:0210340607");
outtextxy(500,400 , " 2005.1.9");
getch();
return;
case 1:Line();break;
case 2:Circle();break;
case 3:_ellipse();break;
case 4: filling();break;
case 5: planar_change();break;
case 6:line_clip();break;
}
goto contiue_input;
}