Giải thuật sinh đa giỏc (Polygon)

Một phần của tài liệu kĩ thuật đồ họa và ngôn ngữ c (Trang 34 - 41)

CHƯƠNG 2 : CÁC GIẢI THUẬT SINH THỰC THỂ CƠ SỞ

2.3. CÁC GIẢI THUẬT XÂY DỰNG THỰC THỂ CƠ SỞ

2.3.8. Giải thuật sinh đa giỏc (Polygon)

a. Thuật giải vẽ đường bao đa giỏc

Việc biểu diễn đa giỏc thụng qua: Tập cỏc đoạn thẳng

Tập cỏc điểm thuộc đa giỏc Cỏc loại đa giỏc:

Hỡnh 2.17 Cỏc loại đa giỏc

Đa giỏc lồi: là đa giỏc cú đường thẳng nối bất ký 2 điểm bờn trong nào của đa giỏc đều nằm trọn trong đa giỏc. Đa giỏc khụng lồi là đa giỏc lừm.

Cỏc đường thẳng bao đa giỏc - cạnh của đa giỏc. Cỏc điểm giao của cạnh - đỉnh của

đa giỏc. Thụng tin cần thiết để xỏc định đa giỏc:

Số cạnh

Toạ độ cỏc đỉnh của đa giỏc Giải thuật:

Polygon (arrayx, arrayy,n)

{ if (n<3 //khụng phải đa giỏc exit;

for (i=1 ; i<= n-1; i++)

line(arrayx[i],arrayy[i], arrayx[i+1], arrayy[i+1]); line(arrayx[i+1],arrayy[i+1], arrayx[1], arrayy[1]); }

b. Cỏc thuật toỏn tụ miền kớn đa giỏc

Lợi thế của hiển thị raster là: khả năng lưu trữ, copy, tụ màu một vựng...Cú hai dạng vựng tụ thường gặp đú là: tụ bằng một màu thuần nhất (solid fill), tụ theo mẫu tụ (fill

pattern) nào đú.

Cũn thiết bị vector thỡ hạn chế do cỏc vựng tụ màu tạo ra bởi một tập cỏc đoạn thẳng sỏt nhau - làm chậm quỏ trỡnh làm tươi.

Giải thuật đường biờn (Boundary - fill Algorithm) Bắt đầu từ 1 điểm (x,y) trong vựng cần được tụ màu:

o Xỏc định màu điểm: getpixel(x,y,c) o Tụ màu putpixel(x,y,c)

Bước tiếp: kiểm tra thuộc tớnh màu cỏc điểm lõn cận o Điểm lõn cận đó tụ màu (exit)

o Trựng với màu đường biờn(exit) o Nếu khụng thỡ tụ màu

Cỏc phương phỏp xỏc định điểm lõn cận

Hỡnh 2.18 Phương phỏp tịnh tiến giải thuật

Giải thuật tụ màu đường biờn:

#include <graphics.h> #include <conio.h>

void FloodFill (int x, int y, int in_color, int new_color){ if (getpixel(x, y) == in_color){

putpixel(x, y, new_color);

FloodFill(x-1, y, in_color, new_color); FloodFill(x+1, y, in_color, new_color); FloodFill(x, y-1, in_color, new_color); FloodFill(x, y+1, in_color, new_color); }}

void main(){

int gr_drive = DETECT, gr_mode; initgraph(&gr_drive, &gr_mode, ""); circle(getmaxx() / 2, getmaxy() / 2, 15); FloodFill(getmaxx() / 2, getmaxy() / 2, 0, 4); getch(); closegraph();} 4-connected 8-connected

Giải thuật dũng quột (scanline) cho việc tụ màu vựng

Giải thuật dựa trờn ý tưởng sử dụng một đường quột trờn trục y của màn hỡnh đi từ

ymax đến ymin của vựng cần được tụ màu.

Với mỗi giỏ trị y = yi đường thẳng quột cắt cỏc đường biờn của vựng cần tụ tạo ra đoạn thẳng y = yi với x ∈[xmin, xmax]. Trờn đoạn thẳng đú chỳng ta tụ màu cỏc điểm tương ứng đi từ xmin đến xmax cú cỏc điểm tụ (xi, yi) ∈y = yi.

Đơn giản nhất vớ dụ tụ màu hỡnh chữ nhật:

void scanline_rectg(x1,y1,x2,y2,c){ int i,j; for(i=y1; i>=y2; i--)

for(j=x1; j<= x2;j++) putpixel(i,j,c); }

Phộp tụ màu 1 đa giỏc bất kỳ sẽ phức tập hơn rất nhiều so với hỡnh chữ nhật Giả sử vựng tụ được cho bởi 1 đa giỏc n đỉnh: pi (xi,yi), i=0,1,....,n-1. Đa giỏc này cú thể là đa giỏc lồi, đa giỏc lừm hay đa giỏc tự cắt....

Cỏc bước túm tắt chớnh của thuật toỏn:

Tỡm ytop, ybottom lần lượt là giỏ trị lớn nhất, nhỏ nhất của tập cỏc tung độ của cỏc đỉnh của đa giỏc đó cho.

ytop = max{yi,(xi,yi) ∈P}, ybottom = min{yi,(xi,yi) ∈P}.

Ứng với mỗi dũng quột y=k, với k thay đổi từ ybottom đến ytop lặp:

o Tỡm tất cả cỏc hoành độ giao điểm của dũng quột y=k với cỏc cạnh của đa giỏc

o Sắp xếp cỏc hoành độ giao điểm theo thứ tự tăng dần: xo,x1,....

o Tụ màu cỏc đoạn thẳng trờn đường thẳng y=k lần lượt được giới hạn bởi cỏc cặp (xo,x1), (x2,x3), ......, (x2k,x2k+1).

Chỳng ta sẽ gặp 1 số vấn đề sau:

Ứng với mỗi dũng quột khụng phải lỳc nào tất cả cỏc cạnh của đa giỏc cũng

tham gia cắt dũng quột. Do đú để cải thiện tốc độ cần phải cú một cỏch nào đú để hạn chế được số cạnh cần tỡm giao điểm ứng với mỗi dũng quột.

Hỡnh 2.19 Giải thuật scanline cho một đa giỏc bất kỳ

x y yqmax yq yqmin yq

Nếu số giao điểm tỡm được giữa cỏc cạnh đa giỏc và dũng quột là lẻ (điều này chỉ xảy ra khi dũng quột sẽ đi qua cỏc đỉnh của đa giỏc) khi đú ta sẽ tớnh số điểm là 2 thỡ cú thể tụ khụng chớnh xỏc. Ngoài ra, việc tỡm giao điểm của

dũng quột với cỏc cạnh nằm ngang là trường hợp đặt biệt...

Để giải quyết cỏc vấn đề trờn ta cú cỏc phương phỏp sau:

Danh sỏch cỏc cạnh kớch hoạt (AET - Active Edge Table)

Mỗi cạnh của đa giỏc được xõy dựng từ 2 đỉnh kề nhau Pi(xi,yi) và Pi+1(xi+1,yi+1) gồm cỏc thụng tin sau:

ymin: giỏ trị nhỏ nhất trong 2 đỉnh của cạnh

xIntersect: hoành độ giao điểm của cạnh với dũng quột hiện đang xột DxPerScan: giỏ trị 1/m (m là hệ số gúc của cạnh)

DeltaY: khoảng cỏch từ dũng quột hiện hành tới đỉnh ymax

Danh sỏch cỏc cạnh kớch hoạt AET: danh sỏch này dựng để lưu cỏc tập cạnh của đa giỏc cú thể cắt ứng với dũng quột hiện hành và tập cỏc điểm giao tương ứng. Nú cú một số

đặc điểm:

Cỏc cạnh trong danh sỏch được sắp xếp theo thứ tự tăng dần của cỏc hoành độ giao

điểm để cú thể tụ màu cỏc đoạn giao một cỏch dễ dàng.

Thay đổi ứng với mỗi dũng quột đang xột, do đú danh sỏch này sẽ được cập nhật liờn tục trong quỏ trỡnh thực hiện thuật toỏn. Đầu tiờn ta cú danh dỏch chứa toàn bộ cỏc cạnh của đa giỏc gọi là ET (Edge Table) được sắp xếp theo thứ tự tăng dần của ymin, rồi sau mỗi lần dũng quột thay đổi sẽ di chuyển cỏc cạnh trong ET thoả điều kiện sang AET.

Một dũng quột y=k chỉ cắt 1 cạnh của đa giỏc khi và chỉ khi k>=ymin và ∆y>0. Chớnh vỡ vậy mà với cỏc tổ chức của ET (sắp theo thứ tự tăng dần của ymin) điều kiện để chuyển cỏc cạnh từ ET sang AET sẽ là k>=ymin; và điều kiện để loại một cạnh ra khỏi AET là ∆y<=0

Cụng thức tỡm giao điểm nhanh

Nếu gọi xk,xk+1 lần lượt là cỏc hoành độ giao điểm của một cạnh nào đú với cỏc dũng quột y=k và y=k+1 ta cú:

xk+1 - xk = 1/m ((k+1) - k) = 1/m hay xk+1 = xk + 1/m

Như vậy nếu lưu hoành độ giao điểm ứng với dũng quột trước lại, cựng với hệ số gúc của cạnh, ta xỏc định được hoành độ giao điểm ứng với dũng quột kế tiếp theo cụng thức trờn. Nờn thụng tin của cạnh cú 2 biến: DxPerScan , xIntersect.

Trường hợp dũng quột đi ngang qua một đỉnh:

Tớnh 1 giao điểm nếu chiều của 2 cạnh kề của đỉnh đú cú xu hướng tăng hay giảm Tớnh 2 giao điểm nếu chiều của 2 cạnh kề của đỉnh đú cú xu hướng thay đổi, nghĩa là tăng-giảm hay giảm-tăng.

Hỡnh 2.20 Qui tắc tớnh: một giao điểm (A) và hai giao điểm (B)

Hỡnh 2.21 lưu đồ thuật toỏn scan - line

Giải thuật tụ vựng kớn theo mẫu (Pattern filling) object (ảnh mẫu)

A[m,n]

Vấn đề: xỏc định điểm ở mẫu và nhiều điểm tương ứng với chỳng trờn màn hỡnh. Phương phỏp 1:

Tỡm điểm neo ở đầu trỏi nhất hàng đầu tiờn của đa giỏc.

Pi Pi Pi Pi Pi-1 Pi-1 Pi-1 Pi-1 Pi+1 Pi+1 Pi+1 Pi+1 A B

Nhược điểm: khụng cú điểm định vị trớ phõn biệt một cỏch rừ ràng cho mẫu tụ trong một đa giỏc bất kỳ.

Phương phỏp 2: sử dụng cho SRGP

Lấy điểm neo ở gốc toạ độ, giả sử ta coi cả màn hỡnh được lỏt bởi màu tụ cỏc thực thể là cỏc đường biờn cho cỏc vựng tụ, vậy nếu ngoài cỏc thực thể cỏc màu tụ khụng được phộp thể hiện.

Hỡnh 2.22 Phương phỏp lấy điểm neo Túm tắt chương:

Để cú thể hiển thị cỏc đối tượng đồ hoạ trờn thiết bị hiển thị dạng điểm mà điển hỡnh là

màn hỡnh, cần phải cú một quỏ trỡnh chuyển cỏc mụ tả hỡnh học của cỏc đối tượng này trong hệ toạ độ thế giới thực về dóy cỏc pixel tương ứng gần với chỳng nhất trờn toạ độ

thiết bị. Quỏ trỡnh này cũn được gọi là quỏ trỡnh chuyển đổi bằng dũng quột. Yờu cầu quan trọng nhất đối với quỏ trỡnh này ngoài việc phải cho kết quả xấp xỉ tốt nhất cũn phải cho tốc độ tối ưu.

Ba cỏch tiếp cận để vẽ đoạn thẳng gồm thuật toỏn DDA, thuật toỏn Bresenham, thuật toỏn Midpiont đều tập trung vào việc đưa ra cỏch chọn một trong hai điểm nguyờn kế tiếp khi đó biết điểm nguyờn ở bước trước. Thuật toỏn DDA đơn giản chỉ dựng thao tỏc làm

trũn nờn phải dựng cỏc phộp toỏn trờn số thực, trong khi đú thuật toỏn Bresenham và Midpiont đưa ra cỏch chọn phức tạp hơn nhưng cho kết quả tốt hơn. Tương tự dựng hai giải thuật Bresenham và Midpiont để vẽ đường trũn và ellpise và một số đường cong

khỏc.

Cỏc thuật toỏn tụ màu vựng gồm thuật toỏn loang (đệ qui) hay thuật toỏn dũng quột. Cú thể tụ cựng một màu hay tụ theo mẫu.

Bài tập:

1. Chỉ định cỏc vị trớ mành nào sẽ được chọn bởi thuật toỏn Bresenham lỳc chuyển

quột một đường thẳng từ toạ độ pixel (1,1) sang toạ độ pixel (8,5).

2. Dựng giải thuật Bresenham viết hàm sinh đoạn thẳng (xột tất cả cỏc trường hợp của hệ số gúc).

3. Dựng giải thuật Midpiont viết hàm sinh đoạn thẳng (xột tất cả cỏc trường hợp của hệ số gúc). x y neo neo x y

4. Dựng giải thuật Midpiont viết hàm sinh đường trũn (toạ độ tõm (xc,yc) và bỏn kớnh r).

5. Dựng giải thuật Midpiont viết hàm sinh đường ellipse (toạ độ tõm (xc,yc) và bỏn

kớnh rx và ry ).

6. Từ hàm vẽ đường thẳng thiết kế và cài đặt hàm vẽ cỏc hỡnh sau: hỡnh chữ nhật, đa giỏc, ngụi nhà....

7. Viết giải thuật tỡm giao điểm hai đoạn thẳng.

8. Viết chương trỡnh tụ màu Floodfill (sử dụng đệ qui với 4-connected).

Một phần của tài liệu kĩ thuật đồ họa và ngôn ngữ c (Trang 34 - 41)

Tải bản đầy đủ (PDF)

(185 trang)