Đoạn thẳng, điểm

Một phần của tài liệu Tìm hiểu về đồ họa máy tính ppt (Trang 94 - 177)

Đoạn thẳng là nguyờn thể đồ họa nhỏ nhất. Ta vẽ đoạn thẳng bằng cỏch trước hết đặt con trỏ đồ họa vào điểm đầu mỳt thứ nhất, sau đú vẽ đoạn nối tới đầu mỳt thứ hai. Ta dựng cặp biến (XP1, YP1) để theo dừi và định vị con trỏ đồ họa.

PROCEDURE VeDen (X,Y : Real);{ Vẽ đoạn nối (XP1,YP1) đến (X,Y) và clipping nú}

BEGIN XP2 := X; YP2 := Y;

Cat (XP1,YP1,XP2,YP2); {clipping}

XP1 := XP2; {chuyển con trỏ tới đầu mỳt thứ hai vừa xỏc định } YP1 := YP2

END;

PROCEDURE Diem (X,Y : Real); BEGIN XP1 := X; YP1 := Y; VeDen (X,Y) END; 6.1.3. Chiếu cửa sổ lờn tầm nhỡn

Sau khi đó xỏc định được cửa sổ (vựng cần khảo sỏt) và tầm nhỡn (vựng dành cho việc hiển thị), cụng việc tiếp theo là chiếu toàn bộ nội dung cửa sổ lờn màn hỡnh. Để làm việc này ta cần cú cụng thức toỏn học của phộp chiếu cho phộp xỏc định tọa độ ảnh (Xe, Ye) của điểm thực (Xr, Yr) qua phộp chiếu.

Đầu tiờn ta tớnh tỷ lệ giữa cửa sổ và tầm nhỡn:

Xtl=(C2-C1)/(F2-F1), Ytl = (C4-C3) /(F4-F3) Khi đú ta cú:

Vớ dụ: Xột cửa sổ (-3,3,-2,3), tầm nhỡn (100,700,50,300) Giả sử (Xr,Yr) = (1.5, 1) Ta cú Xtl = (700-100) / (3+3) = 100; Ytl = (300 -50) / (3+2) = 50 Vậy Xe = (1.5+3).100 = 450; Ye = (3-1).50 = 100; Hỡnh 6.3. Chiếu cửa sổ lờn tầm nhỡn

Hiện tượng mộo hỡnh

Gọi B và H là đỏy và chiều cao cửa sổ, cũn B’, H’ là đỏy và chiều cao của tầm nhỡn. Khi chiếu cửa sổ lờn tầm nhỡn, nếu tỷ lệ B/H ≠ B’/H’ thỡ sẽ xảy ra hiện tượng mộo hỡnh, nghĩa là đối tượng khụng cũn giữ được nguyờn vẹn hỡnh dạng lỳc đầu Cửa sổ Tầm nhỡn F1 (Xr,Yr) F3 F4 C1 C2 C3 C4 (Xe,Ye) 92

Hiệu ứng Zoom

Ta cố định tầm nhỡn trờn màn hỡnh và xột cỏc trường hợp sau:

• Trong khi giữ nguyờn kớch thước cửa sổ, ta di chuyển nú tới những vị trớ khỏc nhau trong khụng gian thực, khi đú trờn tầm nhỡn hiện ra những phần khỏc nhau của ảnh. Hỡnh của ảnh được chiếu lờn màn hỡnh cú kớch thước khụng đổi

• Khi kớch thước cửa sổ bị thu nhỏ lại, phần diện tớch được khảo sỏt của đối tượng cũng thu nhỏ lại theo nhưng ảnh của nú trờn màn hỡnh lại được phúng to ra

• Ngược lại, nếu cửa sổ được phúng to ra thỡ phần diện tớch được khảo sỏt của đối tượng cũng tăng lờn nhưng ảnh của nú trờn màn hỡnh lại thu nhỏ lại

B

H H’

B’

Hỡnh 6.4. Hiện tượng mộo hỡnh

6.2. Cắt xộn (Clipping)

6.2.1. Thuật toỏn Cohen-Sutherland

Bài toỏn: giả thiết rằng cửa sổ hiển thị là một hỡnh chữ nhật với cỏc cạnh song song với cỏc trục tọa độ như hỡnh vẽ. Cho một đoạn thẳng bất kỳ, hóy xỏc định phần nào của nú nằm trong cửa sổ (tức là được hiển thị), phần nào nằm ngoài (bị che khuất). Cửa sổ Cửa sổ Tầm nhỡn Tầm nhỡn Hỡnh 6.5. Hiệu ứng zoom 94 xmin xmax ymin ymax 1001 0001 0101 0100 0000 1000 1010 0010 0110 J I J’ I’ A B C D E F K L K’

Hỡnh 6.6. Cỏch xỏc định phần của đường thẳng nằm trong cửa sổ

Cỏch làm: đầu tiờn ta nhận xột rằng một điểm P(x,y) nằm trong cửa sổ (được nhỡn thấy) khi và chỉ khi thỏa món đồng thời 2 điều kiện:

xmax≥ x ≥ xmin ymax ≥ y ≥ ymin

Ngược lại, nếu một trong 2 điều kiện bị vi phạm thỡ P nằm ngoài cửa sổ và sẽ khụng được hiển thị.

Cỏc đoạn thẳng chỉ cú thể thuộc một trong những trường hợp sau:

• Hoàn toàn nằm trong cửa sổ, vớ dụ như AB, khi đú cả 2 đầu mỳt đều nằm bờn trong cửa sổ

• Hoàn toàn nằm ngoài cửa sổ (bị che toàn phần), vớ dụ như CD, EF

• Chỉ một phần nằm trong cửa sổ và được hiển thị, vớ dụ như KL và IJ

Đầu tiờn, thuật toỏn Cohen – Sutherland dựng 4 đường thẳng chứa cạnh cửa sổ chia mặt phẳng thành 9 phần. Mỗi điểm A(x,y) thuộc mặt phẳng sẽ được gỏn mó 4 bit abcd theo cỏch sau:

• a=1 ⇔ y > ymax : A nằm phớa trờn cửa sổ

• b=1 ⇔ y < ymin : A nằm phớa dưới cửa sổ

• c=1 ⇔ x > xmax : A nằm phớa phải cửa sổ

• d=1 ⇔ x < xmin : A nằm phớa trỏi cửa sổ Khi đú, ta nhận xột rằng:

• đoạn thẳng sẽ hoàn toàn nằm trong cửa sổ nếu cả 2 đầu mỳt đều bằng 0000

• đoạn thẳng sẽ hoàn toàn nằm ngoài cửa sổ nếu kết quả phộp AND của 2 đầu mỳt khỏc 0000

Thực vậy, nhận xột đầu là hiển nhiờn. Để minh họa cho nhận xột 2, xột đoạn thẳng EF:

E = 1010, F = 0010 ⇒ (E) AND (F) = (1010) and (0010) = 0010 ≠ 0

bit thứ 3 của cả 2 đầu mỳt E và F đều bằng 1, chứng tỏ chỳng đều nằm bờn phải cửa sổ, do đú cả đoạn thẳng dĩ nhiờn cũng nằm bờn phải cửa sổ và sẽ khụng được hiển thị.

Vấn đề cũn lại là, nếu kết quả phộp AND hai đầu mỳt bằng 0000, khi đú thuật toỏn sẽ tỡm giao của đoạn thẳng với cỏc biờn của cửa sổ và xột từng phần của nú. Ta ký hiệu 4 đường thẳng chứa cạnh cửa sổ là:

• đường 1: y = ymax

• đường 2: y = ymin

• đường 3: x = xmax

• đường 4: x = xmin

Khi đú nhỡn vào mó của 2 đầu mỳt ta sẽ biết ngay đoạn thẳng đú cắt cạnh nào của cửa sổ. Vớ dụ: 96 xmin xmax ymin ymax 1 2 J I J’ I’ 3 K L K’ 4 0001 0100 0010

Hỡnh 6.7. Giao của đường thẳng và cửa sổ Xột đoạn IJ • Mó của I = 0100, bớt thứ 2 =1 nờn chắc chắn nú sẽ cắt đường 2 • Mó của J = 0001, bớt thứ 4 =1 nờn chắc chắn nú sẽ cắt đường 4 Xột đoạn KL • Mó của L = 0100, bớt thứ 3 =1 nờn chắc chắn nú sẽ cắt đường 3

Việc xỏc định tọa độ giao điểm là rất đơn giản vỡ ta đó biết rừ 2 đầu mỳt. Sau khi chia đoạn thẳng thành cỏc đoạn, ta lặp lại thuật toỏn với mỗi đoạn chia cho đến khi kết thỳc. Vớ dụ ta xột đoạn IJ

• Bước 1: kết quả phộp and bằng 0 nhưng 2 đầu mỳt khỏc 0: tỡm giao điểm với biờn I’

• Bước 2: loại đoạn II’

• Bước 3: xột đoạn JI’ : tỡm giao điểm J’

• Bước 4: loại đoạn JJ’. Kết thỳc với đoạn I’J’ được hiển thị

6.2.2. Thuật toỏn Sutherland - Hodgman

Bài toỏn: ta cần cắt 1 đa giỏc bất kỳ Y vào trong cửa sổ là một đa giỏc lồi X.

Cỏch làm: Ta sẽ duyệt lần lượt cỏc cạnh của X, với mỗi cạnh đú ta lại xột lần lượt cạnh của Y. Kết quả sau khi xộn với cạnh thứ i (của cửa sổ X) sẽ được dựng để xộn với cạnh tiếp theo i+1 của X. Quy tắc là:

• nếu cạnh đang xột của Y đi từ trong cửa sổ ra ngoài (Pi-1 ở trong, Pi ở ngoài) thỡ chỉ giữ lại giao điểm I của Pi-1 Pi với cạnh đang xột của X.

• nếu cạnh đang xột đi từ ngoài vào trong (tức là Pi-1 ở ngoài, Pi ở trong): giữ lại giao điểm I và Pi

• trường hợp cạnh ở ngoài hoàn toàn: loại bỏ

Hỡnh 6.8. Giao của đa giỏc bất kỳ và cửa sổ

Vớ dụ

Đầu tiờn ta xột cạnh UV của cửa sổ cắt là tam giỏc UVT.

Cạnh đang xột (theo chiều

vecto) Hướng đi

Quyết định giữ lại

AB (xột với UV) Từ ngoài vào trong P,B

BC (xột với VT) Trong ra ngoài Q

CD Ngoài vào trong R,D

DE Hoàn toàn nằm trong E

EK (xột với TU) Trong ra ngoài M

KF Hoàn toàn nằm ngoài Loại hết

FG Ngoài vào trong I,G

GH (xột với UV) Trong ra ngoài J

HA Hoàn toàn nằm ngoài Loại hết

Ta thu được đa giỏc (theo thứ tự): P,B,Q,R,D,E,M,I,G,J như hỡnh vẽ Đoạn mó giả (pseudocode) sau minh họa cho thuật toỏn trờn.

t:=1

for i:=1 to n do {Đa giỏc cửa sổ X cú n cạnh}

for j:=1 to m do {Đa giỏc bị cắt Y cú m cạnh }

k:=j+1; {Xột cạnh XjXj+1 của đa giỏc cửa sổ X}

if k>n then k:=1 ; if (Xj ở trong) then A B P Q C R D E K F G J H U V M I T 98

begin

if (Xk ở trong) then Yt := Yk

else Yt := giao điểm của XjXk với cạnh i của X t:=t+1; end else if (Xk ở trong ) then begin Yt := giao điểm; t:=t+1; Yt := Xk ; t:=t+1; end;

Vấn đề: cho tọa độ 1 điểm, làm sao biết điểm đú ở trong/ngoài đa giỏc lồi X ?

Bổ đề: nếu điểm đú nằm bờn phải 1 cạnh nào đú của đa giỏc lồi X theo chiều dương thỡ nú nằm ngoài X. Nếu nú nằm bờn trỏi tất cả cỏc cạnh thỡ nú nằm bờn trong X

chiều dương

bờn phải

bờn trỏi A(x1,y1) B(x2,y2) P(x,y)

Hỡnh 6.9. Vị trớ của một điểm so với đa giỏc

Bổ đề: cho vector AB và điểm P(x,y), P nằm bờn trỏi vector AB (như hỡnh vẽ) nếu và chỉ nếu (x2 – x1)(y – y1) – (y2 – y1)(x – x1) >0

Ta cụng nhận, khụng chứng minh bổ đề toỏn này.

Vấn đề: cho tọa độ tập đỉnh của đa giỏc lồi X dưới dạng 1 danh sỏch cú thứ tự (nghĩa là nếu biết 1 đỉnh thỡ ta luụn biết 2 đỉnh kề của nú), làm sao xếp chỳng lại “theo chiều dương” ?

Cỏch làm: Chọn đỉnh cú hoành độ nhỏ nhất, ký hiệu là A như hỡnh vẽ. Gọi 2 đỉnh kề nú là B,C trong đú xB < xC. Thứ tự theo chiều dương sẽ là BAC. Sau đú ta chỉ việc đi tới đỉnh tiếp theo C ...

Thật vậy, ta cú thể thấy rừ khi nhỡn hỡnh vẽ. Chỉ cú 3 trường hợp:

• B,C nằm ở 2 phớa của đường thẳng x = xA

• B,C cựng nằm bờn phải đường thẳng đú

• B,C cựng nằm bờn trỏi

Hỡnh 6.10. Vị trớ của 3 điểm A, B, C

6.2.3. Clipping một đoạn thẳng vào đường trũn

100 B A C B A C B A C B O A d B O A d B A (b) (a) (c) C D

Hỡnh 6.11. Clipping một đường thẳng vào đường trũn

Gọi d là khoảng cỏch từ tõm O tới đoạn thẳng AB.

• Nếu d > bỏn kớnh r ⇒ clip(AB) = ∅

• Nếu d = bỏn kớnh r ⇒ clip(AB) = {điểm tiếp xỳc}

• Nếu d < bỏn kớnh r, ta chia thành 3 trường hợp

o Cả A,B đều nằm trong đường trũn: clip(AB) = AB

o Một trong hai điểm (giả sử là A) nằm ngoài đường trũn. Gọi C là giao của AB với đường trũn ta cú clip(AB) = BC

o Cả 2 cựng nằm ngoài đường trũn, xột dấu:

 Nếu (xA-xC) (xB-xC) <0 thỡ clip(AB)=CD (trường hợp (c))

 Nếu (xA-xC) (xB-xC) >0 thỡ clip(AB)=∅ (trường hợp (b))

6.2.4. Clipping một vựng (Area clipping)

Làm thế nào cỏc đa giỏc được dựng trong cỏc ứng dụng vẽ đường (line- drawing application) cú thể bị cắt bằng cỏch xử lý cỏc đoạn thẳng thành phần thụng qua cỏc thuật toỏn clipping đường đó được thảo luận. Một đa giỏc được xử lý theo cỏch này sẽ được thu giảm một loạt cỏc đoạn sẽ bị cắt

Khi một một biờn đa giỏc định nghĩa một vựng tụ. Một version thay đổi của thuật toỏn clipping đường được cần đến. Trong trường hợp này, một hoặc nhiều vựng kộp kớn phải được tạo ra để định nghĩa cỏc biờn cho vựng tụ.

Hỡnh 6.13. Một vựng cú hỡnh dạng, trước và sau khi clipping

Một kỹ thuật cho việc clipping đa giỏc, được phỏt triển bởi Sutherland và Hodgman, thực hiện việc clipping bằng cỏch so sỏnh một đa giỏc với lần lượt mỗi biờn cửa sổ. Kết quả trả về của thuật toỏn là một tập cỏc đỉnh định nghĩa vựng bị cắt (vựng này được tụ với một màu hay một mẫu tụ nào đú). Phương phỏp căn bản được thể hiện như hỡnh 5.14:

Hỡnh65.12. Đa giỏc bị cắt bởi một thuật toỏn clipping đường

Hỡnh 6.14.Clipping một vựng đa giỏc bằng cỏch dựng cỏc biờn cửa sổ

Cỏc vựng đa giỏc được định nghĩa bằng việc xỏc định một dóy cú thứ tự cỏc đỉnh. Để cắt một đa giỏc, chỳng ta so sỏnh lần lượt mỗi đỉnh với biờn một cửa sổ. Cỏc đỉnh nằm bờn trong cạnh cửa sổ này được giữ lại cho việc clipping với biờn kế tiếp của cửa sổ.

Hỡnh 6.15.Clipping

Quỏ trỡnh xử lớ cỏc đỉnh của một đa giỏc liờn quan đến biờn của cửa sổ. Từ đỉnh S, đỉnh kế tiếp được xột (P) cú thể sinh ra một điểm, khụng điểm nào, hoặc hai điểm sẽ được lưu bởi thuật toỏn cỏc đỉnh bờn ngoài cạnh cửa sổ bị vứt bỏ. Nếu chỳng ta khởi hành từ một điểm bờn trong cạnh cửa sổ đi đến một điểm bờn ngoài, chỳng ta lưu lại giao điểm của đoạn thẳng với biờn cửa sổ. Cả hai giao điểm và đỉnh đa giỏc được lưu lại nếu chỳng ta đi từ ngoài cạnh cửa sổ vào bờn trong. Khả năng thứ tư cú thể xảy ra khi chỳng ta xử lớ một điểm (P) và điểm trước đú (S) với biờn cửa sổ được minh họa trong hỡnh clipping. Một điểm bờn trong biờn cửa sổ được lưu lại (trường hợp a), trong khi một điểm bờn ngoài thỡ khụng (trường hợp c). Nếu một điểm P và điểm trước đú S nằm trờn cỏc phớa đối diện nhau qua một biờn (P ở trong, S ở ngoài và ngược lại), giao điểm I được tớnh và được lưu (trường hợp b và d). Trong trường hợp d, điểm P nằm trong và điểm trước đú S nằm ngoài, vỡ

vậy cả hai giao điểm I và P được lưu. Khi tất cả cỏc đỉnh vừa được xử lớ với biờn trỏi cửa sổ, tập cỏc điểm được lưu sẽ tiếp tục bị cắt khi xem xột với biờn kế tiếp của cửa sổ.

Chỳng ta minh họa phương phỏp này bằng việc xử lớ vựng như hỡnh dưới đõy khi xem xột với biờn bờn trỏi của cửa sổ. Đỉnh 1 và 2 được xỏc định là nằm bờn ngoài của biờn. Đi qua đến đỉnh 3, đang nằm bờn trong, chỳng ta tớnh giao điểm và lưu lại cả hai giao điểm và đỉnh 3. Đỉnh 4 và 5 được xỏc định là nằm trong, và chỳng nú cũng được lưu lại. Đỉnh thứ sỏu và đỉnh cuối cựng thỡ nằm ngoài, vỡ vậy chỳng ta tớnh và lưu giao điểm. Dựng năm điểm vừa được lưu, chỳng ta lặp lại quỏ trỡnh này khi xem xột với biờn kế tiếp của cửa sổ.

Cài đặt cỏc thuật toỏn vừa được mụ tả đũi hỏi phải dựng khụng gian lưu trữ ngoài để lưu cỏc điểm. Điều cú thể trỏnh được nếu chỳng ta quản lý được mỗi điểm (điểm sắp sửa được lưu và đi nhanh qua nú để kiểm tra tiếp), cựng với cỏc lệnh (instructions) để cắt nú khỏi biờn kế tiếp của cửa sổ. Chỳng ta lưu một điểm (dự là một đỉnh nguyờn thuỷ của đa giỏc hay một đỉnh cú được khi tớnh giao điểm) chỉ sau khi nú được xử lớ khi xem xột với tất cả cỏc biờn. Như thể chỳng ta cú một đường ống chứa một chuỗi cỏc động tỏc clipping. Một điểm nằm bờn trong hay nằm trờn biờn cửa sổ ở một giai đoạn sẽ được đi qua để đến giai đoạn kế tiếp.

Thủ tục sau đõy thể hiện tiếp cận này . Một mảng s, lưu những điểm mới nhất vừa bị cắt cho với mỗi biờn của cửa sổ. Quỏ trỡnh chớnh đi qua mỗi đỉnh p đi vào quỏ trỡnh clip_this để xem xột việc cắt với cạnh đầu tiờn của cửa sổ . Nếu đoạn

104

Hỡnh 6.16. Clipping một đa giỏc khỏi cạnh bờn trỏi cửa sổ, bắt đầu với đỉnh 1. Cỏc số cú phảy được dựng để đỏnh nhón cỏc điểm được lưu bởi thuật toỏn clipping.

thẳng được định nghĩa bởi điểm đầu mỳt p và s[edge] cắt cạnh cửa sổ này, giao điểm được xỏc định và được đi qua để đến giai đoạn kế tiếp. Nếu p nằm bờn trong cửa sổ, nú bị bỏ qua để đến giai đoạn clipping kế tiếp. Bất kỡ điểm nào cũn được giữ lại sau khi xem xột với tất cả cỏc cạnh của cửa sổ thỡ sau đú được gia nhập vào mảng kết quả kết xuất x_out và y_out. Mảng first_point lưu giữ cho mỗi cạnh cửa sổ điểm đầu tiờn bị cắt bởi cạnh đú. Sau khi tất cả cỏc đỉnh của đa giỏc vừa được xem xột xong, một quỏ trỡnh kết thỳc cắt cỏc đoạn (đoạn đó được định nghĩa bởi cỏc điểm đầu và cuối (cỏc điểm bị cắt khỏi mỗi mỗi cạnh).

type

point = array [1..max_points] of real;

procedure polygon_clip (n : integer; x, y : points; var m : integer; var x_out, y_out : points);

const

boundary_count = 4;

type

vertex = array [1..2] of real;

boundary_range = 1..boundary_count;

var

k : integer; p : vertex;

s, first_point : array [1..boudary_count] of vertex; new_edge : array [1..boundary_count] of boolean;

function inside (p : vertex; edge : boundary_range) : boolean;

begin

{trả về true nếu đỉnh p nằm trong cạnh edge cửa sổ}

end; { inside}

begin

{trả về true nếu cạnh đa giỏc ps cắt biờn cửa sổ}

end; {cross}

procedure output_vertex (p : vertex);

begin

m := m +1;

x_out[m] := p[1]; y_out[m] := p[2];

end; { output_vertex }

procedure find_intersection (p, s : vertex;

edge : boundary_range; var i; vertex);

begin

{trả về trong tham số i giao điểm của ps với biờn edge cửa sổ }

end; { intersection }

procedure clip_this (p : vertex; edge : boundary_range);

var i : vertex;

begin{ clip_this }

{lưu điểm đầu tiờn cắt biờn cửa sổ}

if new_edge[edge] then begin

first_point[edge] := p; new_edge[edge] := false

Một phần của tài liệu Tìm hiểu về đồ họa máy tính ppt (Trang 94 - 177)

Tải bản đầy đủ (DOC)

(177 trang)
w