Tải bản đầy đủ (.ppt) (40 trang)

Bài giảng Chương 10: Các giải thuật nâng cao

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (240.84 KB, 40 trang )

Chương 10:
Các giải thuật nâng cao


Scan conversion
ª

ª

Scan conversion: q trình biểu diễn một đối tượng hình
học (đoạn thẳng, vịng trịn,...) trong bộ đệm ảnh đơn
(frame buffer) của hệ thống đồ họa quét raster.
vận hành (drive) the frame buffer thông qua các thủ tục
– SetPixel(⋅ )
– GetPixel(⋅ )


Frame buffer và thiết bị hiển thị
ª

Mơ hình chức năng của frame buffer
C

y

B

R
làm tươi ảnh
x


• B=1
•(value=0) => (pixel off) black
•(value=1) => (pixel on) white

Màn hình


Truy cập vào frame buffer
ª

Mơ hình lập trình
– Mơ hình cho frame buffer
– Các thao tác lên frame buffer.
const
{một ví duï}
MaxColumn = 639; {= C - 1}
MaxRow
MaxRow
= 479; {= R - 1}
MaxColor = 255; {= số các màu - 1}
type
2
col
= 0..MaxColumn;
1
0
row = 0..MaxRow;
0 1 2
MaxColumn
color = 0..MaxColor;

procedure SetPixel(c : col, r : row, value : color); {load frame

buffer}
function

GetPixel(c : col, r : row) : color;

{read

frame buffer}
procedure SetPixelWord(c : col, r : row, value : word);
function GetPixel(c : col, r : row) : word;


Thuật tốn vẽ đoạn thẳng
ª

u cầu






Đi qua 2 điểm đầu mút của đoạn thẳng
Độ sáng đồng đều, trơn
Đường thẳng có độ dốc khác nhau phải có độ sáng như nhau
Giải thuật phải có tính lặp lại (dùng để xóa đường thẳng)
Không phụ thuộc vào các chọn điểm bắt đầu vẽ



Giải thuật DD_Line
ª

Procedure DD_Line(row1,col1,row2,col2,color:integer);
{Giả sử độ dốc nằm giữa [-1,1], col1<= col2}
var
dx, dy, y, m: real;
x: integer;
begin
dx:= col2-col1;
dy:= row2 – row1;
m:= dy/dx;
y:= row1;
for x:=col1 to col2 do
begin
SetPixel(x, Round(y),color);
y:= y + m;
end;
end;


Thuật tốn Bresenham
ª

Những hạn chế của giải thuật DD_Line
– Chậm vì sử dụng hàm Round
– Khơng chính xác khi khoảng cách giữa 2 điểm đầu mút lớn
– Độ sáng không đồng đều


ª

Thuật tốn Bresenham
– Chỉ dùng số ngun
– Thuộc vào lớp giải thuật incremental (xác định tọa độ của điểm
hiện hành dựa vào tọa độ của điểm trước)


Biểu diễn đoạn thẳng trong frame buffer
ª

Cho đoạn thẳng nối hai điểm (xa , ya) và (xb , yb),
– các tọa độ đều là số nguyên (tọa độ trong frame buffer)

ª

Biểu diễn tường minh của đường thẳng:y = m(x − xa) + ya
– Độ dốc:

m=

∆y , với
∆x

∆y = yb − ya
∆x = xb − xa
ª

Bài tốn: Xác định các pixel biểu diễn đoạn thẳng “tốt” nhất
– tùy thuộc vào cách định nghĩa sai số


ª

Wlog (without loss of generality), xa < xb và 0 < m < 1
– X tăng từ a đến b
– X tăng nhanh hơn y
– Mỗi lần x tăng lên 1, y không tăng hoặc tăng lên 1


Sai số khi chọn pixel
ª
ª

Sinh các pixel bằng phương pháp tăng dần
Định nghĩa sai số e(Ti) = y* − yi − 1
e(Si) = (yi − 1 + 1) − y*

Đoạn thẳng lý tưởng

Si
y*
yi −1

Ti
xi − 1

xi


Quy tắc chọn pixel xấp xỉ tốt đoạn thẳng thực

ª

Quy tắc chọn pixel
Chọn Ti nếu và chỉ nếu e(Ti) - e(Si) < 0
Tính e(Ti) − e(Si) = 2m(xi − xa) + 2(ya − yi − 1) − 1
Từ trên, để chỉ tính với số nguyên, định nghĩa
ei = Dx⋅ (e(Ti) - e(Si))
= 2(Dy)(xi - xa) + 2(Dx)(ya - yi - 1) - Dx
Nếu ei < 0 thì chọn yi = yi - 1 , nếu khơng thì chọn yi = yi - 1 + 1
Cần kiểm tra tính đúng đắn của quy tắc trên!

(*)


Kiểm tra tính đúng đắn của quy tắc chọn pixel
ª

Trường hợp đoạn thẳng lý tưởng đi qua giữa Si và Ti
Đoạn thẳng lý tưởng
Si
y*
yi −1

Ti
xi −1

xi

e(Ti) = y* - yi - 1
e(Si) = (yi - 1 + 1) - y*



Kiểm tra tính đúng đắn của quy tắc chọn pixel (tiếp)
ª

Các trường hợp cịn lại
đoạn thẳng lý tưởng
đi qua phía trên Si và Ti

đoạn thẳng lý tưởng
đi qua phía dưới Si và Ti

Si
Si

yi − 1
xi −1
e(Ti) >= 0
e(Si) <= 0

Ti
xi

Ti

yi − 1
xi −1
Nhắc lại: e(Ti) = y* - yi - 1
e(Si) = (yi - 1 + 1) - y*


xi
e(Ti) <= 0
e(Si) >= 0


Tính sai số một cách hữu hiệu
ª

ei = 2(∆y)(xi − xa) + 2(∆x)(ya − yi − 1) − ∆x
Từ
suy ra
ei + 1 = 2(Dy)(xi + 1 - xa) + 2(Dx)(ya - yi ) - Dx
Từ trên,
ei + 1 = ei + 2(Dy)(xi + 1 - xi) - 2(Dx)(yi - yi - 1 )
Theo quy tắc chọn pixel,
– nếu ei < 0 thì chọn yi = yi - 1
ei + 1 = ei + 2Dy
– nếu khơng thì chọn yi = yi - 1 + 1
ei + 1 = ei + 2Dy - 2Dx


Giải thuật của Bresenham
ª

Biểu diễn đoạn thẳng trong frame buffer
– Giải thuật bắt đầu như thế nào?
ª
x0 = xa, y0 = ya
ª


Từ (*) có e1 = 2(Dy) - Dx

(dùng x1 - xa = 1)

procedure Bresenham(xa, xb : col; ya, yb : row; col_val : color);
{vẽ đoạn thẳng có màu là col_val từ (xa, ya) đến (ya,
{wlog, xa < xb và 0 < độ dốc của đoạn thẳng < 1}
var
x : col;
y : row;
dx, dy,
e_inc,
{thay đổi của sai số khi y tăng}
e_noinc, {thay đổi của sai số khi y không tăng}
e : integer; {sai số hiện thời}


Giải thuật của Bresenham (tiếp)
begin
y := ya;
dx := xb - xa;
dy := yb - ya;
e_noinc := dy + dy; {2dy}
e := e_noinc - dx; {e1=2dy-dx}
e_inc := e - dx;
{2dx-dy}
for x := xa to xb do {vòng lặp chính}
begin
SetPixel(x, y, col_val);
if e < 0 then e := e + e_noinc;

else begin
y := y + 1;
e := e + e_inc
end;
end;
end; {Bresenham}


Các trường hợp khác

ª
ª
ª
ª
ª

Giải thuật Bresenham giả sử xa > xb và 0 < m < 1. Giải
quyết các trường hợp cịn lại:
xa > xb (đổi vị trí hai đầu mút)
m > 1 (đổi vai trò của x và y)
Độ dốc âm: -1 < m < 0 (thay dy bằng –dy)
m < -1 (thay dx bằng –dx, đổi vai trò của x và y)
Đoạn thẳng đứng và đoạn thẳng nằm ngang


Biểu diễn vịng trịn trong frame buffer
ª

Bài tốn: Xác định các pixel biểu diễn vòng tròn y2 = R2 –
x2 “tốt” nhất

– tùy thuộc vào cách định nghĩa sai số

ª

Giải quyết
– Do đối xứng, chỉ cần khảo sát cách vẽ khi 0 ≤ x sao cho y(x) ≥ x
tức là cung AB.
– Sinh các pixel bằng phương pháp tăng dần (incremental).


Đối xứng trên vịng trịn
ª

Giảm phí tổn tính tốn bằng cách dùng phép đối xứng trên
vòng tròn
– Chỉ cần xác định các pixel tương
y ứng với một cung là 1/8 vòng
tròn, ở đây chọn cung AB.
(−x, y)
(x, y)
A
B
(y, x)
(−y, x)
x
(−y, −x)
(−x, −y)

(y, −x)
(x, −y)



Sai số khi chọn pixel
ª

ª

Giả sử có pixel tốt nhất tại bước thứ i - 1 là Pi - 1 = (xi - 1, yi 1)
Định nghĩa
Si = (xi - 1 + 1, yi - 1)
Ti = (xi - 1 + 1, yi - 1 - 1)

ª

yi − 1

Pi − 1

Ti

Định nghĩa sai số
e(P) = (x2 + y2) - R2

ª

Định nghĩa hàm số quyết định
di = e(Si) + e(Ti)

Si


xi − 1 xi


Qui tắc chọn pixel xấp xỉ tốt cung vòng tròn
Nếu di < 0 thì chọn Si cịn nếu khơng thì chọn Ti

yi − 1

Pi − 1

Si
Ti

xi − 1 xi
Cần kiểm tra tính đúng đắn của quy tắc trên!


Kiểm tra tính đúng đắn của quy tắc chọn pixel
ª
ª

Nhắc lại: di = e(Si) + e(Ti)
Trường hợp: di < 0 (Si gần đường tròn hơn)
Si

Si

Si
Ti


Ti

e(Si) < 0
e(Ti) < 0
OK!

Ti

e(Si) > 0
e(Ti) < 0
OK, vì di < 0
⇒ Si gần đường trịn hơn

e(Si) > 0
e(Ti) > 0
Khơng thể!


Kiểm tra tính đúng đắn của quy tắc chọn pixel (tiếp)
ª
ª

Nhắc lại: di = e(Si) + e(Ti)
Trường hợp: di ≥ 0 (Ti gần đường trịn hơn)
Si

Si

Si
Ti


Ti

e(Si) < 0
e(Ti) < 0
Khơng thể!

Ti

e(Si) > 0
e(Ti) < 0
OK, vì di ≥ 0
⇒ Ti gần đường tròn hơn

e(Si) > 0
e(Ti) > 0
OK!


Tính hàm số quyết định một cách hữu hiệu
ª
ª

Nhắc lại: e(P) = (x2 + y2) - R2
Có thể chứng minh được (bài tập):
di + 1 = di + 4 xi - 1 + 6 + 2(yi2 - yi - 12) - 2(yi - yi - 1)

Theo quy tắc chọn pixel
– nếu di < 0 thì ta có yi = yi - 1 , do đó chọn Ti
di + 1 = di + 4 xi - 1 + 6

– nếu không thì yi = yi - 1 - 1, do đó chọn Si
di + 1 = di + 4(xi - 1 - yi - 1) + 10
ª

Giải thuật bắt đầu như thế nào?
x0 = 0, y0 = R

do đó S1 = (1, R) và T1 = (1, R - 1), vậy
d1=e(S1) + e(T1) =(12+R2-R2)+(12+(R-1)2-R2)=3 - 2R


Giải thuật của Michener
ª

Biểu diễn vịng trịn trong frame buffer

procedure MichCirc(xc : col; yc : row; Rad : integer; value : color);
{Vẽ vòng tròn có tâm (xc, yc), bán kính Rad, vaø maøu v
var
x : col;
y : row;
d : integer;
begin
x := 0; y := Rad;
d := 3 - 2*Rad;


Giải thuật của Michener (tiếp)
while x <= y do begin
SetPixel(xc + x, yc + y, value); {draw 8 points }

SetPixel(xc - x, yc + y, value); {based on (x, y)}
SetPixel(xc + x, yc - y, value);
SetPixel(xc - x, yc - y, value);
SetPixel(xc + y, yc + x, value);
SetPixel(xc - y, yc + x, value);
SetPixel(xc + y, yc - x, value);
SetPixel(xc - y, yc - x, value);
if d < 0 then d := d + 4*x + 6 {update error term}
else begin
d := d + 4*(x - y) + 10;
y := y - 1
end;
x := x + 1
end
end; {MichCirc}


×