发信人: 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]
|
|