Chương III. 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 tồn đường thẳng: ảnh của đường thẳng qua phép biến hình affine là đường thẳng.
- Bảo tồ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
1
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
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 tồn tỷ lệ về kích thước của vật thể.
2
6
5
4
tx=ty=3
3
2
tx=3; ty=1
1
1
2
3 4 5 6
Phép tỷ lệ
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.
3
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ệ:
tx 0
( ,yx ** ) = (x,y)
0 ty
Q = P×S trong đó
tx 0
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*) = ( ,yx )
− sinα cosα
hay Q=P×R trong đó
cosα sinα
R =
− sinα cosα
là ma trận của phép quay
4
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 ngồ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
yh
h
y=
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
( x*, y*,1) = ( x, y,1) ×0
a
Hay Q = P × T trong đó T là ma trận của phép tịnh tiến
0
0
b 1
1 0
T = 0 1
a b
0
1
0
0
1
Phép tỷ lệ:
tx
( x*, y*,1) = ( x, y,1) × 0
0
Hay Q = P × S trong đó S là ma trận của phép tỷ lệ
0
0
1
0 0
ty 0
0 1
0
ty
0
tx
S =0
0
Phép quay quanh gốc tọa độ:
cos α
( x*, y*,1) = ( x, y,1) ×− sin α
0
Hay Q = P × R trong đó R là ma trận của phép quay
sin α
cos α
0
cos α
R = − sin α
0
0
0
1
sin α
cos α
0
0
0
1
5
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 ) T ( a→ Q' ( x' , y ' ) T ( 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:
1
2
T1 (a, b).T2 (c, d ) = T (a + c, b + d )
1
0
a
0
1
b
0 1
0 ×0
1 c
0
1
d
0 1
0 = 0
1 a + c
0
1
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
0
ty1
0
0 tx 2
0 × 0
1 0
0
ty1
0
0 tx1tx 2
0 = 0
1 0
0
ty1ty 2
0
0
0
1
Kết hợp các phép quay
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ũ
6
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à
M Ox
1
= 0
0
0
−1
0
0
0 ,
1
M Oy
−1
= 0
0
0
1
0
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 hồnh làm thay đổi hồnh độ cịn tung độ giữ nguyên
- Phép biến dạng theo trục tung làm thay đổi tung độ cịn hồnh độ giữ ngun
M Ox
(1,3)
1
= t
0
(3,3)
(1,1) (3,1)
0
1
0
0
0 ,
1
M Oy
(10,3)
(4,1)
1
= 0
0
t
1
0
0
0
1
(12,3)
(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ế ln
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:
7
M
−1
d
1
=
−c
ad − bc
cf − de
−b
a
be − af
0
0
1
-1
Gọi S (tx,ty) là phép đồng dạng, S được biểu diễn như sau:
1
tx
−1
S ( tx, ty ) = 0
0
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
Hồ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à
1
0
T ( a, b, c ) =
0
a
0
1
0
0
0
b
1
c
0
b
0
0
0
0
c
0
0
0
0
1
Phép tỷ lệ
Ma trận của phép tỷ lệ S(a,b,c) là
a
0
S ( a , b, c ) =
0
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
8
y
y
x
x
z
z
Phép tỷ lệ
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ó
cos α
− sin α
R( z, α ) =
0
0
cos α
0
R( y, α ) =
sin α
0
sin α
cos α
0
0
0
0
1
0
0
0
0
1
0
− sin α
1
0
0
0
cos α
0
0
0
0
1
1
0
R ( x, α ) =
0
0
0
0
cos α
− sin α
0
sin α
cos α
0
0
0
0
1
9
y
y
x
z
x
z
Phép quay quanh trục Oy
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:
- 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.
10
y
+
y
x
+
z
Xác định chiều quay dương
x
z
11
Chương IV. 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( )
Procedure CUASO( )
Procedure TAMNHIN( )
Chức năng
- đả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);
12
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 tồ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}
13
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 ngồi}
END;
Ví dụ: để thiết lập chế độ làm việc tồ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à tồ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 tố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)
Giả sử (Xr,Yr) = (1.5, 1)
14
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
C2
F3
F1
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 ngun 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:
15
• 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ổ
Tầm
nhìn
Cửa
sổ
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 ngồ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ổ
16
• 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
1010
Cửa sổ
0001
0010
0000
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 tồn bộ
nằm ngồ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
hồn tồn nằm ngồi cửa sổ và sẽ không được hiển thị lên màn hình.
1001
1000
a
1010
m
b
c
0001
0000
g
0010
e
h
0101
d
i
j
0100
0110
f
n
Các bước:
- Nếu cả hai mã thuộc tính đều là 0000 thì đoạn thẳng hồn tồ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:
17
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
ngồ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 ngồ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
18
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 tố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ì để ngun 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ì để ngun
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ổ
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
PROCEDURE Truc;
CONST dX = 5;
dY = 4;
19
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
20
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 ô vng 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 độ ngun 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;
21
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)
(1)
Yn+ 1 = R.sin( n.Da)
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)
( 2)
Yn+ 1 = Yn .cos(Da) + X n .sin(Da)
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
cos( x) = 1 −
x2 x4 x6
+
−
...
2!
4!
6!
PROCEDURE VeTron (XC,YC,R : Real; Cham : Boolean);
VAR
S,C,X,Y,Aux : Real;
N
: Integer;
BEGIN
22
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);
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
0
0
a0
(2a)0
(3a)0
...
1000 800
0
120
1600
2000
Điểm cuối
0
0
(N.a)0
(N.2a)0
(N.3a)0
...
600
400
200
00
Bolygone bậc 2, gia số góc 200
23
Bolygone bậc
184, gia số góc
10
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;
24
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;
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
25