1. Trang chủ
  2. » Công Nghệ Thông Tin

Đồ họa máy tính - Chương 4 Kỹ thuật xử lý hình khuất - Bài 12 ppt

9 590 2

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 9
Dung lượng 288,52 KB

Nội dung

Phần hiển thị của hình Phần này chúng ta giải quyết bài toán sau: Giả sử đối tượng quan sát nằm trong vùng nhìn thấy, khi đó nó có ảnh trên mặt phẳng chiếu Π.. Nếu bây giờ chúng ta thu

Trang 1

Chương 4

Kỹ thuật xử lý hình khuất

$12 Phần hiển thị của hình

Phần này chúng ta giải quyết bài toán sau:

Giả sử đối tượng quan sát nằm trong vùng nhìn thấy, khi đó nó có ảnh trên mặt phẳng chiếu Π Nếu bây giờ chúng ta thu nhỏ mặt phẳng chiếu, hãy xác định phần hình ảnh của đối tượng có trong mặt phẳng chiếu, chúng ta chú ý rằng vấn đề này rất phù hợp với yêu cầu đặt ra khi mô tả đối tượng trên máy tính Nếu chúng ta coi màn hình là mặt phẳng chiếu hay một vòng hình chữ nhật (cửa sổ) trên màn hình là mặt phẳng chiếu (Trong Pascal, C ta gọi vùng chiếu đó là ViewPort)

Không giảm tổng quát ta giả sử cửa sổ trên mặt phẳng chiếu có kích thước [Xmin,

Xmax] x [Ymin,Ymax]

1 Thuật toán Cohen Sutherland

Thuật toán Cohen Sutherland giải quyết bài toán làm thế nào để xác định phần đoạn thẳng có trong mặt phẳng chiếu Nói một cách khác làm thế nào để xác định phần

đường thẳng cho trước có trong Viewport

Theo Cohen Sutherland một cửa sổ sẽ chia màn hình thành 9 phần mỗi phần ứng với một mã số gồm 4 bit

Mμn hình cửa sổ

Đường thẳng

X O

Y Ymax Ymin

Trang 2

Một điểm P bất kỳ thuộc mặt phẳng chiếu sẽ ứng với một mã gọi là Kod(P)

Kod(P)=b4b3b2b1 Trong đó các bi đ−ợc xác định nh− sau:

( ) 1

b = 1

b = 1

b = 1

b = 1

1

2

3

4

nếu P nằm ở bê n trái của cửa sổ nếu P nằm ở bê n phải của cửa sổ nếu P nằm ở phần bê n d – ới của cửa sổ nếu P nằm ở phần bê n trê n của cửa sổ

Nếu không thoả mãn điều kiện trên thì bi =0, i=1 4,

Một điểm P(x,y) bất kỳ Kod(P)đ−ợc xác định theo (1) nh− sau:

b

1=1 nếu x<xmin b

2=1 nếu x>xmax b

3=1 nếu y>ymax b

4=1 nếu y<ymin Với cách tính này ta suy ra:

b1 lμ bit dấu của x-xmin

b2 lμ bit dấu của xmax-x

b3 lμ bit dấu của ymax-y

b4 lμ bit dấu của y-ymin (Chú ý trong máy tính bit dấu bằng 1 thì có dấu -)

Chúng ta quy −ớc nếu điểm P∈biên của cửa sổ thì Kod(P)=0

Với cách xác định mã ở trên của điểm P ta suy ra P∈ cửa sổ viewport khi

Kod(P)=0000

Do đó

i đoạn thẳng P1P2 thuộc cửa sổ khi

Kod(P1)=Kod(P2)=0000

ii đoạn thẳng sẽ nằm hoàn toàn bên ngoài cửa sổ khi

1001 1000 1010

0001 Viewport 0010

0000

0101 0100 0110

Trang 3

( Kod(P1) And Kod(P2) )≠0000 iii còn lại đoạn thẳng sẽ nằm cả trong lẫn ngoài cửa sổ nghĩa là khi

((Kod(P1) And Kod(P2) ) = 0000) And (( Kod(P1) ≠0000) Or (Kod(P2) ≠0000)) Xác định điểm giao của đoạn thẳng với các cạnh của cửa sổ sau đó vứt bỏ phần không thuộc cửa sổ thuật toán có thể minh hoạ bằng hình sau:

Có thể mô tả thuật toán Cohen-Sutherland như sau:

Giả sử điểm P1 có toạ độ là (x1,y1) và P2 có toạ độ là (x2,y2)

và cửa sổ nhìn có toạ độ là (xmin, ymin)-(xmax,ymax)

1 Tính Kod(P1) và Kod(P2)

2 Nếu Kod(P1)=Kod(P2)=0000 thì P1P2 nằm trong nhẩy đến 5

3 Nếu (Kod(P1) And Kod(P2))<>0000 thì P1P2 nằm ngoài nhẩy đến 6

4 Ngược lại không thoả mãn 2 điều kiện trên thực hiện

- Nếu Kod(P1)=0000 thì ta hoán vị P1 với P2 để Kod(P1)<>0000 và lấy b4b3b2b1= Kod(P1)

- Nếu b1=1 thì y1=y1+(xmin-x1)*(y2-y1)/(x2-x1); x1=xmin

- Nếu b2=1 thì y1=y1+(xmax-x1)*(y2-y1)/(x2-x1); x1=xmax

- Nếu b3=1 thì x1=x1+(ymin-y1)*(x2-x1)/(y2-y1); y1=ymin

- Nếu b4=1 thì x1=x1+(ymax-y1)*(x2-x1)/(y2-y1); y1=ymax

- Quay lại bước 1

5 Vẽ đoạn thẳng P1P2

6 Kết thúc

ở trên chúng ta có thực hiện phép chia cho (x2-x1) và phép chia cho (y2-y1) cho nên trước tiên chúng ta phải xét các trường hợp x2=x1 và trường hợp y2=y1, hai trường hợp này đơn giản tự làm

Chương trình minh họa :

Program Cohen_Sutherland;

uses crt,graph;

type

code=array[1 4] of Byte;

P2 P'2 Bỏ

P4 P"1

P'3 P'1

P3 P1

Trang 4

var

a1,b1,a2,b2 : Real;

n,i, xmin,ymin,xmax,ymax,gd,gm:integer;

b: code;

(****************************************)

Procedure Special_Line(x1,y1,x2,y2: Real);

Var

tg: Real;

Begin

If (x1=x2) And (x1>xmin) And (x1<xmax) Then

Begin

If y1>y2 Then

Begin

tg:=y1; y1:=y2; y2:=tg;

End;

If (y1<ymax) And (y2>ymin) Then

Begin

If y1<ymin Then y1:=ymin;

If y2>ymax Then y2:=ymax;

End;

Line(Round(x1),Round(y1),Round(x2),Round(y2));

End;

If (y1=y2) And (y1>ymin) And (y1<ymax) Then

Begin

If x1>x2 Then

Begin

tg:=x1; x1:=x2; x2:=tg;

End;

If (x1<xmax) And (x2>xmin) Then

Begin

If x1<xmin Then x1:=xmin;

If x2>xmax Then x2:=xmax;

End;

Line(Round(x1),Round(y1),Round(x2),Round(y2));

End;

End;

(*****************************)

Procedure Kod(x,y:real;var b:code );

Begin

For i:=1 To 4 Do b[i]:=0;

if(x < xmin) then b[1]:=1;

if(x > xmax) then b[2]:=1;

if(y < ymin) then b[3]:=1;

if(y > ymax) then b[4]:=1;

End;

Trang 5

(****************************************)

Procedure Cohen_Sutherland_Clipping(x1,y1,x2,y2:Real);

var

c1,c2: code;

chon,tong1,tong2,mu2: Byte;

tgx,tgy : Real;

Begin

Repeat

Kod(x1,y1,c1); Kod(x2,y2,c2);

tong1:=0; tong2:=0; mu2:=1;

For i:=1 To 4 Do

Begin

tong1:=tong1+c1[i]*mu2;

tong2:=tong2+c2[i]*mu2;

mu2:=mu2*2;

End;

If tong1+tong2=0 Then

Begin

chon:=1;

line(Round(x1),Round(y1),Round(x2),Round(y2));

End

Else If (tong1 And tong2)<>0 then

Begin

chon:=2;

End

Else

Begin

chon:=3;

If tong1=0 then

Begin

tgx:=x1; x1:=x2; x2:=tgx;

tgy:=y1; y1:=y2; y2:=tgy;

End;

Kod(x1,y1,b);

if b[1]=1 then

Begin

y1:=y1+(xmin-x1)*(y2-y1)/(x2-x1); x1:=xmin

End;

if b[2]=1 then

Begin

y1:=y1+(xmax-x1)*(y2-y1)/(x2-x1); x1:=xmax

End;

if b[3]=1 then

Begin

x1:=x1+(ymin-y1)*(x2-x1)/(y2-y1); y1:=ymin

Trang 6

End;

if b[4]=1 then

Begin

x1:=x1+(ymax-y1)*(x2-x1)/(y2-y1); y1:=ymax

End;

End;

Until (chon=1) Or (chon=2);

End;

(****************************************)

Begin

clrscr;

write('nhap toa do cua so xmin,ymin: ');

readln(xmin,ymin);

write('nhap toa do cua so xmax,ymax: ');

readln(xmax,ymax);

write('Nhap (a1,b1): '); readln(a1,b1);

write('Nhap (a2,b2): '); readln(a2,b2);

gd:=detect;

initgraph(gd,gm,'c:\tp\bgi');

setbkcolor(Black);

setcolor(red);

rectangle(xmin,ymin,xmax,ymax);

settextjustify(1,1);

outtextxy(320,450,'HIEN THI MOT DOAN THANG TRONG MOT CUA SO CHO TRUOC');

outtextxy(320,470,'THEO THUAT TOAN COHEN-SUTHERLAND');

setcolor(WHITE);

setlinestyle(1,0,0);

line(Round(a1),Round(b1),Round(a2),Round(b2));

setlinestyle(0,0,0);

If (a1<>a2)And(b1<>b2) Then Cohen_Sutherland_Clipping(a1,b1,a2,b2)

Else Special_Line(a1,b1,a2,b2);

readln;

closegraph;

End

2 Thuật toán Liang-Barsky

Thuật toán xác định phần đường thẳng của Cohen Shutherland tương đối đơn giản và thuận tiện, tuy nhiên nó có nhược điểm khi người lặp lại quá trình xác định giao

điểm của đoạn thẳng với cửa sổ phải tiến hành nhiều phép nhân, chia điều này sẽ dẫn đến hậu quả là thời gian xử lý chậm, gặp nhiều sai số Hai nhà toán học Liang

và Barsky đã đưa ra một thuật toán khác để khắc phục nhược điểm trên Giả sử đoạn thẳng cho dưới dạng tham số đi qua 2 điểm P1(x1,y1), P2(x2,y2) có dạng:

x = x + tdx

y = y + tdy

1 1

Trang 7

với dx=x

2-x

1; dy=y

2-y

1 t∈[0,1]

Giả sử cửa sổ giới hạn bởi hai điểm ở góc trên bên trái và góc dưới bên phải

(xmin,ymin) , (xmax,ymax) khi đó đoạn thẳng thuộc vào cửa sổ khi và chỉ khi

x x + tdx x

y y + tdy y

⇔ x - x tdx x - x

y - y tdy y - y

⇔ t.pk≤qk , k=1,2,3,4 (2) Với p

1=-dx q

1=x

1-xmin p

2=xmax-x1

p3=-dy q3=y1-ymin

p4=dy q4=ymax-y1

Từ (2) ta suy ra:

1 Nếu có k (bằng 1 hoặc 3) để p

k=0 thì đoạn thẳng song song với một cạnh nào đó của cửa sổ

2 Nếu với ∀k mà pk≠0 thì ta xác định t1 và t2

t1=Max{0,Max(qk/pk)} với các pk<0

t2=Max{(1,Min(qk/pk)} với các pk>0

khi đó xác định được đoạn thẳng (xw1,yw1)-(xw2,yw2) nằm trong cửa sổ

xw1=x1+t1*dx; yw1=y1+t1*dy

xw2=x1+t2*dx; yw2=y1+t2*dy

Ta có thuật toán Liang Barsky

1 đặt t1=0; t2=1;

2 Tính pk và qk theo công thức trên với k=1,2,3,4

3 Nếu có pk=0 thì đoạn thẳng song song với 1 trong 2 cạnh của cửa sổ

4 Nếu pk<>0 (với k=1,2,3,4) thì

- Cho k chạy từ 1 đến 4

- đặt t=qk/pk

- nếu pk<0 thì đặt t1=max(t1,t)

- nếu pk>0 thì đặt t2=min(t2,t)

5 Nếu t1<=t2 thì toạ độ giao của đoạn thẳng với cửa sổ là

+ xw1=x1+t1*dx ; yw1=y1+t1*dy

+ xw2=x1+t2*dx ; yw2=y1+t2*dy

+ vẽ đoạn thẳng (xw1,yw1)-(xw2,yw2)

6 Nếu t1>t2 thì P1P2 nằm ngoài cửa sổ và kết thúc

Chương trình minh họa :

Program Liang_Barsky;

Uses Crt,Graph;

Trang 8

Var

gd,gm,k : integer;

xmin,xmax,ymin,ymax : integer;

a1,b1,a2,b2,dx,dy : Real;

p,q : Array[1 4] Of Real;

(*****************************)

Procedure Special_Line(x1,y1,x2,y2: Real);

Var

tg: Real;

Begin

If (x1=x2) And (x1>xmin) And (x1<xmax) Then

Begin

If y1>y2 Then

Begin

tg:=y1; y1:=y2; y2:=tg;

End;

If (y1<ymax) And (y2>ymin) Then

Begin

If y1<ymin Then y1:=ymin;

If y2>ymax Then y2:=ymax;

End;

Line(Round(x1),Round(y1),Round(x2),Round(y2));

End;

If (y1=y2) And (y1>ymin) And (y1<ymax) Then

Begin

If x1>x2 Then

Begin

tg:=x1; x1:=x2; x2:=tg;

End;

If (x1<xmax) And (x2>xmin) Then

Begin

If x1<xmin Then x1:=xmin;

If x2>xmax Then x2:=xmax;

End;

Line(Round(x1),Round(y1),Round(x2),Round(y2));

End;

End;

(*****************************)

Procedure Liang_Barsky_Clipping(x1,y1,x2,y2: Real);

Var

xw1,yw1,xw2,yw2,t,t1,t2: Real;

Begin

t1:=0; t2:=1;

dx:=x2-x1; dy:=y2-y1;

p[1]:=-dx; p[2]:=dx; p[3]:=-dy; p[4]:=dy;

Trang 9

q[1]:=x1-xmin; q[2]:=xmax-x1; q[3]:=y1-ymin; q[4]:=ymax-y1;

For k:=1 To 4 Do

Begin

t:=q[k]/p[k];

If p[k]<0 then If t1<t Then t1:=t;

If p[k]>0 then If t2>t then t2:=t;

End;

If t1<=t2 then

Begin

xw1:=x1+t1*dx; yw1:=y1+t1*dy;

xw2:=x1+t2*dx; yw2:=y1+t2*dy;

Line(Round(xw1),Round(yw1),Round(xw2),Round(yw2));

End;

End;

(*****************************)

Begin

Clrscr;

write('Nhap (xmin,ymin): '); readln(xmin,ymin);

write('Nhap (xmax,ymax): '); readln(xmax,ymax);

write('Nhap (a1,b1): '); readln(a1,b1);

write('Nhap (a2,b2): '); readln(a2,b2);

gd:=detect;

Initgraph(gd,gm,'C:\tp\bgi');

setcolor(White);

setlinestyle(1,0,0);

Line(Round(a1),Round(b1),Round(a2),Round(b2));

setlinestyle(0,0,0);

If (a1<>a2) And (b1<>b2) Then Liang_Barsky_Clipping(a1,b1,a2,b2)

Else Special_Line(a1,b1,a2,b2);

settextjustify(1,1);

outtextxy(320,450,'HIEN THI MOT DOAN THANG TRONG MOT CUA SO CHO TRUOC');

outtextxy(320,470,'THEO THUAT TOAN LIANG_BARSKY');

rectangle(xmin,ymin,xmax,ymax);

Readln;

Closegraph;

End

$13 Vùng nhìn thấy

Trong khi quan sát các vật thể trong không gian chúng ta gặp hai tình huống sau:

1 Từ vị trí quan sát chúng ta có thể nhìn thấy một phần hay không nhìn thấy vật thể

Điều này phụ thuộc vào vị trí và góc nhìn của người quan sát đối với vật thể

Ngày đăng: 24/07/2014, 10:21

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w