直线裁剪
program clipline;
uses crt,graph;
var
markseg:word;
gd,gm:integer;
startx,starty,endx,endy:integer;
x1,y1,x2,y2,x,y:integer;
ch:char;
readflag,enterflag:boolean;
procedure lineclip(x1,y1,x2,y2,left,top,right,bottom:integer);
type codetype=array[1..4] of byte;
var
x11,y11:integer;
a,b:codetype;
procedure getcode(x,y:integer;var c:codetype);
begin
c[1]:=0; c[2]:=0; c[3]:=0; c[4]:=0;
if x<left then c[1]:=1;
if x>right then c[2]:=1;
if y>bottom then c[3]:=1;
if y<top then c[4]:=1;
{writeln(c[1],c[2],c[3],c[4])}
end;
procedure swap(var x,y:integer);
var
temp:integer;
begin
temp :=x;
x :=y;
y :=temp;
end;
begin
getcode(x2,y2,b);
repeat
getcode(x1,y1,a);
if (a[1]+a[2]+a[3]+a[4]=0) and (b[1]+b[2]+b[3]+b[4]=0) then
exit
else if (a[1] and b[1]+a[2] and b[2]+a[3] and b[3]+a[4] and b[4]<>0) then
begin
setcolor(0);
setwritemode(copyput);
line(x1,y1,x2,y2);
exit;
end
else
begin
if a[1]+a[2]+a[3]+a[4]=0 then
begin
getcode(x1,y1,b);
getcode(x2,y2,a);
swap(x1,x2);
swap(y1,y2);
end;
if (a[1]=1) then
begin
x11 :=left;
y11 :=round((y2-y1)*(left-x1)/(x2-x1)+y1);
end
else if (a[2]=1) then
begin
x11 :=right;
y11 :=round((y2-y1)*(right-x1)/(x2-x1)+y1);
end
else if (a[3]=1) then
begin
x11 :=round((x2-x1)*(bottom-y1)/(y2-y1)+x1);
y11 :=bottom;
end
else
begin
x11 :=round((x2-x1)*(top-y1)/(y2-y1)+x1);
y11 :=top;
end;
end;
setcolor(0);
setwritemode(copyput);
line(x1,y1,x11,y11);
x1 :=x11;
y1 :=y11;
getcode(x1,y1,a);
until false;
setcolor(white);
end;
begin
gd :=detect;
directvideo :=false;
initgraph(gd,gm,'D:\TP\BGI');
readflag :=false;
x1 :=50; y1:=100;
x2 :=100; y2 :=50;
startx :=70; starty :=30; endx :=90; endy :=100;
line(x1,y1,x2,y2);
rectangle(startx,starty,endx,endy);
{ lineclip(x1,y1,x2,y2,startx,starty,endx,endy);}
readln;
closegraph;
end.
圆的裁剪
#include <graphics.h>
#include <math.h>
int xc=240,yc=195,n=60,rx=120,ry=80,i,j,xL=100,xr=299,yt=100,yb=241,x1,y1;
float x,y,p=30.0,th,cp,sp;
main()
{
int y=0;
int driver=DETECT,mode=0;
initgraph(&driver,&mode,"");
setbkcolor(1);
setcolor(14);
p=p/57.3; cp=cos(p); sp=sin(p);
rectangle(100,100,299,241);
for (i=0;i<=n;i++)
{
th=6.2832/n;
x=rx*cos(i*th);
y=ry*sin(i*th);
x1=xc+x*cp-y*sp;
y1=yc-x*sp-y*cp;
if (x1<xL || x1>xr || y1<yt || y1>yb)
continue;
j++;
if (j==1) moveto(x1,y1);
lineto(x1,y1);
}
getch();
closegraph();
}
多边形裁剪:
/* Sutherland-Hodgman 算法 */
#define LEN sizeof(struct node)
#include <math.h>
#include<stdio.h>
#include<graphics.h>
struct node
{
int dx,dy;
struct node *next;
};
struct node *h,*q,*r;
struct node *creat()
{
int p[8][2]={100,120,160,50,180,100,200,80,240,160,210,220,170,160,140,190};
int i;
setcolor(12);
for (i=0;i<7;i++) line(p[i][0],p[i][1],p[i+1][0],p[i+1][1]);
line(p[0][0],p[0][1],p[7][0],p[7][1]);
rectangle(120,200,230,70);
h=NULL;
for (i=0;i<8;i++)
{
q=(struct node *)malloc(LEN);
q->dx=p[i][0];
q->dy=p[i][1];
if (h==NULL)
h=q;
else r->next=q;
r=q;
}
r->next=NULL;
return(h);
}
int x;
struct node *builx(h,x)
struct node *h;
{
int s[2],j[2];
struct node *hh,*p,*q;
int max,min;
p=h; hh=NULL;
s[0]=p->dx; s[1]=p->dy;
p=p->next;
while (p!=NULL)
{
j[0]=x;
j[1]=s[1]+(p->dy-s[1])*(x-s[0])/(p->dx-s[0]);
max=s[0]; min=p->dx;
if (s[0]<p->dx)
{
max=p->dx;
min=s[0];
}
if ((j[0]>=min)&&(j[0]<=max))
{
q=(struct node *)malloc(LEN);
q->dx=j[0]; q->dy=j[1];
if (hh==NULL)
hh=q;
else
r->next=q;
r=q;
}
if (p->dx>=x)
{ q=(struct node *)malloc(LEN);
q->dx=p->dx; q->dy=p->dy;
if (hh==NULL) hh=q;
else r->next=q;
r=q;
}
s[0]=p->dx; s[1]=p->dy;
p=p->next;
}
p=h;
j[0]=x; j[1]=s[1]+(p->dy-s[1])*(x-s[0])/(p->dx-s[0]);
max=s[0]; min=p->dx;
if (s[0]<p->dx) { max=p->dx; min=s[0]; }
if ((j[0]>=min)&&(j[0]<=max))
{ q=(struct node *)malloc(LEN);
q->dx=j[0]; q->dy=j[1];
if (hh==NULL) hh=q;
else r->next=q;
r=q;
}
if (p->dx>=x)
{ q=(struct node *)malloc(LEN);
q->dx=p->dx; q->dy=p->dy;
if (hh==NULL) hh=q;
else r->next=q;
r=q;
}
r->next=NULL;
return(hh);
}
struct node *builxx(h,x)
struct node *h;
int x;
{int s[2],j[2];
struct node *hh,*p,*q;
int max,min;
p=h;
hh=NULL;
s[0]=p->dx;
s[1]=p->dy;
p=p->next;
while (p!=NULL)
{
j[0]=x;
j[1]=s[1]+(p->dy-s[1])*(x-s[0])/(p->dx-s[0]+0.1);
max=s[0];
min=p->dx;
if (s[0]<p->dx) { max=p->dx;
min=s[0];
}
if ((j[0]>=min)&&(j[0]<=max))
{ q=(struct node *)malloc(LEN);
q->dx=j[0];
q->dy=j[1];
if (hh==NULL)
hh=q;
else r->next=q;
r=q;
}
if (p->dx<=x)
{ q=(struct node *)malloc(LEN);
q->dx=p->dx;
q->dy=p->dy;
if (hh==NULL)
hh=q;
else r->next=q;
r=q;
}
s[0]=p->dx;
s[1]=p->dy;
p=p->next;
}
p=h;
j[0]=x;
j[1]=s[1]+(p->dy-s[1])*(x-s[0])/(p->dx-s[0]+0.1);
max=s[0];
min=p->dx;
if (s[0]<p->dx) { max=p->dx;
min=s[0];
}
if ((j[0]>=min)&&(j[0]<=max))
{ q=(struct node *)malloc(LEN);
q->dx=j[0];
q->dy=j[1];
if (hh==NULL)
hh=q;
else r->next=q;
r=q;
}
if (p->dx<=x)
{ q=(struct node *)malloc(LEN);
q->dx=p->dx;
q->dy=p->dy;
if (hh==NULL)
hh=q;
else r->next=q;
r=q;
}
r->next=NULL;
return(hh);
}
struct node *buily(h,y)
struct node *h;
int y;
{int s[2],j[2];
struct node *hh,*p,*q;
int max,min;
p=h;
hh=NULL;
s[0]=p->dx;
s[1]=p->dy;
p=p->next;
while (p!=NULL)
{
j[1]=y;
j[0]=s[0]+(p->dx-s[0])*(y-s[1])/(p->dy-s[1]+0.1);
max=s[1];
min=p->dy;
if (s[1]<p->dy) { max=p->dy;
min=s[1];
}
if ((j[1]>=min)&&(j[1]<=max))
{ q=(struct node *)malloc(LEN);
q->dx=j[0];
q->dy=j[1];
if (hh==NULL)
hh=q;
else r->next=q;
r=q;
}
if (p->dy>=y)
{ q=(struct node *)malloc(LEN);
q->dx=p->dx;
q->dy=p->dy;
if (hh==NULL)
hh=q;
else r->next=q;
r=q;
}
s[0]=p->dx;
s[1]=p->dy;
p=p->next;
}
p=h;
j[1]=y;
j[0]=s[0]+(p->dx-s[0])*(y-s[1])/(p->dy-s[1]+0.1);
max=s[1];
min=p->dy;
if (s[1]<p->dy) { max=p->dy;
min=s[1];
}
if ((j[1]>=min)&&(j[1]<=max))
{ q=(struct node *)malloc(LEN);
q->dx=j[0];
q->dy=j[1];
if (hh==NULL)
hh=q;
else r->next=q;
r=q;
}
if (p->dy>=y)
{ q=(struct node *)malloc(LEN);
q->dx=p->dx;
q->dy=p->dy;
if (hh==NULL)
hh=q;
else r->next=q;
r=q;
}
r->next=NULL;
return(hh);
}
struct node *builyy(h,y)
struct node *h;
int y;
{int s[2],j[2];
struct node *hh,*p,*q;
int max,min;
p=h;
hh=NULL;
s[0]=p->dx;
s[1]=p->dy;
p=p->next;
while (p!=NULL)
{
j[1]=y;
j[0]=s[0]+(p->dx-s[0])*(y-s[1])/(p->dy-s[1]+0.1);
max=s[1];
min=p->dy;
if (s[1]<p->dy) { max=p->dy;
min=s[1];
}
if ((j[1]>=min)&&(j[1]<=max))
{ q=(struct node *)malloc(LEN);
q->dx=j[0];
q->dy=j[1];
if (hh==NULL)
hh=q;
else r->next=q;
r=q;
}
if (p->dy<=y)
{ q=(struct node *)malloc(LEN);
q->dx=p->dx;
q->dy=p->dy;
if (hh==NULL)
hh=q;
else r->next=q;
r=q;
}
s[0]=p->dx;
s[1]=p->dy;
p=p->next;
}
p=h;
j[1]=y;
j[0]=s[0]+(p->dx-s[0])*(y-s[1])/(p->dy-s[1]+0.1);
max=s[1];
min=p->dy;
if (s[1]<p->dy) { max=p->dy;
min=s[1];
}
if ((j[1]>=min)&&(j[1]<=max))
{ q=(struct node *)malloc(LEN);
q->dx=j[0];
q->dy=j[1];
if (hh==NULL)
hh=q;
else r->next=q;
r=q;
}
if (p->dy<=y)
{ q=(struct node *)malloc(LEN);
q->dx=p->dx;
q->dy=p->dy;
if (hh==NULL)
hh=q;
else r->next=q;
r=q;
}
r->next=NULL;
return(hh);
}
void Initialize(void)
{
int gdriver=DETECT, gmode;
initgraph(&gdriver, &gmode," ");
setbkcolor(WHITE);
}
main()
{ int max,min;
struct node *head,*r,*q;
int i;
int s[2];
Initialize();
head=creat();
q=head;
while (q->next!=NULL)
{ putpixel(q->dx,q->dy,14);
q=q->next;
}
putpixel(q->dx,q->dy,14);
q=builx(head,120);
head=q;
while (q->next!=NULL)
{ putpixel(q->dx,q->dy,15);
q=q->next;
}
putpixel(q->dx,q->dy,15);
q=buily(head,70);
head=q;
while (q->next!=NULL)
{ putpixel(q->dx,q->dy,2);
q=q->next;
}
putpixel(q->dx,q->dy,2);
q=builxx(head,230);
head=q;
while (q->next!=NULL)
{ putpixel(q->dx,q->dy,1);
q=q->next;
}
putpixel(q->dx,q->dy,1);
q=builyy(head,200);
head=q;
s[0]=q->dx;
s[1]=q->dy;
q=q->next;
setcolor(14);
while (q!=NULL)
{ line(s[0],s[1],q->dx,q->dy);
s[0]=q->dx;
s[1]=q->dy;
q=q->next;
}
q=head;
line(s[0],s[1],q->dx,q->dy);
getch();
}