C语言中面向对象的尝试
作者:周志明
说明:程序中关于画直线和园的算法,请参阅图形学相关知识.算法部分写在在main函数后.
运行环境:TC2.0(运行时候注意路径问题)
#include<graphics.h>
#include<stdio.h>
#include<math.h>
void InitGraphSys()
{
int driver,mode;
detectgraph(&driver,&mode);
initgraph(&driver,&mode,"");
}
/**/
typedef struct point
{
int x,y,color;
int (*fconstruct)();
int (*finput)();
int (*fdisplay)();
}POINT,*Point;
int Point_construct(Point pt,int x,int y,int color)
{
pt->x=x;
pt->y=y;
pt->color=color;
}
int Point_input(Point pt)
{
printf("Input the point info,format: Pt=x,y,color/n");
do{
printf("Pt=");
scanf("%d,%d,%d",&pt->x,&pt->y,&pt->color);
}while(pt->x<=0||pt->x>=639||pt->y<=0||pt->y>=479||pt->color<0||pt->color>15);
printf("OK/n");
}
int Point_display(Point pt)
{
putpixel(pt->x,pt->y,pt->color);
}
int Point_init(Point pt)
{
pt->x=pt->y=pt->color=0;
pt->fconstruct=Point_construct;
pt->finput=Point_input;
pt->fdisplay=Point_display;
}
/**/
typedef struct line
{
POINT p1,p2;
int (*fconstruct)();
int (*fcreate)();
int (*fdisplay)();
}LINE,*Line;
int Line_construct(Line ln,Point from,Point to)
{
ln->p1=*from;
ln->p2=*to;
}
int Line_create(Line ln)
{
ln->p1.finput(&ln->p1);
ln->p2.finput(&ln->p2);
}
int Line_display(Line ln)
{
dda(&ln->p1,&ln->p2);
/*line(ln->p1.x,ln->p1.y,ln->p2.x,ln->p2.y);*/
}
int Line_init(Line ln)
{
Point_init(&ln->p1),Point_init(&ln->p2);
ln->fconstruct=Line_construct;
ln->fcreate=Line_create;
ln->fdisplay=Line_display;
}
/**/
typedef struct circle
{
POINT pt;
int r;
int (*fcreate)();
int (*fdisplay)();
}CIRCLE,*Circle;
int Circle_create(Circle crcl)
{
crcl->pt.finput(&crcl->pt);
printf("the Circle's redius:/nRedius=");
scanf("%d",&crcl->r);
printf("OK/n");
}
int Circle_display(Circle crcl)
{
midptcircle(crcl);
/*circle(crcl->pt.x,crcl->pt.y,crcl->r);*/
}
int Circle_init(Circle crcl)
{
Point_init(&crcl->pt);
crcl->r=0;
crcl->fcreate=Circle_create;
crcl->fdisplay=Circle_display;
}
/**/
typedef struct ptnode
{
POINT pt;
struct ptnode* next;
}PTNODE,*Ptnode;
typedef struct polygon
{
int n;
Ptnode pnhead;
int (*fcreate)();
int (*fdisplay)();
}POLYGON,*Polygon;
int Polygon_create(Polygon pg,int n)
{
Ptnode pnpre=NULL,pncur=NULL;
if(!n) return 1;
pg->n=n;
pg->pnhead=pnpre=pncur=(Ptnode)malloc(sizeof(PTNODE));
pncur->next=NULL;
Point_init(&pncur->pt);
pncur->pt.finput(&pncur->pt);
while(--n)
{
pncur=(Ptnode)malloc(sizeof(PTNODE));
pncur->next=NULL;
pnpre->next=pncur;
pnpre=pncur;
Point_init(&pncur->pt);
pncur->pt.finput(&pncur->pt);
}
return 0;
}
int Polygon_display(Polygon pg)
{
int i;
LINE ln;
Ptnode head=pg->pnhead;
Line_init(&ln);
for(i=0;i<pg->n-1;i++)
{
ln.fconstruct(&ln,&head->pt,&head->next->pt);
ln.fdisplay(&ln);
head=head->next;
}
ln.fconstruct(&ln,&head->pt,&pg->pnhead->pt);
ln.fdisplay(&ln);
return 0;
}
int Polygon_init(Polygon pg)
{
pg->n=0;
pg->pnhead=NULL;
pg->fcreate=Polygon_create;
pg->fdisplay=Polygon_display;
}
int Polygon_destroy(Polygon pg)
{
Ptnode pncur=NULL;
while(pg->pnhead!=NULL)
{
pncur=pg->pnhead;
pg->pnhead=pncur->next;
free(pncur);
}
}
/***************************************************/
void main()
{
LINE ln;
CIRCLE cr;
POLYGON pg;
/**/
InitGraphSys();
setbkcolor(1);
/**/
Line_init(&ln);
ln.fcreate(&ln);
ln.fdisplay(&ln);
getch(),getch();
cleardevice();
Circle_init(&cr);
cr.fcreate(&cr);
cr.fdisplay(&cr);
getch(),getch();
cleardevice();
Polygon_init(&pg);
pg.fcreate(&pg,5);
pg.fdisplay(&pg);
Polygon_destroy(&pg);
getch(),getch();
closegraph();
}
/*******************************************/
int dda(POINT *p1,POINT *p2)
{
POINT star=(*p1);
int dx,dy,steps;
float x,y,xin=0.0,yin=0.0;
dx=(p2->x - p1->x);
dy=(p2->y - p1->y);
steps=(abs(dx)>abs(dy))?abs(dx):abs(dy);
if(!steps)
{
printf("ERROR:the two point overlap!");
}
else
{
xin=(float)dx/steps;
yin=(float)dy/steps;
x=star.x+0.5;
y=star.y+0.5;
do{
star.x=(int)x;
star.y=(int)y;
star.fdisplay(&star);
x+=xin;
y+=yin;
}while(--steps);
}
return 0;
}
int bresenham(Point p1,Point p2) /*0<=dy<=dx*/
{
POINT star=*p1;
int i,dx,dy;
float e;
dx=p2->x - p1->x;
dy=p2->y - p1->y;
e=2*dy-dx;
for(i=0;i<abs(dx);i++)
{
star.fdisplay(star.x,star.y,star.color);
star.x++;
if(e>0)
{
star.y++;
e+=2*(dy-dx);
}
else
{
e+=2*dy;
}
}
return 0;
}
int transCrclCooder(Circle crcl,Point pt,int *xx,int *yy,int x,int y)
{
int i;
xx[0]=x,yy[0]=y;
xx[1]=y,yy[1]=x;
xx[2]=y,yy[2]=-x;
xx[3]=x,yy[3]=-y;
xx[4]=-x,yy[4]=-y;
xx[5]=-y,yy[5]=-x;
xx[6]=-y,yy[6]=x;
xx[7]=-x,yy[7]=y;
for(i=0;i<8;i++)
{
Point_init(& pt[i]);
pt[i].fconstruct(&pt[i],(crcl->pt.x+xx[i]),(crcl->pt.y+yy[i]),14);
pt[i].fdisplay(& pt[i]);
/*putpixel(crcl->pt.x+xx[i],crcl->pt.y+yy[i],14);*/
}
}
int midptcircle(Circle crcl)
{
int i,x=0,y=crcl->r,d=1-crcl->r;
int xx[8],yy[8];
POINT pt[8];
transCrclCooder(crcl,pt,xx,yy,x,y);
while(x<y)
{
if(d<0)
{
d+=2*x+3;
x++;
}
else
{
d+=2*(x-y)+5;
x++;y--;
}
transCrclCooder(crcl,pt,xx,yy,x,y);
}
}