Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
17
Добавлен:
01.05.2014
Размер:
12.61 Кб
Скачать
#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;
     }
   }
}
Соседние файлы в папке Лабораторная работа