Chương IV.

Các phép biến hình
Các phép biến đổi hình học cơ sở bao gồm: - tịnh tiến /dời hình (translation) - quay (rotation) - tỷ lệ /vị tự / (scaling) Ví dụ: - một báo cáo viên muốn thu nhỏ các biểu đồ trong báo cáo - một kiến trúc sư muốn nhìn tòa nhà ở những góc nhìn khác nhau - nhà thiết kế muốn quan sát, tách rời và chỉnh sửa từng chi tiết của mẫu thiết kế - ... Có hai quan điểm về phép biến đổi hình học, có liên quan với nhau và đều có những lợi thế riêng: - Biến đổi đối tượng (object transformation): tọa độ của từng điểm trên đối tượng được biến đổi theo công thức của phép biến hình, tạo ra ảnh của đổi tượng qua phép biến hình đó. - Biến đổi hệ tọa độ (coordinate transformation): tạo ra một hệ tọa độ mới, sau đó tất cả các điểm của đối tượng sẽ được chuyển về hệ tọa độ đó. Phép biến hình affin Ánh xạ T: R2 R2 P(x,y) Q(x*,y*) ⎧ x* = f ( x, y ) trong đó: ⎨ ⎩ y* = g ( x, y ) và f() và g() là hai hàm tuyến tính thì được gọi là phép biến hình Affin (affine). Ta chỉ khảo sát các phép biến hình loại này. Phép biến hình affin có những tính chất sau: - Bảo toàn đường thẳng: ảnh của đường thẳng qua phép biến hình affine là đường thẳng. - Bảo toàn tính song song của các đường thẳng: ảnh của các đường thẳng song song qua phép biến hình affine cũng là các đường thẳng song song. - Bảo toàn tỷ lệ về khoảng cách: giả sử C là điểm chia đoạn AB theo tỷ lệ x và A’,B’,C’ lần lượt là ảnh của A,B,C qua một phép biến hình affin. Khi đó C’ cũng chia đoạn A’B’ theo tỷ lệ x.

4.1. Các phép biến hình phẳng
4.1.1 Các phép biến hình trong hệ tọa độ Decac Phép tịnh tiến Ảnh của phép tịnh tiến theo vector (a,b) của điểm P(x,y) là điểm Q(x*,y*) ⎧ x* = x + a ⎨ ⎩ y* = y + b Vector tịnh tiến (a,b) còn gọi là “vector độ dời”. Chúng ta có thể áp dụng quy tắc trên cho mọi điểm của đối tượng để dịch chuyển nó. Đơn giản hơn, để tịnh tiến một đa giác chỉ cần http://www.ebook.edu.vn 1

tịnh tiến các đỉnh của nó rồi vẽ lại đa giác mới. Tương tự, đối với đường tròn, ellip ta tịnh tiến tâm của chúng tới vị trí mới rồi vẽ lại.

Phép tịnh tiến trong mặt phẳng Phép tỷ lệ Làm thay đổi kích thước của đối tượng.

⎧ x* = tx.x ⎨ ⎩ y* = ty. y
trong đó ty, tx là hệ số co dãn theo trục tung và trục hoành. Khi tx,ty nhỏ hơn 1, phép biến đổi sẽ thu nhỏ đối tượng. Khi tx,ty lớn hơn 1, phép biến đổi sẽ phóng to đối tượng. Khi tx=ty: ta gọi đó là phép đồng dạng (uniform scaling), nó bảo toàn tỷ lệ về kích thước của vật thể.

6 5 4 3 2 1 1 2 3 4 5 6 Phép tỷ lệ tx=3; ty=1 tx=ty=3

http://www.ebook.edu.vn

2

Phép quay Phép quay làm thay đổi hướng của đối tượng. Để xác định phép quay, ta cần biết tâm quay và góc quay. Phép quay điểm P(x,y) quanh gốc tọa độ một góc α tạo thành điểm ảnh Q(x*,y*) có công thức như sau:

⎧ x* = x. cos α − y. sin α ⎨ ⎩ y* = x. sin α + y. cos α

1800

Phép quay quanh một điểm 4.1.2 Ma trận của phép biến hình. Nếu ta biểu diễn điểm P,Q dưới dạng vector dòng (x,y) (x*,y*) như trên thì ma trận của các phép biến hình như sau: Phép tịnh tiến: (x*,y*) = (x,y) + (a,b) Q = P + T trong đó T = (a,b) Phép tỷ lệ:

⎜ (x*, y *) = (x, y )⎛ ⎜

tx 0 ⎞ ⎟ ⎟ ⎝ 0 ty ⎠

⎛ tx 0 ⎞ Q = P×S trong đó S = ⎜ ⎟ ⎜ 0 ty ⎟ là ma trận của phép đồng dạng ⎠ ⎝ Phép quay quanh gốc tọa độ: cos α sin α ⎞ ⎜ (x*, y *) = (x, y )⎛ ⎜ − sin α cos α ⎟ ⎟ ⎝ ⎠

http://www.ebook.edu.vn

3

⎛ cos α sin α ⎞ hay Q=P×R trong đó R = ⎜ ⎜ − sin α cos α ⎟ là ma trận của phép quay ⎟ ⎝ ⎠ Tuy nhiên, cách biểu diễn trên sẽ gặp khó khăn khi kết hợp các phép biến đổi lại với nhau vì biểu diễn của phép tịnh tiến (cộng ma trận) khác với hai phép biến hình còn lại (nhân ma trận). Chẳng hạn, khi thiết kế một động cơ, ta muốn tháo riêng một chi tiết ra ngoài (tịnh tiến), xoay 1 góc (quay) rồi lắp vào chỗ cũ (tịnh tiến). Khi đó ta phải thực hiện 3 phép tính trên ma trận (+ × + ). Người ta đã tìm ra cách biểu diễn trong hệ tọa độ thuần nhất, nhờ đó rút gọn chuỗi biến đổi trên về chỉ một phép tính.

4.1.3 Hệ tọa độ thuần nhất (homogeneous coordinates) Tọa độ thuần nhất (đôi khi còn gọi là “đồng nhất”) của điểm (x,y) trên mặt phẳng được biểu diễn bằng bộ ba (xh,yh,h) liên hệ với tọa độ (x,y) bởi công thức

x=

xh , h

y=

yh h

Nếu một điểm có tọa độ thuần nhất là (x,y,z) trong không gian Decac thì nó cũng có tọa độ thuần nhất là (x.h,y.h,z.h) trong đó h là số thực khác không bất kỳ. Ngược lại điểm (x,y,z) trong hệ tọa độ thuần nhất sẽ có tương ứng với điểm (x/z,y/z) trong hệ tọa độ Decac. Tọa độ thuần nhất của một điểm trong không gian 3 chiều hay nhiều chiều cũng được xác định theo cách tương tự. Để đơn giản hóa, người ta thường chọn h=1, lúc này điểm P(x,y) sẽ được biểu diễn dưới dạng tọa độ thuần nhất là (x,y,1)
4.1.4 Ma trận của các phép biến hình trong hệ tọa độ thuần nhất Phép tịnh tiến:

⎛ 1 0 0⎞ ⎜ ⎟ (x*, y*,1) = (x, y,1) × ⎜ 0 1 0 ⎟ ⎜ a b 1⎟ ⎝ ⎠ ⎛ 1 0 0⎞ ⎟ ⎜ Hay Q = P × T trong đó T là ma trận của phép tịnh tiến T = ⎜ 0 1 0 ⎟ ⎜ a b 1⎟ ⎠ ⎝
Phép tỷ lệ:

⎛ tx 0 0 ⎞ ⎜ ⎟ (x*, y*,1) = (x, y,1) × ⎜ 0 ty 0 ⎟ ⎜ 0 0 1⎟ ⎝ ⎠
⎛ tx 0 0 ⎞ ⎜ ⎟ Hay Q = P × S trong đó S là ma trận của phép tỷ lệ S = ⎜ 0 ty 0 ⎟ ⎜ 0 0 1⎟ ⎝ ⎠
Phép quay quanh gốc tọa độ:

http://www.ebook.edu.vn

4

⎛ cos α ⎜ (x*, y*,1) = (x, y,1) × ⎜ − sin α ⎜ 0 ⎝

sin α cos α 0

0⎞ ⎟ 0⎟ 1⎟ ⎠
sin α cos α 0 0⎞ ⎟ 0⎟ 1⎟ ⎠

⎛ cos α ⎜ Hay Q = P × R trong đó R là ma trận của phép quay R = ⎜ − sin α ⎜ 0 ⎝

4.1.5 Kết hợp các phép biến hình Bất kỳ phép biến hình nào cũng được kết hợp từ phép tịnh tiến, tỷ lệ và quay. Khi áp dụng liên tiếp các phép biến hình trên đối tượng, ta phải thực hiện nhiều phép nhân với các ma trận tương ứng. Thay vào đó, ta sẽ chuẩn bị sẵn ma trận tích và sử dụng như ma trận của phép biến hình tổng thể. Kết hợp các phép tịnh tiến

Ta thực hiện phép tịnh tiến T1 với vector tịnh tiến (a,b) lên điểm P(x,y) và thu được ảnh Q’, sau đó thực hiện tiếp phép tịnh tiến T2(c,d) đối với Q’ và thu được Q(x*,y*)

P ( x, y ) ⎯T1 ( a⎯→ Q ' ( x' , y ' ) ⎯T2 ( c⎯→ Q ( x*, y*) ⎯ ,b ) ⎯ ,d )
Kết hợp của 2 hay nhiều phép tịnh tiến cho kết quả là phép tịnh tiến có ma trận là tổng các ma trận hành phần:

T1 (a, b).T2 (c, d ) = T (a + c, b + d ) 0 ⎛ 1 0 0⎞ ⎛1 0 0⎞ ⎛ 1 ⎜ ⎟ ⎜ ⎟ ⎜ 1 ⎜ 0 1 0⎟ × ⎜ 0 1 0⎟ = ⎜ 0 ⎜ a b 1⎟ ⎜ c d 1⎟ ⎜ a + c b + d ⎝ ⎠ ⎝ ⎠ ⎝ 0⎞ ⎟ 0⎟ 1⎟ ⎠

Kết hợp các phép tỷ lệ Tương tự như phép tịnh tiến, kết hợp của nhiều phép tỷ lệ là một phép tỷ lệ. Giả sử ta kết hợp hai phép tỷ lệ sau: S = S1. S2 Ma trận kết hợp sẽ là

⎛ tx1 0 ⎜ ⎜ 0 ty1 ⎜0 0 ⎝
Kết hợp các phép quay

0 ⎞ ⎛ tx 2 ⎟ ⎜ 0⎟ × ⎜ 0 1⎟ ⎜ 0 ⎠ ⎝

0 ty1 0

0 ⎞ ⎛ tx1tx 2 ⎟ ⎜ 0⎟ = ⎜ 0 1⎟ ⎜ 0 ⎠ ⎝

0 ty1ty 2 0

0⎞ ⎟ 0⎟ 1⎟ ⎠

http://www.ebook.edu.vn

5

Tương tự như phép tịnh tiến, kết hợp của nhiều phép quay quanh gốc tọa độ cũng là một phép quay quanh gốc tọa độ. Giả sử phép quay R1có góc quay là α1, phép quay R2 có góc quay α2, ma trận kết hợp của hai phép quay R1. R2 là ⎛ cos α 1 sin α 1 0 ⎞ ⎛ cos α 2 sin α 2 0 ⎞ ⎛ cos(α 1 + α 2 ) sin (α 1 + α 2 ) 0 ⎞ ⎟ ⎟ ⎜ ⎟ ⎜ ⎜ ⎜ − sin α 1 cos α 1 0 ⎟ × ⎜ − sin α 2 cos α 2 0 ⎟ = ⎜ − sin (α 1 + α 2 ) cos(α 1 + α 2 ) 0 ⎟ ⎜ 0 0 1⎟ ⎜ 0 0 1⎟ ⎜ 0 0 1⎟ ⎠ ⎠ ⎝ ⎠ ⎝ ⎝
Phép quay với tâm quay bất kỳ Phép quay quanh tâm quay A(x,y) góc quay α có thể phân tích thành các phép biến hình cơ sở sau: - Tịnh tiến theo vector (-x,-y) để đưa tâm quay về gốc tọa độ - Quay quanh gốc tọa độ một góc α - Tịnh tiến theo vector (x,y) để đưa đối tượng về chỗ cũ

0 0 ⎞ ⎛ cos α sin α 0 ⎞ ⎛ 1 0 0 ⎞ ⎛ 1 ⎜ ⎟ ⎜ ⎟ ⎜ ⎟ 1 0 ⎟ × ⎜ − sin α cos α 0 ⎟ × ⎜ 0 1 0 ⎟ = ⎜ 0 ⎜ − x − y 1⎟ ⎜ 0 0 1⎟ ⎜ x y 1⎟ ⎝ ⎠ ⎝ ⎠ ⎝ ⎠ cos α sin α 0⎞ ⎛ ⎜ ⎟ =⎜ − sin α cos α 0⎟ ⎜ x(1 − cos α ) + y. sin α − sin α .x + (1 − cos α ) y 1 ⎟ ⎝ ⎠
Phép đối xứng Phép đối xứng trục có thể xem là phép quay 1800 quanh trục đối xứng. Phép đối xứng qua trục hoành và trục tung có ma trận lần lượt là ⎛1 0 0⎞ ⎛ −1 0 0⎞ ⎜ ⎟ ⎜ ⎟ M Ox = ⎜ 0 − 1 0 ⎟ , M Oy = ⎜ 0 1 0 ⎟ ⎜0 0 1⎟ ⎜ 0 0 1⎟ ⎝ ⎠ ⎝ ⎠ Phép biến dạng Là phép biến hình làm thay đổi tỷ lệ về kích thước, nói cách khác là làm méo mó đối tượng. Hai phép biến dạng là: - Phép biến dạng theo trục hoành làm thay đổi hoành độ còn tung độ giữ nguyên - Phép biến dạng theo trục tung làm thay đổi tung độ còn hoành độ giữ nguyên

M Ox

⎛1 t 0⎞ ⎛1 0 0⎞ ⎟ ⎟ ⎜ ⎜ = ⎜ t 1 0 ⎟ , M Oy = ⎜ 0 1 0 ⎟ ⎜0 0 1⎟ ⎜0 0 1⎟ ⎠ ⎠ ⎝ ⎝

http://www.ebook.edu.vn

6

(1,3)

(3,3)

(10,3)

(12,3)

(1,1) (3,1)

(4,1)

(6,1)

Phép biến dạng theo trục Ox, hệ số biến dạng t =3 Phép biến đổi ngược Một ví dụ cho phép biến đổi ngược chính là thao tác Undo mà các phần mềm vẽ thiết kế luôn có. Giả sử phép biến hình M có ma trận như sau:

⎛a ⎜ M = ⎜c ⎜e ⎝

b d f

0⎞ ⎟ 0⎟ 1⎟ ⎠

giả thiết ad-bc ≠ 0. Khi đó phép biến đổi ngược của M, ký hiệu là M-1, được biểu diễn như sau:

M

−1

Gọi S (tx,ty) là phép đồng dạng, S-1 được biểu diễn như sau:

−b ⎛ d 1 ⎜ = a ⎜ −c ad − bc ⎜ ⎝ cf − de be − af
⎛1 ⎜ ⎜ tx S −1 (tx, ty ) = ⎜ 0 ⎜ ⎜0 ⎜ ⎝ ⎞ 0⎟ ⎟ 0⎟ ⎟ 1⎟ ⎟ ⎠

0⎞ ⎟ 0⎟ 1⎟ ⎠

0 1 ty 0

Phép quay quanh gốc tọa độ R(α) có biến đổi ngược như sau:

⎛ cos α ⎜ R −1 (α ) = ⎜ sin α ⎜ 0 ⎝

− sin α cos α 0

0⎞ ⎟ 0 ⎟ = R(−α ) 1⎟ ⎠

4.2. Các phép biến hình trong không gian 3 chiều
Hoàn toàn tương tự như trong mặt phẳng, ta cũng sử dụng các ma trận trong hệ tọa độ thuần nhất để biểu diễn các phép biến hình: tịnh tiến, quay và đồng dạng.
Phép tịnh tiến Ma trận của phép tịnh tiến T(a,b,c) là

http://www.ebook.edu.vn

7

⎛1 ⎜ ⎜0 T (a, b, c) = ⎜ 0 ⎜ ⎜a ⎝
Phép tỷ lệ Ma trận của phép tỷ lệ S(a,b,c) là

0 0 0⎞ ⎟ 1 0 0⎟ 0 1 0⎟ ⎟ b c 1⎟ ⎠

⎛ a 0 0 0⎞ ⎜ ⎟ ⎜ 0 b 0 0⎟ S (a, b, c) = ⎜ 0 0 c 0⎟ ⎜ ⎟ ⎜ 0 0 0 1⎟ ⎝ ⎠ trong đó a,b,c là hệ số tỷ lệ tương ứng theo các trục tọa độ Ox,Oy,Oz

y

y

x z
Phép tỷ lệ

x z
Phép tịnh tiến

Phép quay Nếu trong mặt phẳng ta có phép quay quanh một tâm quay thì trong không gian 3 chiều ta có phép quay quanh một trục. Ký hiệu ma trận của các phép quay quanh 3 trục Ox, Oy, Oz lần lượt là R(x,α), R(y,α), R(z,α) với α là góc quay. Ta có

http://www.ebook.edu.vn

8

⎛ cos α sin α 0 0 ⎞ ⎟ ⎜ ⎜ − sin α cos α 0 0 ⎟ R( z, α ) = ⎜ 0 0 1 0⎟ ⎟ ⎜ ⎜ 0 0 0 1⎟ ⎠ ⎝ ⎛ cos α 0 − sin α ⎜ 1 0 ⎜ 0 R( y, α ) = ⎜ sin α 0 cos α ⎜ ⎜ 0 0 0 ⎝

0⎞ ⎟ 0⎟ 0⎟ ⎟ 1⎟ ⎠

0 ⎛1 ⎜ ⎜ 0 cos α R ( x, α ) = ⎜ 0 − sin α ⎜ ⎜0 0 ⎝

0 sin α cos α 0

0⎞ ⎟ 0⎟ 0⎟ ⎟ 1⎟ ⎠

y

y

x z
Phép quay quanh trục Oy

z

x

Phép quay quanh trục Ox

y

x z
Phép quay quanh trục Oz

Chú ý: vẫn như trước, góc quay α có giá trị đại số. Chiều quay dương được xác định theo quy tắc như sau: http://www.ebook.edu.vn 9

- Quay quanh trục Ox: chiều quay dương là chiều quay từ trục y đến trục z - Quay quanh trục Oy: chiều quay dương là chiều quay từ trục z đến trục x - Quay quanh trục Oz: chiều quay dương là chiều quay từ trục x đến trục y Nói cách khác, nếu đặt mắt nhìn thẳng vào trục tọa độ đi tới thì chiều quay dương là ngược chiều kim đồng hồ. Hoặc có thể dùng quy tắc bàn tay phải: ngón cái chỉ chiều đi tới (vector pháp tuyến), bốn ngón khum lại chỉ chiều quay dương.

y + x z Xác định chiều quay dương x z y +

http://www.ebook.edu.vn

10

Chương V. Thư viện đồ họa 2D, 3D
Trong chương này chúng ta sẽ khảo sát thư viện đồ họa lấy từ cuốn “GRAPHICSME DANS LE PLAN ET DANS L’ESPACE AVEC TURBO PASCAL”, R.DONY, 1990.
1. Nguyên tắc thiết kế của thư viện 1. Chúng ta sẽ xây dựng những công cụ chuyển đổi từ hệ tọa độ Toán học (hệ Decac thuận, tọa độ là số thực không giới hạn) sang hệ tọa độ màn hình (hệ Decac ngược, tọa độ là số nguyên). Bộ công cụ đó gồm các thủ tục sau: Thủ tục Procedure CAT( ) Chức năng

Procedure CUASO( ) Procedure TAMNHIN( )

- đảo tung độ y, - chiếu “cửa sổ” lên màn hình, - cắt những phần nằm ngoài phạm vi cửa sổ thiết lập nên “cửa sổ” thiết lập nên “tầm nhìn”

2. Sau khi đã có bộ công cụ chuyển tọa độ trên, các lệnh vẽ về sau đều coi như đang vẽ trên hệ tọa độ Toán học quen thuộc. Việc biến đổi về hệ tọa độ màn hình và hiển thị được thực hiện tự động bởi các công cụ đã có. 3. Đoạn thẳng được chọn làm nguyên thể đồ họa. Mọi đối tượng hình học khác đều được xây dựng từ đoạn thẳng, chẳng hạn một điểm được vẽ như một đoạn thẳng với 2 đầu mút trùng nhau, các đường cong được vẽ bằng một loạt đoạn thẳng ngắn liên tiếp nhau, đường tròn được xấp xỉ hóa bởi một đa giác đều nhiều cạnh ...
2. Khái niệm cửa sổ, tầm nhìn Về lý thuyết, không gian 2D thực tế là vô hạn nhưng con người không thể bao quát hết mà thường chỉ quan tâm tới một vùng nào đó. Cửa sổ được định nghĩa là hình chữ nhật chứa những đối tượng đang được khảo sát. Chẳng hạn nhìn lên một bức tranh tường, ta chú ý vào một họa tiết nào đó, khi đó cửa sổ là hình chữ nhật nhỏ nhất có thể chứa nó. Khi chuyển sự chú ý sang những phần khác, cửa sổ sẽ được di chuyển theo. Thủ tục tiết lập cửa sổ như sau: CuaSo (F1,F2,F3,F4: Real) Trong đó F1, F2, F3, F4 là tọa độ các đỉnh cửa sổ (hình vẽ) và phải thỏa mãn: F1 < F2, F3 < F4 PROCEDURE Cuaso (F1,F2,F3,F4 : Real); BEGIN XgFen := F1; {Hoanh do trai} XdFen := F2; {Hoanh do phai} YbFen := F3; {Tung do duoi} YhFen := F4 {Tung do tren} END;

Ví dụ ta gọi thủ tục sau để thiết lập cửa sổ vuông: CuaSo (13.5, 22, 18.5, 27);

http://www.ebook.edu.vn

11

YhFen F4

Cửa sổ
YbFen F3

XgFen F1

XdFen F2

Hình ảnh mà ta đang khảo sát trên cửa sổ phải được thể hiện lên màn hình máy tính. Không phải lúc nào ta cũng dùng toàn bộ màn hình mà thường chia thành nhiều vùng, mỗi vùng cho một mục đích, để hiển thị một cửa sổ khác nhau. Ta gọi vùng màn hình đó là tầm nhìn của cửa sổ tương ứng.

YhClot C4

Tầm nhìn
YbClot C3

XgClot C1

XdClot C2

Thủ tục thiết lập tầm nhìn như sau: TamNhin (C1, C2, C3, C4: Integer) trong đó 0≤ C1 < C2 ≤ GetMaxX 0≤ C3 < C4 ≤ GetMaxY PROCEDURE TamNhin (C1,C2,C3,C4 : Integer); BEGIN {Có đổi chiều trục Y } XgClot := C1; {Hoành độ trái} XdClot := C2; {Hoành độ phải} YbClot := C3; {Tung độ dưới} http://www.ebook.edu.vn 12

YhClot := C4; {Tung độ trên} Xtl := (XdClot - XgClot) / (XdFen - XgFen); {tỷ lệ chiều ngang} Ytl := (YhClot - YbClot) / (YhFen - YbFen); {tỷ lệ chiều dọc} SetviewPort (XgClot, MaxY-YhClot, XdClot, MaxY-YbClot, ClipOn) {không vẽ ra ngoài} END; Ví dụ: để thiết lập chế độ làm việc toàn màn hình ta gọi thủ tục PROCEDURE TamNhinDay; {tầm nhìn đầy} BEGIN TamNhin (0,MaxX,0,MaxY) {Tầm nhìn là toàn bộ màn hình} END;
3. Đoạn thẳng, điểm

Đ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) để thao 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;
4. 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ó: Xe = (Xr-F1). Xtl; Ye = (F4-Yr). Ytl Ví dụ: Xét cửa sổ (-3,3,-2,3), tầm nhìn (100,700,50,300) http://www.ebook.edu.vn 13

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;

F4
Cửa sổ (Xr,Yr)

C4
Tầm nhìn

(Xe,Ye) C3 C1 F3 F1 C2

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

Méo hình: B/H ≠ B’/H’

H

H’

B B’
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:

http://www.ebook.edu.vn

14

• 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

Cửa sổ

Cửa sổ

Tầm nhìn

Tầm nhìn

Vấn đề Clipping (cắt bỏ những phần không nằm trong cửa sổ) Vấn đề đặt ra là cần phải cắt bỏ những phần của đối tượng không nằm trong cửa sổ. Vì ta đã coi đoạn thẳng là nguyên thể đồ họa nên vấn đề quy về việc làm sao để clipping một đoạn thẳng. Sau đây ta áp dụng thuật toán Cohen – Sutherland để giải quyết vấn đề này. Trước hết xét một điểm (X,Y). Nếu tọa độ của nó vi phạm một trong các điều kiện sau thì điểm đó nằm ngoài cửa sổ và sẽ bị loại bỏ F1≤ X ≤ F2 và F3≤ Y ≤ F4 Dấu bằng cho thấy các điểm nằm trên biên được coi như nằm trong cửa sổ. Với đoạn thẳng, ta kéo dài các đường biên cửa sổ thành các đường thẳng. Chúng chia mặt phẳng làm 9 vùng. Mỗi điểm trong mặt phẳng sẽ tương ứng với mã 4 bit được xác định theo quy tắc sau: • bit thứ 1 là 1 nếu điểm đó nằm bên trái cửa sổ • bit thứ 2 là 1 nếu điểm đó nằm bên phải cửa sổ

http://www.ebook.edu.vn

15

• bit thứ 3 là 1 nếu điểm đó nằm bên dưới cửa sổ • bit thứ 4 là 1 nếu điểm đó nằm bên trên cửa sổ 1001 1000 Cửa sổ 0001 0000 0010 1010

0101

0100

0110

Nhận xét; • Đoạn thẳng nằm hoàn toàn trong cửa sổ khi và chỉ khi mã của cả 2 đầu mút là 0000. Ngược lại, nếu một trong hai mã khác 0000 thì đoạn thẳng có 1 phần hoặc toàn bộ nằm ngoài cửa sổ • Nếu kết quả phép AND hai mã của 2 đầu mút khác 0000 thì đoạn thẳng tương ứng hoàn toàn nằm ngoài cửa sổ và sẽ không được hiển thị lên màn hình.

1001 a

1000 b c m

1010

0001 g h i e

0000

d

0010 j 0110

0101

0100

f

n

Các bước: - Nếu cả hai mã thuộc tính đều là 0000 thì đoạn thẳng hoàn toàn nằm trong cửa sổ - Nếu kết quả phép AND hai mã khác 0000 thì đoạn thẳng hoàn toàn nằm ngoài cửa sổ - Trường hợp không rơi vào hai khả năng trên: giao điểm của đoạn thẳng với biên cửa sổ chia đoạn thẳng đã cho thành nhiều đoạn. Ta xét từng đoạn theo cách như trên. Toàn bộ các bước kể trên được thể hiện trong thủ tục CAT dưới đây: http://www.ebook.edu.vn 16

PROCEDURE Cat (X1,Y1,X2,Y2 : Real); TYPE Region = (Left,Right,Low,High); Code = SET OF Region; VAR C,C1,C2 : Code; X,Y : Real; XX1,YY1 : Integer; XX2,YY2 : Integer; PROCEDURE MaNhiPhan (X,Y : Real; VAR C : Code); {Tạo mã thuộc tính cho 2 đầu, xây dựng tập C của điểm (X,Y)} BEGIN C := []; IF X < XgFen THEN C := [Left] {nằm bên trái đường thẳng X=XgFen} ELSE IF X > XdFen THEN C := [Right]; IF Y < YbFen THEN C := C+[Low] ELSE IF Y > YhFen THEN C := C+[High] END; {MaNhiPhan} BEGIN MaNhiPhan (X1,Y1,C1); MaNhiPhan (X2,Y2,C2); WHILE (C1 <> []) OR (C2 <> []) DO {chừng nào ít nhất 1 trong 2 điểm còn nằm ngoài cửa sổ } BEGIN {Cắt dần để tìm đoạn hiển thị} IF (C1*C2) <> [] THEN Exit; {C1∩C2 ≠∅: cắt toàn bộ} IF C1 = [] THEN C := C2 ELSE C := C1; {chọn C là điểm nằm ngoài} IF Left IN C THEN BEGIN {tìm giao điểm (X,Y) với dt X=XgFen} X := XgFen; Y := Y1+(Y2-Y1)*(XgFen-X1)/(X2-X1) END ELSE IF Right IN C THEN {tìm giao điểm (X,Y) với dt X=XdFen} BEGIN X := XdFen; Y := Y1+(Y2-Y1)*(XdFen-X1)/(X2-X1) END ELSE IF Low IN C THEN BEGIN Y := YbFen; X := X1+(X2-X1)*(YbFen-Y1)/(Y2-Y1) END ELSE IF High IN C THEN BEGIN http://www.ebook.edu.vn 17

Y := YhFen; X := X1+(X2-X1)*(YhFen-Y1)/(Y2-Y1) END; IF C = C1 {X1,Y1 nằm ngoài cửa sổ} THEN BEGIN X1 := X; {gán giao điểm (X,Y) mới tìm được cho (X1,Y1)} Y1 := Y; MaNhiPhan (X,Y,C1) {tính lại tập C1} END ELSE BEGIN {X2,Y2 nằm ngoài cửa sổ } X2 := X; Y2 := Y; MaNhiPhan (X,Y,C2) END END; {While} XX1 := Round ((X1-XgFen)*Xtl); YY1 := Round ((YhFen-Y1)*Ytl); XX2 := Round ((X2-XgFen)*Xtl); YY2 := Round ((YhFen-Y2)*Ytl); MoveTo (XX1,YY1); LineTo (XX2,YY2) END;
5. Vẽ trục tọa độ Vị trí tương đối giữa hệ trục và cửa sổ có rất nhiều trường hợp. Ta quy ước chỉ vẽ trục một cách tương đối, không tính toán chính xác theo vị trí tuyệt đối, nói cách khác việc vẽ trục chỉ mang tính trang trí, mang lại cho người xem cảm giác về vị trí tương đối của đối tượng so với hệ trục. - Trục nào cắt cửa sổ thì để nguyên và vẽ lên tầm nhìn - Trục nào không cắt qua cửa sổ: tịnh tiến ép sát vào mép trái hoặc mép dưới cửa sổ - Trục nào vốn đã trùng với mép trái hoặc mép dưới cửa sổ thì để nguyên Như vậy cuối cùng hình dạng cửa sổ có kèm theo hệ trục tọa độ sẽ có một trong 4 dạng sau:

2 trục không cắt cửa sổ PROCEDURE Truc; CONST dX = 5; dY = 4;

2 trục đều cắt cửa sổ: để nguyên

trục Oy cắt cửa sổ: giữ nguyên

trục Ox cắt cửa sổ: giữ nguyên

http://www.ebook.edu.vn

18

PROCEDURE MuiTenTrenX; {giả sử lúc đầu con trỏ CP đã ở A} BEGIN {Ve mui ten tren truc X} MoveRel (-dX,dY); {kéo CP về B} LineRel (dX,-dY); {vẽ BA} MoveRel (-dX,-dY); {kéo CP về C} LineRel (dX,dY) {vẽ CA} END; C PROCEDURE MuiTenTrenY; BEGIN {Ve mui ten tren truc Y} MoveRel (-dY,dX); LineRel (dY,-dX); MoveRel (dY,dX); LineRel (-dY,-dX) END; B dX BEGIN IF (XgFen < 0) AND (XdFen > 0) THEN XOrig := 0 ELSE XOrig := XgFen; {mep trai} IF (YbFen < 0) AND (YhFen > 0) THEN YOrig := 0 ELSE YOrig := YbFen; {mep duoi} Diem (XgFen,YOrig); VeDen (XdFen,YOrig); {Ve truc X} MuiTenTrenX; Diem (XOrig,YbFen); VeDen (XOrig,YhFen); {Ve truc Y} MuiTenTrenY; END;

A dY

Vẽ vạch chia độ Khi vẽ trục tọa độ ta phải vẽ các vạch chia thể hiện độ đo trên các trục đó. Vấn đề là khoảng chia phải đi qua gốc tọa độ. hình sau minh họa một trường hợp vẽ sai vạch chia

Vẽ vạch chia sai

Vẽ vạch chia đúng

http://www.ebook.edu.vn

19

Các thủ tục sau đảm nhiệm việc vẽ các vạch chia độ trên trục tọa độ: • Procedure ChinhTrucX; • Procedure ChinhTrucY; • Procedure DoDo;
Đường viền và lưới Thủ tục Luoi() vẽ lưới ô vuông nhằm giúp người xem đánh giá vị trí tọa độ dễ dàng hơn. Thủ tục Vien() vẽ một đường viền bao quanh tầm nhìn PROCEDURE Vien (Mau : Byte); BEGIN SetColor (Mau); Diem (XgFen,YbFen); VeDen (XdFen,YbFen); VeDen (XdFen,YhFen); VeDen (XgFen,YhFen); VeDen (XgFen,YbFen) END;

PROCEDURE VeVien; BEGIN Vien (White) END; PROCEDURE XoaVien; BEGIN Vien (Black) END;
5. Vẽ đa giác Nếu đa giác có tọa độ nguyên ta dùng công cụ DrawPoly của Pascal để vẽ. Nếu tọa độ là số thực, ta sẽ dùng thủ tục DaGiac() với các tham số: - X,Y: bảng chứa các tọa độ đa giác - Lim: số đỉnh của đa giác - Mode: giá trị boolean chỉ thị vẽ đa giác kín hay mở PROCEDURE DaGiac (X,Y : Table; Lim : Integer; Mode : Integer); VAR I : Integer; BEGIN Diem(X[1],Y[1]); FOR I := 2 TO Lim DO VeDen(X[I],Y[I]); IF Mode = Dong THEN VeDen(X[1],Y[1]) {Net cuoi} END;

PROCEDURE VeDaGiac (X,Y : Table; Lim : Integer; Mode : Integer); BEGIN SetColor(White); DaGiac(X,Y,Lim,Mode) END; http://www.ebook.edu.vn 20

PROCEDURE XoaDaGiac(X,Y : Table; Lim : Integer; Mode : Integer); BEGIN SetColor(Black); DaGiac(X,Y,Lim,Mode) END;
5. Vẽ đường tròn Ta xấp xỉ hóa đường tròn bằng một đa giác đều có số cạnh đủ lớn (72). Gọi (XC,YC) là tâm đường tròn, R là bán kính. Gọi Da là góc giữa 2 đỉnh liên tiếp, (Xn, Yn) là đỉnh thứ n. Có 2 cách để tính tọa độ các đỉnh. Cách trực tiếp:

⎧ X n+1 = R. cos(n.Da ) ⎨ ⎩Yn+1 = R. sin (n.Da )

(1)

Cách 2: tọa độ đỉnh thứ n là

⎧ X n = R. cos(a ) ⎨ ⎩Yn = R. sin (a )

với a là góc ở tâm tương ứng. Ta có ⎧ X n +1 = R. cos(a + Da) ⎧ X n +1 = R. cos(a) cos( Da) − R. sin(a) sin( Da) ⇒⎨ ⎨ ⎩Yn +1 = R. sin (a + Da ) ⎩Yn +1 = R. sin(a) cos( Da) + R. cos(a). sin( Da) cuối cùng ta có:

⎧ X n+1 = X n . cos( Da) − Yn .sin( Da) ⎨ ⎩Yn+1 = Yn . cos( Da) + X n .sin( Da)

(2)

Phương pháp (1) tốn 2 phép nhân và 2 phép sin/cos cho mỗi đỉnh. Phương pháp (2) tốn 4 phép nhân và 2 phép ±. Lưu ý là máy tính phải dùng công thức Taylo để tính sin/cos x2 x4 x6 + − ... cos( x) = 1 − 2! 4! 6! PROCEDURE VeTron (XC,YC,R : Real; Cham : Boolean); VAR S,C,X,Y,Aux : Real; N : Integer; BEGIN S := Sin(Pi/36); {Da=Pi/36} C := Cos(Pi/36); X := XC+R; Y := YC; Diem(X,Y); FOR N := 2 TO 73 DO BEGIN Aux := XC+(X-XC)*C-(Y-YC)*S; Y := YC+(X-XC)*S+(Y-YC)*C; X := Aux; IF Cham THEN Diem(X,Y); http://www.ebook.edu.vn 21

VeDen(X,Y) END END; Sau đây là một số chương trình ứng dụng thư viện DOHOA để vẽ các đường trong mặt phẳng.
6. Vẽ hình Bolygone Xét đường tròn đơn vị (bán kính bằng 1, tâm ở gốc tọa độ). Hình Bolygone bậc N gia số góc a là tập các dây cung nối các điểm sau:

Điểm đầu 00 a0 (2a)0 (3a)0 ...

Điểm cuối 00 (N.a)0 (N.2a)0 (N.3a)0 ...

1000 800 120 1600 2000
0

600 400 200 00

Bolygone bậc 2, gia số góc 200

Bolygone bậc 184, gia số góc 10

http://www.ebook.edu.vn

22

Bolygone bậc 192, gia số góc 10

Phương trình đường tròn bán kính R, tâm ở gốc tọa độ là: X = R.Cos(α) Y=R.Sin(α) với đường tròn đơn vị (R=1) ta có X=cos(α) Y=sin(α). Khi đó chương trình vẽ Bolygone như sau: PROGRAM Bolygone; USES Crt,Dohoa; VAR Ordre, Pas : Integer; ADeg,ARad : Real; F1,F2,F3,F4 : Real; C1,C2,C3,C4 : Integer; PROCEDURE NhapSoLieu; BEGIN ClrScr; Write ('Gõ số nguyên chỉ bậc (2,3,5 ...): gõ 0 để kết thúc'); Readln (Ordre); Writeln; IF Ordre <> 0 THEN BEGIN Write ('Cho gia số góc (1,3,5,7,11 ... ): '); ReadLn (Pas);{ Write ('Cho toa do cua so (F1,F2,F3,F4): '); ReadLn (F1,F2,F3,F4); Write ('Gõ tọa độ tầm nhìn (C1,C2,C3,C4): '); ReadLn (C1,C2,C3,C4);} F1:=-1;F2:=1; F3:=-1;F4:=1; http://www.ebook.edu.vn 23

C1:=100;C2:=540;C3:=20;C4:=460; END END; PROCEDURE VeBolygone (Ordre,Pas : Integer); BEGIN ADeg := 0; REPEAT ARad := Pi*ADeg/180; Diem (Cos(ARad),Sin(ARad)); VeDen (Cos(Ordre*ARad),Sin(Ordre*ARad)); ADeg := ADeg+Pas; UNTIL ADeg > 360; {nếu tăng giới hạn 360 lên, chẳng hạn 3600, thì số dây cung sẽ tăng lên} END; BEGIN NhapSoLieu; WHILE Ordre <> 0 DO BEGIN MhDohoa; CuaSo (F1,F2,F3,F4); TamNhin (C1,C2,C3,C4); VeVien; VeBolygone (Ordre,Pas); Cho; MhVanBan; NhapSoLieu END END.
7. Vẽ các đường Cycloide

Định nghĩa: Đường Cycloide là đường cong được vẽ bởi một điểm của vòng tròn lăn không trượt trên một đường thẳng. Phương trình tham số của cycloide là: X=R.(T-sin(T)) Y=R.(1-cos(T)) Đường Epicycloide là đường cong được vẽ bởi một điểm của vòng tròn lăn không trượt bên ngoài một vòng tròn cố định khác. http://www.ebook.edu.vn 24

Đường Hypocycloide là đường cong được vẽ bởi một điểm của vòng tròn lăn không trượt bên trong một vòng tròn cố định khác.
⎧ ⎛ R1 + R2 ⎞ T⎟ ⎪ X = ( R1 + R2 ). cos(T ) − L.R2 cos⎜ ⎜ R ⎟ 2 ⎪ ⎝ ⎠ ⎨ ⎪Y = ( R + R ). sin(T ) − L.R sin ⎛ R1 + R2 T ⎞ ⎟ ⎜ 1 2 2 ⎟ ⎜ R ⎪ 2 ⎠ ⎝ ⎩

Trong đó: R1 là bán kính đường tròn cố định R2 là bán kính đường tròn di động T: góc tạo bởi trục Ox và đường nối tâm của vòng tròn di động với gốc tọa độ L là tham biến • L>1: đường cong giãn ra • L=1: đường cong bình thường • L<1: đường cong thu lại Ta thấy: • Nếu R2>0 ta nhận được đường Epicycloide • Nếu R2<0 ta nhận được đường Hypocycloide • Hình dáng đường cong tùy thuộc vào tỷ lệ Q=R1/R2. Nếu Q là số nguyên, đường cong gồm Q nhánh quay quanh đường cong cố định và không cắt nhau. • Nếu Q là phân số hữu tỷ, các nhánh sẽ cắt nhau. Sau hữu hạn nhánh điểm chuyển động sẽ quay về vị trí đầu. • Nếu Q là số vô tỷ, điểm chuyển động không bao giờ quay về vị trí xuất phát. PROGRAM Cycloide; USES Crt,Graph,DoHoa; VAR aux1,aux2,aux3 : Real; R1,R2,L : Real; rmax : Real; Chuky : Real; Sinh : Char; FUNCTION Fx (T : Real) : Real; BEGIN FX := aux1*Cos(t) - aux3*Cos(aux2*t) END; FUNCTION Fy (T : Real) : Real; BEGIN FY := aux1*Sin(t) - aux3*Sin(aux2*t) END; http://www.ebook.edu.vn 25

PROCEDURE Timtudongchuky; VAR Xdau,Ydau : Real; Xhien,Yhien : Real; deltaX,deltaY : Real; BEGIN chuky := 0; Xdau := Fx(0); Ydau := Fy(0); REPEAT chuky := chuky + 2*Pi; Xhien := Fx(chuky); Yhien := Fy(chuky); deltaX := Abs(Xhien-Xdau); deltaY := Abs(Yhien-Ydau); UNTIL ((deltaX<1E-6) and (deltaY<1E-6)) or (chuky>200*Pi) END; PROCEDURE Nhapdulieu; BEGIN Clrscr; Writeln ('CAC DUONG CYCLOIDE:'); Writeln ; Writeln (' R1 = ban kinh duong tron co dinh'); Writeln (' R2 = ban kinh duong tron di dong'); Writeln; Writeln (' Neu R2 > 0 ta co EPICYCLOIDE'); Writeln (' Neu R2 < 0 ta co HYPOCYCLOIDE'); Writeln; Writeln (' Neu L > 1 ta co duong cong keo dan'); Writeln (' Neu L = 1 ta co duong cong binh thuong'); Writeln (' Neu 0 < L < 1 ta co duong cong thu lai'); Writeln; Write ('Cho R1: '); Readln (R1); Write ('Cho R2: '); Readln (R2); REPEAT Write ('Cho L: '); Readln (L) UNTIL L >= 0; aux1 := R1 + R2; aux2 := (R1 + R2)/R2; aux3 := L*R2; Writeln; Write ('Co ve duong tron sinh khong? (C/K) '); Readln (Sinh) END; PROCEDURE Timcuaso; BEGIN rmax := 0; http://www.ebook.edu.vn 26

IF L >= 1 THEN rmax := R1 + R2 + Abs(L*R2) ELSE IF R2 > 0 THEN rmax := R1 + 2*R2 ELSE rmax := R1 END; PROCEDURE Veduongcong; VAR a,giaso : Real; BEGIN a := 0; giaso := Pi/48; Diem (Fx(0),Fy(0)); REPEAT a := a+giaso; VeDen (Fx(a),Fy(a)) UNTIL a >= chuky END; PROCEDURE Vongtronsinh; BEGIN Troncham (0,0,R1); Troncham (R1+R2,0,R2) END; PROCEDURE Trinhbaythambien; VAR s1,s2,s3,s4,s5 : string; BEGIN Str (R1:5:2,s1); Str (R2:5:2,s2); Str (L:5:2,s3); Str (chuky:8:5,s4); Str (rmax:8:5,s5); Tamnhin (0,maxX,0,11); OutTextXY (10,0,'R1 ='+s1+' R2 ='+s2+' L ='+s3 +' Chu ky ='+s4+' Rmax ='+s5) END; BEGIN Nhapdulieu; Timtudongchuky; Timcuaso; Mhdohoa; Cuaso (-rmax,rmax,-rmax,rmax); Tamnhin (0,maxX,0,maxY); Vevien; Tamnhin (140,580,15,345); IF upcase (sinh) = 'C' THEN Vongtronsinh; http://www.ebook.edu.vn 27

Veduongcong; Trinhbaythambien; Cho; MhVanban END.
7. Tổng hợp hai giao động điều hòa Phương trình tổng quát của giao động điều hòa là hàm Y=A.Sin(F.T) trong đó A là biên độ, F là tần số, F.T là pha. Ta sẽ lập trình vẽ đồ thị hai giao động Y1=A1.sin(F1.T) Y2=A2.sin(F2.T+D) với D là độ lệch pha giữa Y1 và Y2. Sau đó, trên cùng màn hình ta vẽ đồ thị giao động tổng hợp Y=Y1+Y2. Màn hình được chia thành 3 tầm nhìn dành cho 3 cửa sổ tương ứng: • CuaSo(0,2Pi,-A1,A1) để khảo sát giao động thứ nhất • CuaSo(0,2Pi,-A2,A2) để khảo sát giao động thứ hai • CuaSo(0,2Pi,-A1-A2,A1+A2) để khảo sát giao động tổng hợp

uses crt,Graph,dohoa; const pas=0.02; var f1,f2,a1,a2,D,B,P,X:real; cy:integer; { bề rộng cửa sổ 1,2 } PROCEDURE NhapSolieu; Begin clrscr; Writeln ('------------ TỔNG HỢP 2 GIAO ĐỘNG ------------'); GotoXY(1,10); Write('Giao động 1: biên độ, tần số'); readln(F1,A1); {có thể thử với: 5,1} GotoXY(1,14); Write('Giao động 2: biên độ, tần số, độ lệch pha (radian)'); readln(F2,A2,D); {có thể thử với:: 3, 1, 3.14} {thử với f1=f2, d=0: ⇒ độ lệch pha =0} End; FUNCTION Func1(X:real) : real; Begin Func1:=A1*sin(F1*x); End; FUNCTION Func2(X:real) : real; Begin Func2:=A2*sin(F2*x+D); End; FUNCTION FuncSum(X:real) : real; Begin FuncSum:=Func1(x)+Func2(x); End; http://www.ebook.edu.vn 28

PROCEDURE VeHam1; Begin Cuaso(0,2*pi,-A1,A1); TamNhin(10,getmaxX-10,3*cy,4*cy); Truc; DoDo(1,0); x:=0;mausac(white); Diem(x,Func1(x)); Repeat x:=x+Pas; Veden(x,func1(x)); Until x>=2*pi; End; PROCEDURE VeHam2; Begin Cuaso(0,2*pi,-A2,A2); TamNhin(10,getmaxX-10,2*cy,3*cy); Truc; DoDo(1,0); x:=0;mausac(Green); Diem(x,Func2(x)); Repeat x:=x+Pas; Veden(x,func2(x)); Until x>=2*pi; End; PROCEDURE VeHamTong; Begin Cuaso(0,2*pi,-A1-A2,A1+A2); TamNhin(10,getmaxX-10,0,2*cy); Truc; DoDo(1,0); x:=0;mausac(Magenta); Diem(x,FuncSum(x)); Repeat x:=x+Pas; Veden(x,FuncSum(x)); Until x>=2*pi; End; BEGIN NhapSolieu; Mhdohoa; cy:=getmaxY div 4; Veham1; Cho; Veham2; Cho; VehamTong;Cho; { TamnhinDay; http://www.ebook.edu.vn 29

Cho; } Mhvanban; END.

Chương VI. Hình học Fractal
I. Sự cần thiết của hình học Fractal Hình học là ngôn ngữ đặc biệt để mô phỏng tự nhiên, và hình học Euclide đã ngự trị một thời gian dài trong lĩnh vực mô tả, xử lý các hình dạng của tự nhiên. Tuy nhiên trong thế giới thực có một lớp hình dạng không dễ dàng được mô tả bởi hình học Euclide như: núi, mây, trời, biển ... Đặc tính của những đối tượng này là khi phóng to một phần chi tiết nào đó thì sẽ có được dạng lặp lại của toàn hình, đặc tính đó được gọi là tự tương tự (selfsimilarity). Hình học Fractal (viết tắt của Fractional – phân đoạn) ra đời để thích nghi với việc mô phỏng lớp hình dạng đó: lớp hình có đặc tính “Fractal” – tự tương tự. (Xem và chạy thử file fractal.exe) Đường cong Fractal không thể được mô tả như đường hai chiều thông thường, mặt Fractal không thể mô tả như mặt 3 chiều mà đối tượng Fractal có thêm chiều hữu tỷ. Mặc dù các đối tượng Fractal trong từng trường hợp cụ thể chỉ chứa một số hữu hạn chi tiết, nhưng nó chứa đựng bản chất cho phép mô tả vô hạn chi tiết, tức là tại một thời điểm xác định thì là hữu hạn, nhưng xét về tổng thể là vô hạn vì bản chất Fractal cho phép phóng đại lên một mức độ bất kỳ một chi tiết tùy ý. Hiện nay hình học Fractal và các khái niệm của nó đã trở thành công cụ trung tâm trong các lĩnh vực của khoa học tự nhiên như: vật lý, hóa học, sinh học, địa chất học, khí tượng học, khoa học vật liệu ... Để hiểu thế nào là hình học Fractal, ta hãy so sánh với hình học Euclide cổ điển
Hình học Euclide 1) Xuất hiện từ rất lâu, trên 2000 năm trước Hình học Fractal 1) Xuất hiện năm 1975 (năm nhà toán học Benoit Mandelbrot công bố công trình về tập Mandelbrot) 2) Không có kích thước xác định

2) Vật thể hình học Euclide có kích thước đặc trưng 3) Thích hợp với việc mô tả những thực thể được tạo ra bởi con người. 4) Được mô tả bởi công thức (phương trình tham số, phương trình bề mặt, quỹ đạo ...)

3) Thích hợp để mô tả những vật thể trong tự nhiên 4) Được mô tả bởi thuật toán lặp

Hình học Euclide cho sự mô tả gọn gàng, chính xác những vật thể được tạo bởi con người (khối lập phương, mặt trụ, mặt cầu ... ) nhưng không thích hợp khi dùng để mô tả những hình dạng tự nhiên vì đòi hỏi một khối lượng tính toán (số và bậc của phương trình, ố lượng biến ... ) rất cồng kềnh mà vẫn không chính xác. Còn sự mô tả của hình học Fractal (các thuật lặp) lại đặc biệt thích hợp với việc tạo sinh bằng máy tính. Thực thể Fractal là kết quả của một quá trình lặp theo một thuật toán xác định, được tạo sinh lý tưởng bằng máy tính và rất khó được tạo một cách thủ công. http://www.ebook.edu.vn 30

II Một số khái niệm cơ bản Các thực thể Fractal có 3 đặc tính quan trọng: • Tự tương tự (self-similarity) • Tự tương tự đa phần (statistical self-similarity) • Tự Affine Chúng ta chỉ khảo sát đặc tính đầu tiên và quan trọng nhất: đặc tính tự tương tự (selfsimilarity) Một thực thể có đặc tính tự tương tự nếu nó là hợp của N tập con không giao nhau, mỗi tập con được tạo sinh từ tập gốc qua các phép biến đổi như: co dãn, dịch chuyển, quay. Phát biểu một cách hình thức hơn, xét tập S gồm những điểm: x = (x1, x2, ... xE) trong không gian E chiều Dưới phép đồng dạng với hệ số co 0 < T < 1, tập S biến thành tập TS với những điểm: Tx = (Tx1, Tx2, ... TxE) Tập S là tự tương tự nếu S là hợp của N tập con không giao nhau, mỗi tập con tương đương với TA (có thể sai khác một phép tịnh tiến, quay hoặc vị tự). Khi đó số chiều của S được định nghĩa bởi log N D= 1 log T Tập S cũng được gọi là tự tương tự nếu các tập con được tạo sinh từ tập gốc theo các hệ số co Ti khác nhau. Trong trường hợp này số chiều D được tính từ công thức sau

∑T
i =1

N

D

i

=1

III Ví dụ minh họa Ta hãy xét một ví dụ minh họa tính tự tương tự của một thực thể Fractal kinh điển: đường Von-Koch. Đường Von- Koch (còn gọi là “Bông hoa tuyết Von-Koch” như trong Wikipedia) là một trong những đường Fractal được công bố sớm nhất, vào năm 1904 bởi nhà toán học Thụy Điển Helge Von Koch. Thuật toán lặp cho đường Von-Koch gồm những bước sau: a) Một đoạn thẳng cho trước được chia làm 3 phần bằng nhau b) Đoạn giữa được thay bởi 2 đoạn có chiều dài tương đương c) Mỗi đoạn trong số 4 đoạn này lại được thay bởi 4 đoạn mới có chiều dài bằng 1/3 đoạn trước d) Quá trình cứ thế lặp lại

http://www.ebook.edu.vn

31

a)

b)

c)

Đặc điểm của đường Von-Koch • Đường cong này có tính tự tương tự, mỗi phần nhỏ khi được phóng to có thể tạo sinh lại giống như phần lớn hơn, nói cách khác nó bất biến dưới sự phóng to hình. • Qua mỗi bước lặp, độ dài đường von-Koch tăng lên 4/3 lần • Đường cong (sau vô hạn bước) có độ dài vô hạn mặc dù nó chỉ chiếm một phần diện tích hữu hạn của mặt phẳng • Không tự cắt • Thuật toán tạo sinh đường Von-Koch khá đơn giản, nhưng không có công thức đại số để xác định những điểm trên đường cong • Số chiều của đường Von-Koch là hữu tỷ:
D= log(4) log N = ≈ 1,26... ⎛ 1 ⎞ log(3) log⎜ ⎟ ⎝T ⎠

http://www.ebook.edu.vn

32

D phản ánh mức độ lan tỏa của đường cong. Khi D biến thiên từ 1 đến 2, đường cong biến thiên từ đường thẳng lan dần đến lấp đầy mặt phẳng hơn.
Số bước lặp 1 2 3 4 5 6 ... 10 25 50 100 Độ dài phân đoạn 1 1/3 1/9 1/27 1/81 1/243 ... 1/19683 1/2.82e+11 1/2.39e+23 1/1.71e+47 Số phân đoạn Tổng chiều dài đường Koch 1 1.00 4 1.33 16 1.77 64 2.37 256 3.16 1024 4.21 ... ... 262144 13.31 2.81e+14 996.62 3.17e+29 1324335.72 4.02e+59 2338486807656.00

Chương trình vẽ đường Von-Koch

{ Vẽ 3 đường Von Koch giáp nhau tạo thành hình bông tuyết} Uses crt,graph; { hệ số đổi từ độ sang radian } Const RADS = 0.017453293; Var i,gd,gm:integer; temp:real; Procedure Koch(dir:integer; len:real; n:integer); http://www.ebook.edu.vn 33

Begin if (n>0) then begin Koch(dir, len / 3, n-1); dir := dir + 60; Koch(dir, len / 3, n-1); dir := dir - 120; Koch(dir, len / 3, n-1); dir := dir + 60; Koch(dir, len / 3, n-1); end else linerel(round(len * cos(RADS * dir)), round(len * sin(RADS * dir))); End; Begin gd:=detect; initgraph(gd,gm,''); for i:=1 to 4 do begin setcolor(White); rectangle(0, 0, getmaxx, getmaxy); moveto(100,350); Koch(0, 420 , i); setcolor(blue); Koch(-120, 420 , i); setcolor(yellow); Koch(120, 420 , i); readln; cleardevice; end; closegraph; End. Đường Hilbert do nhà toán họa Đức David Hilbert công bố năm 1891. Độ dài của nó tại bước lặp thứ n là

Ln = 2 n −
tức là độ dài tăng theo hàm mũ đối với n

1 2n

http://www.ebook.edu.vn

34

Cả 4 quy tắc (rules) thực chất chỉ là 1

Quay 900 thì như nhau

http://www.ebook.edu.vn

35

Chương trình vẽ đường Hilbert

{Vẽ các đường Hilbert} Uses Crt,Graph; Var gd,gm,h:integer; Procedure A (i:integer);FORWARD; Procedure B (i:integer);FORWARD; Procedure C (i:integer);FORWARD; Procedure D (i:integer);FORWARD; Procedure A(i:integer); Begin if (i>=0) then Begin D(i-1); linerel(-h, 0); A(i-1); linerel(0, -h); A(i-1); linerel(h, 0); B(i-1); End; End; Procedure B(i:integer); Begin if (i>=0) then Begin C(i-1); linerel(0, h); B(i-1); linerel(h, 0); B(i-1); linerel(0, -h); A(i-1); End; End; Procedure C(i:integer); Begin http://www.ebook.edu.vn 36

if (i>=0) then Begin B(i-1); linerel(h, 0); C(i-1); linerel(0, h); C(i-1); linerel(-h, 0); D(i-1); End; End; Procedure D(i:integer); Begin if (i>=0) then Begin A(i-1); linerel(0, -h); D(i-1); linerel(-h, 0); D(i-1); linerel(0, h); C(i-1); End; End; Procedure Hilbert; Var i:integer; Begin for i:=0 to 5 do begin h:= 30 - 5 * i; moveto(getmaxx - 130, getmaxy - 50); A(i); readln; cleardevice; end; End; Begin gd:=detect; initgraph(gd,gd,''); setcolor(YELLOW); rectangle(0, 0, getmaxx, getmaxy); Hilbert; closegraph; End.

http://www.ebook.edu.vn

37

Chương trình vẽ Nhân sư (Sphinx)

{ Vẽ con nhân sư Sphinx } Uses Crt,Graph; { hệ số đổi từ độ sang radian } Const RADS = 0.017453293; Var curangle,curx, cury:real; gd,gm:integer; Procedure lineforward(angle, length:real); Begin curangle :=curangle+ angle; curx := curx + length*cos(curangle*RADS); cury := cury + length*sin(curangle*RADS); lineto(round(curx), round(cury)); End; Procedure moveforward(angle,length:real); Begin curangle := curangle + angle; curx := curx + length*cos(curangle*RADS); cury := cury + length*sin(curangle*RADS); lineto(round(curx), round(cury)); End; http://www.ebook.edu.vn 38

Procedure Sphinx(angle, length: real; level,leftright:integer); Var len4, len2, len1, oldx, oldy, oldangle: real; Begin if (leftright<>0) then Begin if (level = 0) then begin len1 := length / 3; lineforward(angle, length); lineforward(-120,len1*2); lineforward(-120,len1); lineforward(+60,len1); lineforward(-60,len1); end else begin Sphinx(angle, length, 0, leftright); len4 := length / 4; Sphinx(240, len4, 0, 1); moveforward(240, len4); Sphinx(0, len4, 0, 1); moveforward(240, len4); Sphinx(0, len4, 0, 1); moveforward(240, len4); Sphinx(0, len4, 0, 1); moveforward(240, len4); moveforward(-120, len4*2/3); Sphinx(0, len4, 0, 0); moveforward(240, len4); Sphinx(0, len4, 0, 0); moveforward(-180, len4*2/3); Sphinx(-120, len4, 0, 0); moveforward(240, len4/3); Sphinx(-240, len4, 0, 1); moveforward(240, len4); Sphinx(0, len4, 0, 1); moveforward(240, len4); Sphinx(-60, len4, 0, 0); moveforward(-180, len4*2/3); lineforward(-60, len4); moveforward(60, len4/3); moveforward(-120, len4); Sphinx(-180, len4, 0, 0); end; end else begin http://www.ebook.edu.vn 39

if (level = 0) then begin len1 := length / 3; lineforward(angle, length); lineforward(-120,len1); lineforward(-60,len1); lineforward(60,len1); lineforward(-120,len1*2); end else begin Sphinx(angle, length, 0, leftright); len4 := length / 4; end; end; End; Begin curangle := 0.0; gd:=detect; initgraph(gd,gm,''); moveto(10, 470); curx := 10; cury := 470; Sphinx(0, 600, 1, 1); readln; closegraph; End.
Chương trình vẽ Phong cảnh (Fractal.exe)

Uses crt,graph; Const CLIP_ON = 1; Var n,c,t,mau:integer; hs,go:real; i,gd,gm:integer; ch:char; Function dau:integer; Begin if (random(2) = 0) then dau:= -1 else dau:= 1; End; Procedure cay(x,y:integer; h,g,gw:real; k:integer); http://www.ebook.edu.vn 40

Var x1,y1,i,j,d,leaf,c:integer; dg,tt:real; Begin if (k > 0) then for j:= 1 to (random(t) + t) do begin x1:= x + round(h * cos(g)); y1:= y + round(h * sin(g)); setcolor(DARKGRAY); for i:= 0 to round((h/35)*(h/35)) do begin line(x + i, y, x1 + i, y1); delay(10); {Ve cay cham de quan sat } for d:= 1 to round((h/5)) do begin tt:= random(1); putpixel(round((1-tt)*x+tt*x1+i), round((1-tt)*y+tt*y1), LIGHTGRAY); end; end; dg := gw/(2*n+1); for i:= -n to n do if (random(1000)*0.001 > 0.5) then cay(x1,y1,h*(0.5+(random(1000)*0.001)/3),g+i*dg,gw*hs,k-1); x := x1; y := y1; g := g + PI/18; end else begin setfillstyle(1,random(15)); setcolor(random(15)); for leaf:= 1 to 2 do fillellipse(x+random(8)*dau,y+random(5)*dau,random(5)+2,random(2)+1); for leaf:= 1 to 70 do begin case leaf of 0..20: begin putpixel(x+random(15)*dau,y+random(5)*dau,BLUE); break; end; 21..25: begin putpixel(x+random(15)*dau,y+random(5)*dau,LIGHTBLUE); break; end; http://www.ebook.edu.vn 41

26..49: begin putpixel(x+random(15)*dau,y+random(5)*dau,LIGHTGREEN); break; end; End; End; End; End; Procedure cloud(x,y:integer; Rx,Ry:real; k:integer); Var i:integer; Begin if (k > 0) then for i:= 1 to 5 do cloud(x+random(round(Rx)),y+random(round(Ry)),Rx*0.8,Ry*0.6,k-1) else for i:= 1 to round(sqrt(Rx*Ry)/3.5) do putpixel(x+random(round(Rx)),y+random(round(Ry)),WHITE); End; Procedure phong; Var l,i:integer; Begin l := (getmaxy div 7) * 5; mau:=random(15); setfillstyle(1,mau); bar(0,0,getmaxx,l); setfillstyle(1,LIGHTGRAY); bar(0,l,getmaxx,getmaxy); for i:= 1 to 20000-1 do case (random(8)) of 0..4: begin putpixel(random(getmaxx),l+random(getmaxy-l),GREEN); break; end; 5,6: begin putpixel(random(getmaxx),l+random(getmaxy-l),YELLOW); break; end; 7: begin putpixel(random(getmaxx),l+random(getmaxy-l),LIGHTRED); break; end; http://www.ebook.edu.vn 42

end; if (mau<>RED) then Begin if (mau<>BLACK) then begin setfillstyle(1,RED); setcolor(RED); end; end else begin setfillstyle(1,YELLOW); setcolor(YELLOW); end; fillellipse(random(getmaxx div 2)+300,100,30,30); for i:= 1 to 5 do cloud(random(getmaxx),random(150)+10,random(60)+60,random(40)+20,5); End; BEGIN randomize; gd:=detect; initgraph(gd,gm,''); setviewport(0,0,getmaxx,getmaxy,CLIPON); repeat n := 1; hs := 1.2; go := PI /2.8; t := 2; phong; cay(((getmaxx-100) div 5)+random(60),(getmaxy div 7)*6 +random(30)*dau,getmaxy div 6,-PI/2,go,5); ch:=readkey; until (ch=#27); closegraph; END.

http://www.ebook.edu.vn

43

Chương trình vẽ cây Pytago

{ Cây Pythagoras } Uses Crt,Graph; Const { 1 / sqrt(2) } FCT = 0.7071067; { he so doi tu do sang radian } RADS = 0.017453293; Var gd,gm:integer; Procedure quadrat(x,y,a,angle:real); Var cp,sp:real; Begin setcolor(RED); if (a < 35) then setcolor(2); if (a < 8) then setcolor(7); cp := a * cos(angle); sp := a * sin(angle); line(round(x), 200 - round(y), round(x + cp), 200 - round(y+sp)); line(round(x), 200 - round(y), round(x - cp), 200 - round(y+cp)); line(round(x+cp), 200 - round(y+sp), round(x - sp + cp), 200 - round(y+sp+cp)); line(round(x-sp), 200 - round(y+cp), round(x - sp + cp), 200 - round(y+sp+cp)); if (a > 2) then Begin quadrat(x - sp, y + cp, 3 * a / 5, angle + 0.93); quadrat(x - sp + 3 * a / 5 * cos(angle + 0.93), y + cp + 3 * a / 5 * sin (angle + 0.93), a * 4 / 5, angle - 0.64); http://www.ebook.edu.vn 44

End; End; Begin gd:=detect; initgraph(gd,gm,''); setcolor(7); quadrat(250, -120, 70, 0); readln; closegraph; End.

http://www.ebook.edu.vn

45

Sign up to vote on this title
UsefulNot useful