精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>编程开发>>● 编程世界>>其他>>图形学中多边行裁剪的问题(附源代码)

主题:图形学中多边行裁剪的问题(附源代码)
发信人: 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]

[关闭][返回]