Chương 2 : CÁC THUẬT TOÁN TÔ MÀU
2.3. Các thuật tốn tơ màu
2.3.3. Phương pháp tô màu dựa theo đường biên
Bài tốn đặt ra : Cần tơ màu một vùng nếu biết được màu của đường biên vùng tô và
một điểm nằm bên trong vùng tô.
Ý tưởng : Bắt đầu từ một điểm nằm bên trong vùng tô, kiểm tra các điểm lân cận của
nó đã được tơ với màu muốn tơ, hay điểm lân cận có màu trùng với màu biên không ? Nếu cả hai trường hợp đều khơng phải thì ta sẽ tơ điểm đó với màu muốn tơ. Q trình này được lặp lại cho đến khi khơng cịn tơ được nữa thì dừng (xem hình 2.8).
Hình 2.8 : Tơ màu theo đường biên.
Có 2 quan điểm về cách tơ này. Đó là dùng 4 điểm lân cận (có thể gọi là 4 liên thông) hay 8 điểm lân cận (8 liên thơng) (xem hình 2.9).
(x,y-1)
(x-1,y) (x,y)(x+1,y)
(x,y+1)
Hình 2.9 : 4 liên thông và 8 liên thông.
Cài đặt minh họa thuật tốn 4 liên thơng
Procedure Boundary_fill ( x,y, mauto, maubien :integer); var mau_ht : integer;
begin
mau_ht:= getpixel(x, y);
if (mau_ht <> mauto) and (mau_ht <> maubien) then begin
Chương 2: Các thuật tốn tơ màu
putpixel(x,y,color);
Boundary_fill ( x+1,y, mauto, maubien ); Boundary_fill ( x-1,y, mauto, maubien ); Boundary_fill ( x,y+1, mauto, maubien ); Boundary_fill ( x,y-1, mauto, maubien ); end;
end;
Nhận xét :
- Thuật tốn có thể khơng chính xác khi có một số điểm nằm trong vùng tơ có màu là màu cần tơ của vùng.
- Việc thực hiện gọi đệ qui làm thuật tốn khơng thể sử dụng cho vùng tô lớn ( tràn stack).
- Có thể khắc phục việc tràn stack bằng cách giảm số lần gọi đệ qui. Khởi đầu điểm (x,y) là điểm có vị trí đặc biệt trong vùng tơ, sau đó, gọi đệ qui các điểm lân cận của (x,y) (xem hình 2.8).
Hình 2.10: Tam giác với 3 tọa độ đỉnh.
(100,100)
(100,400)
(500,200)
Ví dụ 1: Trong hình 2.10, ta có thể xét điểm (x,y) có tọa độ là (498, 200). Với điểm khởi đầu này thì chỉ cần xét 3 điểm lân cận là (x-1,y), (x,y-1), (x,y+1). Khi đó thủ tục tơ màu theo đường biên được viết lại như sau :
Procedure Boundary_fill ( x,y,mauto, maubien :integer); var mau_ht : integer;
Chương 2: Các thuật tốn tơ màu
begin
mau_ht:= getpixel(x,y);
if (mau_ht <> mauto) and (mau_ht <> maubien) then begin
putpixel(x,y,color);
Boundary_fill ( x-1,y, mauto, maubien ); Boundary_fill ( x,y+1, mauto, maubien ); Boundary_fill ( x,y-1, mauto, maubien ); end;
end;
Ví dụ 2: Trong hình 2.10, ta có thể xét điểm (x,y) có tọa độ là (102, 102). Với điểm khởi đầu này thì chỉ cần xét 2 điểm lân cận là (x+1,y), (x,y+1). Khi đó thủ tục tơ màu theo đường biên được viết lại như sau :
Procedure Boundary_fill ( x,y,mauto, maubien :integer); var mau_ht : integer;
begin
mau_ht:= getpixel(x,y);
if (mau_ht <> mauto) and (mau_ht <> maubien) then begin
putpixel(x,y,color);
Boundary_fill ( x+1,y, mauto, maubien ); Boundary_fill ( x,y+1, mauto, maubien ); end;
Chương 2: Các thuật tốn tơ màu
- Một cải tiến khác : không cài đặt đệ qui mà tơ theo từng dịng (xem hình 2.11).
Hình 2.10 : Tơ theo từng dòng.