BÀI TẬP LỚN ĐỒ HỌA MÁY TÍNH
Bài 3. Trình bày các kỹ thuật xén tỉa. Viết chương trình mô phỏng các kỹ thuật đó.
Nhóm 3 Gồm: +: Nguyễn Bá Hoàng (1300863)
+: Nguyễn Quốc Hưng (1300775)
+:Nguyễn Văn Dũng (1300773)
+:Đặng Văn Thụ (1300481) +:Nguyễn Tiến Đức (1300536)
Chủ đề
+: Xén hình
+: Xén đoạn thẳng bằng thuật toán CohenSutherland
+: Xén đa giác bằng thuật toán SutherlandHodegman
+: Xén hình
+: Xén đoạn thẳng bằng thuật toán CohenSutherland
+: Xén đa giác bằng thuật toán SutherlandHodegman
I: Xén hình là gì (Clipping).
- Là thao tác loại bỏ phần hình ảnh của thế giới thực nằm bên ngoài một cửa sổ quan sát.II: Các loại xén hình
- Xén điểm
+: Input Điểm P+: Output
P thuộc cửa sổ W(Wl ,Wr ,Wb ,Wt )
- Xén đoạn thẳng bằng thuật toán Cohen-Sutherland
+: Input+: Đoạn thẳng P1 P2
+: Output
P1 P2 giao W(Wl ,Wr ,Wb ,Wt )
- Mặt phẳng được chia làm 5 vùng
- Input
- Đoạn thẳng P1 P2
- Output
P1 P2 giao W(Wl ,Wr ,Wb ,Wt )
- Lặp
- Bước 1 : Tính mã vùng
C1 là mã vùng của P1
C2 là mã vùng của P2
- Bước 2 : Xét mã vùng
Trường hợp 1 : Đoạn thẳng nằm vùng bên trong
Trường hợp 2 : Đoạn thẳng thuộc các vùng bên ngoài
Trường hợp 3 :
- Tóm Tắt Xén đoạn thẳng bằng thuật toán Cohen-Sutherland
- Cài Đặt Bài Toán Xén Đường Thẳng Với Hình Chữ Nhật Bằng CohenSutherland:
#include<graphics.h>#include<math.h>
#include<dos.h>
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
void cohen(int x1,int y1,int x2,int y2,int xa, int ya, int xb,int yb)
{
int a[4],b[4],i,kthuc=0;
while(kthuc==0)
{
a[1]=a[2]=a[3]=a[4]=0;
if(xa<x1) a[1]=1;
if(xa>x2) a[2]=1;
if(ya<y1) a[3]=1;
if(ya>y2) a[4]=1;b[1]=b[2]=b[3]=b[4]=0;
if(xb<x1) b[1]=1;
if(xb>x2) b[2]=1;
if(yb<y1) b[3]=1;
if(yb>y2) b[4]=1;
int ktra=0;
for(i=1;i<=4;i++)
{ if( (a[i]==1) || (b[i]==1) ) ktra=1; };
if(ktra==0) { setcolor(10);line(xa,ya,xb,yb);kthuc=1;}
else
{
int ktra1=1;
for(i=1;i<=4;i++)
{if( (a[i]==1) && (b[i]==1) ) ktra1=0;}
if(ktra1==0) {kthuc=1;}
else
{ if(a[1]==0 && a[2]==0 && a[3]==0 && a[4]==0)
{
for(i=1;i<=4;i++)
{
int tg1=a[i];a[i]=b[i];b[i]=tg1;
}
int tg2=xa;xa=xb;xb=tg2;
int tg3=ya;ya=yb;yb=tg3;
}
if(a[1]==1)
{
ya=(yb-ya)*(x1-xa)/(xb-xa)+ya;
xa=x1; //cout<<xa<<" "<<ya<<endl;
}
if(a[2]==1)
{
ya=(yb-ya)*(x2-xa)/(xb-xa)+ya;
xa=x2;
}
if(a[3]==1)
{
xa=(xb-xa)*(y1-ya)/(yb-ya)+xa;
ya=y1;
}
if(a[4]==1)
{
xa=(xb-xa)*(y2-ya)/(yb-ya)+xa;
ya=y2;
}
}
}
}
}
int main()
{
int md=0, dr=0;
initgraph(&md,&dr,"c:\\tc\\bgi");
setcolor(11);
rectangle(200,200,400,400);
cohen(200,200,400,400,150,100,300,300);
getch();
}
- Kết Quả Chạy Bài Toán:
- Xén đa giác bằng thuật toán Sutherland-Hodegman
+: InputĐa giác P
+: Output
P giao W
+: Mỗi cạnh chia mặt phẳng ra làm 2 phần gồm: nửa mặt phẳng trong và nửa mặt phẳng ngoài.
+: Cửa sổ quan sát là giao của các nửa mặt phẳng trong của các cạnh
+: Dùng từng cạnh của cửa sổ lần lượt xén đa giác.
Bước 1 : Xén trái
Bước 2 : Xén phải
Bước 3 : Xén dưới
Bước 4 : Xén trên
+: Input
Đa giác IN = {p0 , p1 , ... , pn-1 }
+ :Output
Đa giác OUT = IN giao W(Wl ,Wr ,Wb ,Wt )
Bước 1
OUT = {}Bước 2
Lặpp : p0 ... pn-1
s là đỉnh kề trước của p
Trường hợp 1 : p bên trong, s bên trong
Trường hợp 2 : p bên ngoài, s bên trong
Trường hợp 3 : p bên ngoài, s bên ngoài
Trường hợp 4 : p bên trong, s bên ngoài
- Ví Dụ Xén đa giác ABCDEF vào vùng cửa sổ
- Cài Đặt Xén đa giác bằng Sutherland-Hodegman
#include <stdio.h>#include <graphics.h>
#include <conio.h>
#include <math.h>
#include <process.h>
#define TRUE 1
#define FALSE 0
typedef unsigned int outcode;
outcode CompOutCode(float x,float y);
enum { TOP = 0x1,
BOTTOM = 0x2,
RIGHT = 0x4,
LEFT = 0x8
};
float xmin,xmax,ymin,ymax;
void clip(float x0,float y0,float x1,float y1)
{
outcode outcode0,outcode1,outcodeOut;
int accept = FALSE,done = FALSE;
outcode0 = CompOutCode(x0,y0);
outcode1 = CompOutCode(x1,y1);
do
{
if(!(outcode0|outcode1))
{
accept = TRUE;
done = TRUE;
}
else
if(outcode0 & outcode1)
done = TRUE;
else
{
float x,y;
outcodeOut = outcode0?outcode0:outcode1;
if(outcodeOut & TOP)
{
x = x0+(x1-x0)*(ymax-y0)/(y1-y0);
y = ymax;
}
else
if(outcodeOut & BOTTOM)
{
x = x0+(x1-x0)*(ymin-y0)/(y1-y0);
y = ymin;
}
else
if(outcodeOut & RIGHT)
{
y = y0+(y1-y0)*(xmax-x0)/(x1-x0);
x = xmax;
}
else
{
y = y0+(y1-y0)*(xmin-x0)/(x1-x0);
x = xmin;
}
if(outcodeOut==outcode0)
{
x0 = x;
y0 = y;
outcode0 = CompOutCode(x0,y0);
}
else
{
x1 = x;
y1 = y;
outcode1 = CompOutCode(x1,y1);
}
}
}while(done==FALSE);
if(accept)
line(x0,y0,x1,y1);
outtextxy(150,20,"Da Giac Sau Khi Xen");
rectangle(xmin,ymin,xmax,ymax);
}
outcode CompOutCode(float x,float y)
{
outcode code = 0;
if(y>ymax)
code|=TOP;
else
if(y<ymin)
code|=BOTTOM;
if(x>xmax)
code|=RIGHT;
else
if(x<xmin)
code|=LEFT;
return code;
}
void main( )
{
float x1,y1,x2,y2;
/* request auto detection */
int gdriver = DETECT, gmode, n,poly[14],i;
clrscr( );
printf("Nhap so canh cua da giac");
scanf("%d",&n);
printf("\nNhap Toa Do Da Giac\n");
for(i=0;i<2*n;i++)
{
scanf("%d",&poly[i]);
}
poly[2*n]=poly[0];
poly[2*n+1]=poly[1];
printf("Nhap Toa Do Vuong Goc Cua Da Giac\n");
scanf("%f%f%f%f",&xmin,&ymin,&xmax,&ymax);
/* initialize graphics and local variables */
initgraph(&gdriver, &gmode, "c:\\tc\\bgi");
outtextxy(150,20,"Da Giac Truoc Khi Xen");
drawpoly(n+1,poly);
rectangle(xmin,ymin,xmax,ymax);
getch( );
cleardevice( );
for(i=0;i<n;i++)
clip(poly[2*i],poly[(2*i)+1],poly[(2*i)+2],poly[(2*i)+3]);
getch( );
restorecrtmode( );
}