发信人: ysnf() 
整理人: jinhu(1999-07-13 10:34:31), 站内信件
 | 
 
 
  我编了一个图形学中多边行裁剪的程序,但还有一些问题。
 如空间不能释放(多裁几次就出问题)等等。头都调大了,
 还是不能完全搞定。请大家帮我看一看。如能把你的意见
 告诉我,万分感谢 !! Email [email protected] OR [email protected]
 
  程序中用‘上’‘下’‘左’ ‘右’控制裁剪方向,‘q’键
 退出。
 
  源代码:
 
 #include "stdio.h"
 #include "dos.h"
 #include "bios.h"
 #include "stdio.h"
 #include "fstream.h"
 #include "process.h"
 #include "stdlib.h"
 #include "conio.h"
 #include "graphics.h"
 #include "math.h"
 #define LEFT 1
 #define RIGHT 2
 #define BOTTOM 4
 #define TOP 8
 #define SIZE 2
 #define IN 1
 #define OUT 2
 #define NONE 3
 
 struct point {
    int x;
    int y;
    int number;
    int flag;
    struct point *next;
 }*mainp,*cutp,*main_i,*cut_i,*save,*pq,*pq_p,*pq_q,*p,*q,*pp,
 *yt,*yb,*xl,*xr,*a,*b,*c,*d,temp;
 
 struct j_d {
    int x;
    int y;
    int flag;
 }jiao_d[3],cut[4];
 
 int pixel_n;//jiao dian's number.
 int XL=200,XR=400,YB=200,YT=80;
 //int XL=120,XR=410,YB=280,YT=150;
 int  fxcode(int x,int y);
 void getpoint();
 void paintpoly(struct point *pain,int color);
 void freelists(struct point *ppp);
 void add_q(struct point * add_pq);
 void locate(struct point * lp1);
 void init_dl();
 void init_cut();
 void insert_dl();
 int jiao_df(int x1,int y1,int x2,int y2);
 void in_out(int x1,int y1,int x2,int y2);
 void print(struct point *printp);
 void build_cut_i(int i);
 
 int main()
 {
 
    int gd=DETECT,gm;
    int key='d';
    int main_flag=1;
 
    registerbgidriver(EGAVGA_driver);// 注册图形库,如你的编译器没经过处                                     // 理请把该行注释掉.
 
    initgraph(&gd,&gm,"f:\\borlandc\\bgi");
    setcolor(YELLOW);
 //   rectangle(170,150,460,280);
 
 while(key!='q') {
    mainp=(struct point *)malloc(sizeof(struct point));
    cutp=(struct point *)malloc(sizeof(struct point));
    main_i=(struct point *)malloc(sizeof(struct point));
    cut_i=(struct point *)malloc(sizeof(struct point));
    pq=(struct point *)malloc(sizeof(struct point));
    pq_p=pq;
 
    init_dl();
 //   init_dl();
    switch (key) {
       case 72:YT=YT-7;YB=YB-7;cleardevice();break;
       case 80:YT=YT+7;YB=YB+7;cleardevice();break;
       case 75:XL=XL-7;XR=XR-7;cleardevice();break;
       case 77:XR=XR+7;XL=XL+7;cleardevice();break;
    }
    setcolor(YELLOW);
    rectangle(XL,YT,XR,YB);
 
    cut[0].x=XL;cut[0].y=YT;cut[1].x=XR;cut[1].y=YT;
    cut[2].x=XR;cut[2].y=YB;cut[3].x=XL;cut[3].y=YB;
 
    init_cut();
    a=cutp->next;b=a->next;
    c=b->next;d=c->next;
 
    insert_dl();
    paintpoly(main_i,13);
 //   insert_cut();
  /*
       p=main_i;
    while(p->next!=NULL) {
       p=p->next;
       printf("p->x:%d p->y:%d p->flag:%d\n",p->x,p->y,p->flag);
    }
    printf("      -----------\n");
   */
 //   free(mainp);
 //   free(cutp);
 again1:   p=main_i->next;
    while(p!=NULL ) {
        if(p->flag!=IN) p=p->next;
        else {
 	    pp=p;
 	    save=p;    //save p
 	    add_q(pp);//add to Q
 //	    print(pp);
 again:	    p->flag=NONE;// del p's "IN" flag
 	    if(p->next==NULL) p=main_i->next;
 	    else  p=p->next;
 	    add_q(p); //add to Q
 
 //	    setcolor(10);
 //	    circle(p->x,p->y,5);
 //	    print(p);
 
 	    while(p->flag!=OUT ) {
 	       if(p->next==NULL) p=main_i->next;
 	       else  p=p->next;
 	       add_q(p);
 
 //	       print(p);
 
 	    }
 	    locate(cut_i);
 	    if(p->next!=NULL) p=p->next;
 	    else p=cut_i->next;
 	    add_q(p);
 
 //	    print(p);
 //	    setcolor(10);
 //	    circle(p->x,p->y,5);
 
 	    while(p->flag!=IN ) {
 	       if(p->next==NULL) p=cut_i->next;
 	       else p=p->next;
 	       add_q(p);
 
 //	       print(p);
 //	       setcolor(10);
 //	       circle(p->x,p->y,5);
 
 	    }
 	    if(p->x!=save->x || p->y!=save->y) {
 	       locate(main_i);
 	       goto again;
 	    }
 	    else {
 /*
 		 p=pq;
 		 while(p->next!=NULL) {
 		   p=p->next;
 		   printf("p->x:%d p->y:%d p->flag:%d\n",p->x,p->y,p->flag);
 		 }
 */
 		 paintpoly(pq,WHITE);
 		 goto again1;
 		 }
        }
     }// to while(p->next!=NULL)
 //    mainp=NULL;main_i=NULL;cutp=NULL;cut_i=NULL;
 //    xl=yt=xr=yb=NULL;
   free(mainp);
   free(main_i);
   free(pq);
   free(cutp);
   free(cut_i);
   free(xl);
   free(yt);
   free(xr);
   free(yb);
   free(a);
   free(b);
   key=getch();
 }//to while(key)
   return 0;
 }
 
 
 void add_q(struct point *add_qp)
 {
    pq_q=(struct point *)malloc(sizeof(struct point));
    if(pq_q==NULL) exit(1);
    pq_p->next=pq_q;
    pq_p=pq_q;
    pq_p->x=add_qp->x;
    pq_p->y=add_qp->y;
    pq_p->next=NULL;
 }
 
 void add_main_i(int i) //add a point begin with p;
 {
    struct point *add_m_i;
    add_m_i=(struct point *)malloc(sizeof(struct point));
    add_m_i->x=jiao_d[i].x;
    add_m_i->y=jiao_d[i].y;
    add_m_i->flag=jiao_d[i].flag;
    add_m_i->next=p->next;
    p->next=add_m_i;
 }
 
 void locate(struct point *lp1)//have some bug without sentence ONE.
 {
    while(lp1->next!=NULL) {
       if(lp1->x==p->x && lp1->y==p->y)  {
 	 p=lp1;
 	 break;
       }
       lp1=lp1->next;
    }
    if(lp1->next==NULL) p=lp1; // sentence ONE.
 }
 void build_cut_i(int i)
 {
    int j;
 
    struct point *bp,*bq,*bf;
    for(j=1;j<=i;j++) {
      if(jiao_d[j].y==YT) {
 	 bp=a; bf=a;
 	 while(bf!=b) {
 	   bp=bp->next;
 	   if(bp->x>jiao_d[j].x )  {
 	      bq=(struct point *)malloc(sizeof(struct point));//new a point
 	      bq->y=jiao_d[j].y;           //   |
 	      bq->x=jiao_d[j].x;           //   |
 	      bq->flag=jiao_d[j].flag;     //   --> input data to point
 	      bq->next=bp;
 	      bf->next=bq;
 	      bf=b;
 	   }
 	   if(bf!=b) bf=bf->next;
 	 }  // to while
      }// to if
      if(jiao_d[j].x==XR) {
 	 bp=b; bf=b;
 	 while(bf!=c) {
 	   bp=bp->next;
 	   if(bp->y>jiao_d[j].y )  {
 	      bq=(struct point *)malloc(sizeof(struct point));//new a point
 	      bq->y=jiao_d[j].y;           //   |
 	      bq->x=jiao_d[j].x;           //   |
 	      bq->flag=jiao_d[j].flag;     //   --> input data to point
 	      bq->next=bp;
 	      bf->next=bq;
 	      bf=c;
 	   }
 	   if(bf!=c) bf=bf->next;
 	 }  // to while
      }// to if
      if(jiao_d[j].y==YB) {
 	 bp=c; bf=c;
 	 while(bf!=d) {
 	   bp=bp->next;
 	   if(bp->x<jiao_d[j].x )  {
 	      bq=(struct point *)malloc(sizeof(struct point));//new a point
 	      bq->y=jiao_d[j].y;           //   |
 	      bq->x=jiao_d[j].x;           //   |
 	      bq->flag=jiao_d[j].flag;     //   --> input data to point
 	      bq->next=bp;
 	      bf->next=bq;
 	      bf=d;
 	   }
 	   if(bf!=d) bf=bf->next;
 	 }  // to while
      }// to if
      if(jiao_d[j].x==XL) {
 	 bp=d; bf=d;
 	 while(bf!=NULL) {
 	   bp=bp->next;
 	   if(bp->next==NULL) {
 	      bq=(struct point *)malloc(sizeof(struct point));//new a point
 	      bq->y=jiao_d[j].y;           //   |
 	      bq->x=jiao_d[j].x;           //   |
 	      bq->flag=jiao_d[j].flag;     //   --> input data to point
 	      bq->next=bp;
 	      bf->next=bq;
 	      bf=NULL;
 
 	   }
 	   else if(bp->y<jiao_d[j].y )  {
 		  bq=(struct point *)malloc(sizeof(struct point));//new a point
 		  bq->y=jiao_d[j].y;           //   |
 		  bq->x=jiao_d[j].x;           //   |
 		  bq->flag=jiao_d[j].flag;     //   --> input data to point
 		  bq->next=bp;
 		  bf->next=bq;
 		  bf=NULL;
 		}
 	   if(bf!=NULL) bf=bf->next;
 	 }  // to while
      }// to if
    }// to for
 }
 
 void insert_dl()
 {
    p=mainp->next;
    while (p->next!=NULL) {
       pixel_n=jiao_df(p->x,p->y,p->next->x,p->next->y);
       if(pixel_n) {  //if have jiao dian
 	 in_out(p->x,p->y,p->next->x,p->next->y);//
 	 if(pixel_n==1) {
 	    save=p;
 	    locate(main_i);
 	    add_main_i(1);
 	    p=save;
    //	    creat_jd(1);
 	    build_cut_i(1);
 	 }
 	 else {
 	    if(jiao_d[1].flag!=IN) {
 	       temp.x=jiao_d[1].x;
 	       temp.y=jiao_d[1].y;
 	       temp.flag=jiao_d[1].flag;
 	       jiao_d[1].x=jiao_d[2].x;
 	       jiao_d[1].y=jiao_d[2].y;
 	       jiao_d[1].flag=jiao_d[2].flag;
 	       jiao_d[2].x=temp.x;
 	       jiao_d[2].y=temp.y;
 	       jiao_d[2].flag=temp.flag;
 	    }
 	    save=p;
 	    locate(main_i);
 	    add_main_i(1);
 	    p=p->next;
 	    add_main_i(2);
 	    p=save;
 //	    creat_jd(1);
 //	    creat_jd(2);
 	    build_cut_i(2);
 	 }
       }//to if(pixel_n)
       p=p->next;
       // p->next=NULL but must do onece
       if(p->next==NULL && p->x!=mainp->next->x && p->y!=mainp->next->y ) {
 	 q=(struct point *)malloc(sizeof(struct point));
 	 q->x=p->x;
 	 q->y=p->y;
 	 q->flag=p->flag;
 	 p=q;
 	 q=(struct point *)malloc(sizeof(struct point));
 	 q->x=mainp->next->x;
 	 q->y=mainp->next->y;
 	 q->flag=mainp->next->flag;
 	 p->next=q;
 	 q->next=NULL;
       }
    } //to while
 }
 
 void init_dl()
 {
    int x,y,flag=NONE;
    struct point *p_inp,*p_inq;
    getpoint();
    //copy mainp to main_i
    p=mainp;
    pp=main_i;
    while(p->next!=NULL) {
        p=p->next;
        q=(struct point *)malloc(sizeof(struct point));
        pp->next=q;
        pp=q;
        pp->x=p->x;
        pp->y=p->y;
        pp->flag=p->flag;
        pp->next=NULL;
 
    }
 }
 
 void init_cut()
 {
    struct point *i_c_p,*i_c_pp,*i_c_q;
    int i;
    i_c_p=cutp;
    i_c_pp=cut_i;
    for(i=0;i<4;i++) {
       i_c_q=(struct point*)malloc(sizeof(struct point));
       i_c_p->next=i_c_q;
       i_c_pp->next=i_c_q;
       i_c_p=i_c_q;
       i_c_pp=i_c_q;
       i_c_p->x=cut[i].x;
       i_c_pp->x=cut[i].x;
       i_c_p->y=cut[i].y;
       i_c_pp->y=cut[i].y;
       i_c_p->flag=NONE;
       i_c_pp->flag=NONE;
       i_c_p->next=NULL;
       i_c_pp->next=NULL;
    }
 }
 
 
 void getpoint()
 {
   int x,y,flag=NONE;
   struct point *p_inp,*p_inq;
   fstream read;
 
   read.open("ysclip.dat",ios::in);
   if(!read){
     cout << "Cannot find the file in the path!" << endl;
     exit(0);
   }
    p_inp=mainp;
    read >> x >> y >> flag;
  while(flag!=0) {
    p_inq=(struct point *)malloc(sizeof(struct point));
    p_inp->next=p_inq;
    p_inp=p_inq;
    p_inp->x=x;
    p_inp->y=y;
    p_inp->flag=flag;
    p_inp->next=NULL;
    read >> x >> y >> flag;
  }
 
   read.close();
 }
 
 
 void paintpoly(struct point *pain,int color)
 {
    struct point *paintp,*paintq;
    setcolor(color);
    paintq=pain->next;
    paintp=pain->next;
    while(paintp->next!=NULL) {
     /*  if( (pq_p->x==170 && pq_p->next->x==170) ||
 	  (pq_p->x==460 && pq_p->next->x==460) ||
 	  (pq_p->y==150 && pq_p->next->y==150) ||
 	  (pq_p->y==280 && pq_p->next->y==280)  ) pq_p=pq_p->next;
       else {*/
 	   circle(paintp->x,paintp->y,3);
 	   circle(paintp->next->x,paintp->next->y,3);
 	   line(paintp->x,paintp->y,paintp->next->x,paintp->next->y);
 	   paintp=paintp->next;
    //	   }
    }
    line(paintp->x,paintp->y,paintq->x,paintq->y);
 }
 
 
 int  fxcode(int x,int y)
 {
    int c=0;
    if(x<XL) c=c|LEFT;
    else if(x>XR) c=c|RIGHT;
    if(y>YB) c=c|BOTTOM;
    else if(y<YT) c=c|TOP;
    return c;
 }
 
 
 int jiao_df(int x1,int y1,int x2,int y2)
 {
    int  code1,code2,code;
    int x,y;
    int i=0;
    code2=fxcode(x2,y2);
    code1=fxcode(x1,y1);
    while( code1!=0 || code2!=0 ){
      if((code1&code2)!=0) return i;
      code=code1;
      if(code1==0) code=code2;
      if((LEFT&code)!=0){
        x=XL;
        y=y1+int((y2-y1)*(XL-x1)*1.0/(x2-x1));
        if(y<=YB && y>=YT) {
 	  i++;
 	  jiao_d[i].x=x;
 	  jiao_d[i].y=y;
        }
      }
      else
        if((RIGHT&code)!=0){
 	  x=XR;
 	  y=y1+int((y2-y1)*(XR-x1)*1.0/(x2-x1));
 	  if(y<=YB && y>=YT) {
 	     i++;
 	     jiao_d[i].x=x;
 	     jiao_d[i].y=y;
 	  }
        }
        else
 	 if((BOTTOM&code)!=0){
 	   y=YB;
 	   x=x1+int((x2-x1)*(YB-y1)*1.0/(y2-y1));
 	   if(x<=XR && x>=XL) {
 	      i++;
 	      jiao_d[i].x=x;
 	      jiao_d[i].y=y;
 	   }
 	 }
 	 else
 	   if((TOP&code)!=0){
 	      y=YT;
 	      x=x1+int((x2-x1)*(YT-y1)*1.0/(y2-y1));
 	      if(x<=XR && x>=XL) {
 		 i++;
 		 jiao_d[i].x=x;
 		 jiao_d[i].y=y;
 	      }
 	   }
       if(code==code1){
        x1=x;
        y1=y;
        code1=fxcode(x,y);
       }else{
        x2=x;
        y2=y;
        code2=fxcode(x,y);
       }
     } //to while
 
     return i;
 }
 
 void in_out(int x1,int y1,int x2,int y2)
 {
    int f1,f2;
    if(pixel_n==1) {
       if(fxcode(x1,y1)) jiao_d[1].flag=IN;
       else jiao_d[1].flag=OUT;
    }
    else {
     if(jiao_d[1].x==jiao_d[2].x && jiao_d[1].y==jiao_d[2].y) {
       pixel_n=1;
       jiao_d[1].flag=OUT;
     }
     else{
       f1=fabs(jiao_d[1].x-x1)+fabs(jiao_d[1].y-y1);
       f2=fabs(jiao_d[2].x-x1)+fabs(jiao_d[2].y-y1);
       if(f1<f2) {
 	 jiao_d[1].flag=IN;
 	 jiao_d[2].flag=OUT;
       }
       else {
 	 jiao_d[2].flag=IN;
 	 jiao_d[1].flag=OUT;
       }
     }
    }
 }
 
 void freelists(struct point *ppp)
 {
    struct point *pp,*qq;
    for(pp=ppp;pp!=NULL;){
      qq=pp;
      pp=pp->next;
      delete(qq);
    }
 }
 void print(struct point *printp)
 {
    char sxy[10];
    int x=printp->x,y=printp->y;
    setcolor(15);
    moveto(x,y);
    sprintf(sxy,"(%d,%d)",x,y);
    outtextxy(x+5,y-5,sxy);
 }
  -- ※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.103.31.67]
  | 
 
 
 |