- Khi điểm tiếp theo được chọn là D ,M tăng một đơn vị theo hướng x Tọa độ trung điểm mới là (xp+2, yp+1/2) Do đó: d1
dnew =d old +b2 (2xp+ 3) 2( −2 yp+ 2)= dold D
2.5.2. Thuật toán tô màu theo làn
• Làn: là dãy liên tục các điểm ảnh trên một dòng có cùng mầu với nhau.
Ta vận dụng kỹ thuật “điểm phải nhất” để xây dựng thuật toán tô màu như sau. Điểm có số hiệu 1 chính là điểm (x,y) nơi xuất phát tô màu.
Trước hết ta gọi toán tử cc=getpixel(x,y) để xác định màu cũ của hình. Nếu cc=c tức là hình đã có màu c cần tô, ta kết thúc thuật toán. Ngược lại, ta xuất phát từ điể 1 trên dòng chứa nó, tức dòng x, điểm biên phải nhất là điểm 2, lưu điểm này vào stack s. Điểm (x,y) trên dòng x được gọi là điểm phải nhất nếu màu của nó là cc và màu của điểm sát phải nó khác cc, tức là:
getpixel(x,y)==cc && getpixel(x,y+1)!=cc
Bản chất của phương pháp điểm phải nhất là như sau. Việc tô màu được tổ chức thực hiện theo từng làn. Làn là những đoạn gồm liên tiếp các ô trên một dòng của hình. Trong hình minh họa trên, dòng thứ 3 gồm có 2 làn biểu thị qua các dãy oo5 và ooo3. Mỗi làn được quản lý theo điểm phải nhất của làn đó. Thí dụ làn oo5 được quản lý bằng điểm 5, còn làn ooo3 bằng điểm 3. Để tô màu cho mỗi làn ta bắt đầu từ điểm phải nhất của làn đó rồi tô dần qua trái. Mỗi khi tô một điểm ta tranh thủ phát hiện và lưu
giữ các điểm phải nhất nằm trên và dưới điểm đó. Nắm giữ được các điểm phải nhất của mỗi làn tức là có thể quản lý và tổ chức tô màu cho làn đó. Trước khi bắt đầu tô mầu, ta xuát phát từ điểm (x,y) chuyển qua phải để tìm điểm phải nhất trên dòng x. Mỗi khi bắt đầu xử lý một làn ta lên dòng trên và xuống dòng dưới của làn dó để tìm điểm phải nhất, nếu tìm được ta nạp chúng vào stack. Bước này dựa vào tính chất liên thông của hình nhằm đảm bảo không bỏ sót việc duyệt các điểm trong hình.
Thủ tục tô màu theo kỹ thuật điểm phải nhất sẽ như sau: 1. Khởi trị
cấp phát stack s
làm rỗng s
khởi trị các biến khác
2. Từ điểm (x,y) qua phải tìm điểm phải nhất (x,y) để nạp vào s 3. Xử lý: lặp đến khi stack rỗng
3.1. lấy ngọn s đưa vào x, y
3.2. nếu điểm (x,y) đã được tô thì lặp lại bước 3
3.3. từ (x,y) tìm điểm phải nhất trên dòng (x-1,y), nếu có: nạp vào s 3.4. từ (x,y) tìm điểm phải nhát trên dòng (x+1,y), nếu có: nạp vào s 3.5. Lặp: chuyển dần qua trái đến hết làn
3.5.1. Tô màu điểm (x,y)
3.5.2. Nếu điểm (x-1,y) là điểm phải nhất: nạp(x-1,y) vào s 3.5.3. Nếu điểm (x+1,y) là điểm phải nhất: nạp (x+1,y) vào s
Theo hình trên, trước khi xử lý làn 2 ta tìm được điểm 3 là điểm phải nhất. Bước 3.4 không cho điểm phải nhất nào. Khi di chuyển từ điểm đầu làn qua trái ta nạp thêm được ba điểm 4,5 và 6 vào stack.
void Color(int x,int y,int c){
/* Lay ngon Stack dua vao cac bien x va y */ #define POP(x,y) {y=*s--;x=*s--;}
/* Nap toa do (x,y) vao Stack s */ #define PUSH(x,y) {*(++s)=x;*(++s)=y;}
/*Xuat phat tu diem(x,y)qua trai,tim diem phai nhat*/ #define TORIGHT(x,y) {while(getpixel(x,y)==cc) y++;}
/* Kiem tra diem phai nhat */
#define SEARCH(x,y) (getpixel(x,y)==cc&&getpixel(x,y+1)!=cc) #define OK(x,y) (getpixel(x,y)==cc)
int cc,i;
int *s=NULL,*p; cc=getpixel(x,y); if(cc==-1||cc==c) return;
if((s=(int *)malloc(1500))==NULL){ printf("%c Khong du mien nho",7); getch();
return; }
p=s;
TORIGHT(x,y); /* Tim diem xuat phat */ PUSH(x,y-1); /* Nap vao Stack */
do{
POP(x,y); /* Lay tu Stack */ if(OK(x-1,y)){ i=y; TORIGHT(x-1,i); if(i>y+1) PUSH(x-1,i-1); } if(OK(x+1,y)){ i=y; TORIGHT(x+1,i); if(i>y+1) PUSH(x+1,i-1); } do{ putpixel(x,y,c); if(SEARCH(x-1,y)) PUSH(x-1,y); if(SEARCH(x+1,y)) PUSH(x+1,y); y--; }while(OK(x,y)); }while(s!=p); free(p); } 2.6. CÁC THUẬT TOÁN CẮT XÉN HÌNH
Thao tác loại bỏ các phần hình ảnh nằm ngoài một vùng cho trước được gọi là xén hình. Vùng được dùng để xén hình gọi là cửa sổ xén (clip window).
Tùy thuộc vào từng ứng dụng cụ thể mà cửa sổ xén có thể có dạng là đa giác hay là đường cong khép kín. Trong phần này chúng ta sẽ khảo sát các thuật toán xén hình vào cửa sổ xén là hình chữ nhật trước, sau đó sẽ khảo sát các cửa sổ xén có dạng khác. Để đơn giản, trong các thuật toán xén hình, cửa sổ xén được gọi là cửa sổ.
• Các giải pháp cắt xén:
1.Kiểm tra từng pixel của đoạn thẳng có ở trong chữ nhật? 2.Tính toán các điểm cắt của từng đoạn thẳng với cạnh chữ nhật
cắt xén.
3.Thuật toán Sutherland-Cohen: loại bỏ ngay được các đoạn không cần cắt xén bằng cách xét tọa độ đầu mút của các đoạn thẳng. 4.Các thuật toán khác: Cyrus-Beck sử dụng đường thẳng tham số,
Liang-Barsky dành cho khối.