Добавил:
Studfiles2
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Лабораторная работа / CGLABS2D
.CPP#include<conio.h>
#include<graphics.h>
#include<process.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include <dos.h>
#define LEFT 75
#define RIGHT 77
#define UP 72
#define DOWN 80
struct P
{
int x,y;
}points[100];
/////////////////////////////////////////////////////////////////////////////
//Bresenhames algorithm
void Line(int x1,int y1,int x2, int y2,int color)
{
int dx=abs(x2-x1);
int dy=abs(y2-y1);
int sx=(x2>=x1) ? 1:-1;
int sy=(y2>=y1) ? 1:-1;
if(dy<=dx)
{
int d=(dy<<1)-dx;
int d1=(dy<<1);
int d2=(dy-dx)<<1;
putpixel(x1,y1,color);
for(int x=x1+sx,y=y1,i=1;i<=dx;++i,x+=sx)
{
if(d>0)
{
d+=d2;
y+=sy;
}
else d+=d1;
putpixel(x,y,color);
}
}
else
{
int d=(dx<<1)-dy;
int d1=(dx<<1);
int d2=(dx-dy)<<1;
putpixel(x1,y1,color);
for(int x=x1,y=y1+sy,i=1;i<=dy;++i,y+=sy)
{
if(d>0)
{
d+=d2;
x+=sx;
}
else d+=d1;
putpixel(x,y,color);
}
}
}
/////////////////////////////////////////////////////////////////////////////
//Interpolation algorithm
void ILine(int x1,int x2, int y,int ia,int ib)
{
long i=((long) ia)<<16;
long di=(((long)(ib-ia))<<16)/(x2-x1+1);
for(int x=x1;x<=x2;i+=di,x++)
putpixel(x,y,(int)(i>>16));
}
/////////////////////////////////////////////////////////////////////////////
//Rectangle algorithm
void Rectangle(int x1,int y1,int x2, int y2,int color)
{
Line(x1,y1,x2,y1,color);
Line(x2,y1,x2,y2,color);
Line(x1,y2,x2,y2,color);
Line(x1,y1,x1,y2,color);
}
/////////////////////////////////////////////////////////////////////////////
//Circle algorithm
void circlePoints(int xc,int yc,int x,int y,int color)
{
putpixel(xc+x,yc+y,color);
putpixel(xc+y,yc+x,color);
putpixel(xc+y,yc-x,color);
putpixel(xc+x,yc-y,color);
putpixel(xc-x,yc-y,color);
putpixel(xc-y,yc-x,color);
putpixel(xc-y,yc+x,color);
putpixel(xc-x,yc+y,color);
}
void Circle(int xc,int yc,int r,int color)
{
int x=0;
int y=r;
int d=1-r;
int delta1=3;
int delta2=-2*r+5;
circlePoints(xc,yc,x,y,color);
while(y>x)
{
if(d<0)
{
d+=delta1;
delta1+=2;
delta2+=2;
x++;
}
else
{
d+=delta2;
delta1+=2;
delta2+=4;
x++; y--;
}
circlePoints(xc,yc,x,y,color);
}
}
/////////////////////////////////////////////////////////////////////////////
//Sazerland-Kohen
void swap(int&a,int&b)
{
int c;
c=a;
a=b;
b=c;
}
int outCode(int x,int y,int X1,int Y1,int X2,int Y2)
{
int code=0;
if(x<X1) code|=0x01;
if(y<Y1) code|=0x02;
if(x>X2) code|=0x04;
if(y>Y2) code|=0x08;
return code;
}
void clipLine(int x1,int y1,int x2,int y2,int X1,int Y1,int X2,int Y2,int lc,int rc)
{
int code1=outCode(x1,y1,X1,Y1,X2,Y2);
int code2=outCode(x2,y2,X1,Y1,X2,Y2);
int inside=(code1|code2)==0;
int outside=(code1&code2)!=0;
while(!outside&&!inside)
{
if(code1==0)
{
swap(x1,x2);
swap(y1,y2);
swap(code1,code2);
}
if(code1&0x01)//clip left
{
y1+=(long)(y2-y1)*(X1-x1)/(x2-x1);
x1=X1;
}
else
if(code1&0x02)//clip above
{
x1+=(long)(x2-x1)*(Y1-y1)/(y2-y1);
y1=Y1;
}
else
if(code1&0x04)//clip right
{
y1+=(long)(y2-y1)*(X2-x1)/(x2-x1);
x1=X2;
}
else
if(code1&0x08)//clip below
{
x1+=(long)(x2-x1)*(Y2-y1)/(y2-y1);
y1=Y2;
}
code1=outCode(x1,y1,X1,Y1,X2,Y2);
code2=outCode(x2,y2,X1,Y1,X2,Y2);
inside=(code1|code2)==0;
outside=(code1&code2)!=0;
}
if(!outside)
Line(x1,y1,x2,y2,lc);
Rectangle(X1,Y1,X2,Y2,rc);
}
/////////////////////////////////////////////////////////////////////////////
int LineFill(int x,int y,int dir,int prevXl,int prevXr,int borderColor,int color,int ifill)
{
int xl=x;int xr=x;
int c;
//find line segment
do c=getpixel(--xl,y);
while((c!=borderColor)&&(c!=color));
do c=getpixel(++xr,y);
while((c!=borderColor)&&(c!=color));
xl++;;xr--;
if(ifill)
ILine(xl,xr,y,color,getmaxcolor()-color);//fill segment
else Line(xl,y,xr,y,color);//fill segment
//fill adjacent segments in the same direction
for(x=xl;x<=xr;x++)
{
c=getpixel(x,y+dir);
if((c!=borderColor)&&(c!=color))
x=LineFill(x,y+dir,dir,xl,xr,borderColor,color,ifill);
}
for(x=xl;x<=prevXl;x++)
{
c=getpixel(x,y-dir);
if((c!=borderColor)&&(c!=color))
x=LineFill(x,y-dir,-dir,xl,xr,borderColor,color,ifill);
}
for(x=prevXr;x<xr;x++)
{
c=getpixel(x,y-dir);
if((c!=borderColor)&&(c!=color))
x=LineFill(x,y-dir,-dir,xl,xr,borderColor,color,ifill);
}
return xr;
}
void Fill(int x,int y,int borderColor,int color,int ifill)
{
LineFill(x,y,1,x,x,borderColor,color,ifill);
}
/////////////////////////////////////////////////////////////////////////////
void DrawArea(struct P points[100],int n,int ocolor,int icolor,int x,int y,int ifill)
{
int i;
for(i=0;i<n-1;++i)
Line(points[i].x,points[i].y,points[i+1].x,points[i+1].y,ocolor);
Line(points[0].x,points[0].y,points[n-1].x,points[n-1].y,ocolor);
Fill(x,y,ocolor,icolor,ifill);
}
/////////////////////////////////////////////////////////////////////////////
int menu()
{
char ch;
int midx = getmaxx() / 2;
int midy = getmaxy() / 2;
do
{
/* clear the screen */
cleardevice();
/* for centering screen messages */
settextjustify(CENTER_TEXT, CENTER_TEXT);
setcolor(RED);
outtextxy(midx, midy-50, "=====The main menu=====");
setcolor(MAGENTA);
outtextxy(midx, midy-40, "1->Bresenhames algorithm");
setcolor(GREEN);
outtextxy(midx, midy-30, "2->Interpolation");
setcolor(MAGENTA);
outtextxy(midx, midy-20, "3->Sazerland-Kohen algoritm");
setcolor(GREEN);
outtextxy(midx, midy-10, "4->Circle");
setcolor(MAGENTA);
outtextxy(midx, midy, "5->Fill any (simple or complex) area");
setcolor(GREEN);
outtextxy(midx, midy+10, "6->Random lines");
setcolor(CYAN);
outtextxy(midx, midy+20, "ESC->Exit");
setcolor(YELLOW);
outtextxy(midx, midy+30, "Do your choice: ");
ch=getch();
}while(((ch<'1')||(ch>'6'))&&ch!=27);
setcolor(WHITE);
return ch;
}
/////////////////////////////////////////////////////////////////////////////
//Initialization of the graphics system
void init()
{
/* request auto detection */
int gdriver = DETECT, gmode, errorcode;
/* initialize graphics mode */
initgraph(&gdriver, &gmode, "");
/* read result of initialization */
errorcode = graphresult();
if (errorcode != grOk) /* an error occurred */
{
printf("Graphics error: %s\n", grapherrormsg(errorcode));
printf("Press any key to halt:");
getch();
exit(1); /* return with error code */
}
}
/////////////////////////////////////////////////////////////////////////////
void main(void)
{
char ch,key,buff[256],str[256];
int x1,y1,x2,y2,color,xmax,ymax,cmax;
int X1,Y1,X2,Y2,rcolor,icolor,ocolor;
struct P points[100];
float x,y;
int i,n;
init();
xmax=getmaxx();
ymax=getmaxy();
cmax=getmaxcolor();
while(1)
{
ch=menu();
switch(ch)
{
case '1':
restorecrtmode();
puts("Please give (x1,y1,x2,y2) and the color");
strcpy(buff,"x<=");
strcat(buff,itoa(xmax,str,10));
strcat(buff,", y<=");
strcat(buff,itoa(ymax,str,10));
strcat(buff,", color<=");
strcat(buff,itoa(cmax,str,10));
puts(buff);
scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&color);
setgraphmode(getgraphmode());
Line(x1,y1,x2,y2,color);
while((key=getch())!=27)
{
switch(key)
{
case LEFT:x1--;x2--;break;
case RIGHT:x1++;x2++;break;
case UP:y1--;y2--;break;
case DOWN:y1++;y2++;break;
case '1':
x=x1*cos(M_PI_4)-y1*sin(M_PI_4)-x2*cos(M_PI_4)+y2*sin(M_PI_4)+x2;
y=x1*sin(M_PI_4)+y1*cos(M_PI_4)-x2*sin(M_PI_4)-y2*cos(M_PI_4)+y2;
x1=x;y1=y;
break;
case '2':
x=x2*cos(M_PI_4)-y2*sin(M_PI_4)-x1*cos(M_PI_4)+y1*sin(M_PI_4)+x1;
y=x2*sin(M_PI_4)+y2*cos(M_PI_4)-x1*sin(M_PI_4)-y1*cos(M_PI_4)+y1;
x2=x;y2=y;
break;
}
cleardevice();
Line(x1,y1,x2,y2,color);
}
break;
case '2':
int ia,ib;
restorecrtmode();
puts("Please give line (x1,x2,y,color1,color2)");
strcpy(buff,"x<=");
strcat(buff,itoa(xmax,str,10));
strcat(buff,", y<=");
strcat(buff,itoa(ymax,str,10));
strcat(buff,", color<=");
strcat(buff,itoa(cmax,str,10));
puts(buff);
scanf("%d%d%d%d%d",&x1,&x2,&y2,&ia,&ib);
setgraphmode(getgraphmode());
ILine(x1,x2,y2,ia,ib);
while((key=getch())!=27)
{
switch(key)
{
case LEFT:x1--;x2--;break;
case RIGHT:x1++;x2++;break;
case UP:y1--;y2--;break;
case DOWN:y1++;y2++;break;
}
cleardevice();
ILine(x1,x2,y2,ia,ib);
}
break;
case '3':
restorecrtmode();
puts("Please give line (x1,y1,x2,y2) and the color");
strcpy(buff,"x<=");
strcat(buff,itoa(xmax,str,10));
strcat(buff,", y<=");
strcat(buff,itoa(ymax,str,10));
strcat(buff,", color<=");
strcat(buff,itoa(cmax,str,10));
puts(buff);
scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&color);
puts("Please give rectangle (x1,y1,x2,y2) and the color");
puts(buff);
scanf("%d%d%d%d%d",&X1,&Y1,&X2,&Y2,&rcolor);
setgraphmode(getgraphmode());
clipLine(x1,y1,x2,y2,X1,Y1,X2,Y2,color,rcolor);
while((key=getch())!=27)
{
switch(key)
{
case LEFT:X1--;X2--;break;
case RIGHT:X1++;X2++;break;
case UP:Y1--;Y2--;break;
case DOWN:Y1++;Y2++;break;
case '1':x1--;x2--;break;
case '2':x1++;x2++;break;
case '3':y1--;y2--;break;
case '4':y1++;y2++;break;
}
cleardevice();
clipLine(x1,y1,x2,y2,X1,Y1,X2,Y2,color,rcolor);
}
break;
case '4':
restorecrtmode();
puts("Please give (xc,yc,radius) and the color");
strcpy(buff,"xc<=");
strcat(buff,itoa(xmax,str,10));
strcat(buff,", yc<=");
strcat(buff,itoa(ymax,str,10));
strcat(buff,", color<=");
strcat(buff,itoa(cmax,str,10));
puts(buff);
scanf("%d%d%d%d%",&x1,&y1,&x2,&color);
setgraphmode(getgraphmode());
Circle(x1,y1,x2,color);
while((key=getch())!=27)
{
switch(key)
{
case LEFT:x1--;break;
case RIGHT:x1++;break;
case UP:y1--;break;
case DOWN:y1++;break;
}
cleardevice();
Circle(x1,y1,x2,color);
}
break;
case '5':
int ifill;
restorecrtmode();
puts("Please give polygone points");
puts("Enter number of points < 100");
scanf("%d",&n);
for(i=0;i<n;++i)
{
printf("Give point %d\n",i);
scanf("%d%d",&points[i].x,&points[i].y);
}
puts("Enter inside and outside colors (not the same)");
scanf("%d%d",&icolor,&ocolor);
printf("Give a point in the area\n");
scanf("%d%d",&x1,&y1);
printf("Give the kind of fill (0-for normal fill or other for interpolation fill)\n");
scanf("%d",&ifill);
setgraphmode(getgraphmode());
DrawArea(points,n,ocolor,icolor,x1,y1,ifill);
while((key=getch())!=27)
{
switch(key)
{
case LEFT:for(i=0;i<n;++i) points[i].x--;break;
case RIGHT:for(i=0;i<n;++i) points[i].x++;break;
case UP:for(i=0;i<n;++i) points[i].y--;break;
case DOWN:for(i=0;i<n;++i) points[i].y++;break;
}
cleardevice();
DrawArea(points,n,ocolor,icolor,x1,y1,ifill);
}
break;
case '6':
int n=0;
cleardevice();
while(!kbhit())
{
if(n==100)
{
cleardevice();
n=0;
}
ILine(rand()%xmax,rand()%xmax,rand()%ymax,rand()%cmax,rand()%cmax);
//Line(rand()%xmax,rand()%ymax,rand()%xmax,rand()%ymax,rand()%cmax);
delay(100);
n++;
}
break;
case 27:
/* closes down the graphics system */
closegraph();return;
}
}
}
Соседние файлы в папке Лабораторная работа