Đồ họa máy tính - Chương 3 pot

18 322 0
Đồ họa máy tính - Chương 3 pot

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Đồ họa máy tính - Khoa CNTT - ĐHSPHN http://www.ebook.edu.vn 39 Chương III: Một số thuật toán đồ họa cơ bản I. Vẽ đoạn thẳng Xét đoạn thẳng y = m.x +b có hệ số góc 0<m<1, ta chọn điểm đầu và điểm cuối sao cho dx =x2-x1>0. Làm sao để vẽ đoạn thẳng nối (x1,y1) (x2,y2) trong khi ta chỉ có thể ra lệnh cho màn hình vẽ từng điểm ảnh (kiểư như PutPixel của TP)? Bản chất của quá trình này là sự rời rạc hóa và nguyên hóa một đối tượng thực (ở đây là đoạn thẳng thực - đoạn thẳng toán h ọc) trên màn hình sao cho cuối cùng ta có tập các Pixel trông “giống” đối tượng nhất. Bản chất của các thuật toán vẽ đoạn thẳng là đi tìm tập các pixel liền nhau sao cho trông chúng “giống” với đoạn thẳng thực nhất Thế nào là giống ? - Liên tục (không đứt đoạn) - Gần với đoạn thẳng thực (đoạn thẳng toán học) nhất Hơn nữa, còn vấn đề tối ưu tốc độ, nghĩa là thuật toán phải tô các pixel trong thời gian nhanh nhất Bài toán: ta phải vẽ đoạn thẳng y = m.x +b có hệ số góc 0<m<1, dx>0 (các trường hợp khác đều có thể quy về trường hợp này) Đầu tiên ta nhận xét, với các đoạn thẳng dạng này, nếu (x i , y i ) là điểm ảnh đã vẽ được ở bước thứ i (điểm màu đen) thì - chắc chắn x i+1 = x i +1 - y i+1 =y i hoặc y i+1 =y i +1 do đó điểm ảnh ở bước (i+1) tiếp theo chỉ có thể là 1 trong 2 trường hợp như hình vẽ. Vấn đề quy về việc chọn điểm nào trong hai điểm đó. x1 x2 y1 y2 Làm sao vẽ đoạn thẳng nối 2 điểm này V 1 2 x i y i x i+1 (x i +1, y i ) (x i +1, y i +1) Đồ họa máy tính - Khoa CNTT - ĐHSPHN http://www.ebook.edu.vn 40 1. Thuật toán DDA vẽ đoạn thẳng Việc quyết định chọn y i+1 là y i hay y i +1 dựa vào phương trình của đoạn thẳng thực. Ta sẽ tính tọa độ của điểm y = m (x i +1) + b thuộc về đoạn thẳng thực, sau đó chọn điểm nào gần với nó nhất trong 2 điểm, nghĩa là y i+1 = round(y) = round(m.x i+1 +b) Như vậy sẽ tốn 1 phép nhân và 1 phép cộng số thực. Để cải thiện tốc độ, người ta dùng cách sau để khử phép nhân. Nhận xét rằng: y i = m.x i + b y i+1 = m.x i+1 +b ⇒ y i+1 = y i + m Ví dụ: Cho A(12,20) và B(22,27), ta có m=0.7 Begin x < x 2 ? Yes No End x:=x+1; y:=y+m; PutPixel(x,round(y)); m:=dy/dx ; x:=x1; y:=y1; putpixel(x,round(y)); Lưu đồ thuật toán DDA (x i +1, y) y (x i +1, round(y)) (x i , y i ) Đồ họa máy tính - Khoa CNTT - ĐHSPHN http://www.ebook.edu.vn 41 i x i y i y 0 12 20 20 1 13 21 20.7 2 14 21 21.4 3 15 22 22.1 4 16 23 22.8 5 17 24 23.5 6 18 24 24.2 7 19 25 24.9 8 20 26 25.6 9 21 26 26.3 10 22 27 27 Thuật toán DDA vẽ đoạn thẳng { Vẽ đoạn thẳng trong trường hợp 0<m<1, dx >0} uses crt,graph; var gd,gm:integer; i,x1,y1,x2,y2,x:integer; y,m:real; Begin gd:=detect; initgraph(gd,gm,''); Randomize; Repeat {vẽ các đoạn thẳng ngẫu nhiên} x1:=random(GetMaxX); x2:=x1+random(GetMaxX-x1); y1:=random(GetMaxY); y2:=y1+random(x2-x1); x:=x1; y:=y1; m:=(y2-y1)/(x2-x1); putpixel(x,round(y),white); for i:=x1 to x2 do begin x:=x+1; y:=y+m; putpixel(x,round(y),white); end; delay(1000); Until Keypressed; closegraph; End. Đồ họa máy tính - Khoa CNTT - ĐHSPHN http://www.ebook.edu.vn 42 2. Thuật toán Bresenham vẽ đoạn thẳng Trong hình vẽ (x i +1,y) là điểm thuộc đoạn thẳng thực, ta có: y = m(x i +1) + b. Giả sử ở bước i ta đã xác định được điểm (x i ,y i ). Đặt d 1 = y – y 1 ; d 2 = (y i +1) - y ; Việc chọn điểm tiếp theo (x i+1 , y i+1 ) là S hay P tùy thuộc vào việc d 1 lớn hơn hay nhỏ hơn d 2 , nói cách khác là phụ thuộc vào dấu của (d 1 – d 2 ) • Nếu d 1 – d 2 <0, ta sẽ chọn S, tức là y i+1 = y i • Trường hợp còn lại: d 1 – d 2 >0, ta sẽ chọn P, tức là y i+1 = y i +1 Đặt p i = dx (d 1 – d 2 ). Thay d 1 = y – y 1 ; d 2 = (y i +1) – y vào ta có p i = dx (2y - 2y i -1) Thay y = mx i +b = dy(x i +1)/dx + b vào ta có p i = 2dx [dy(x i +1)/dx +b] – 2y i dx –dx = 2x i dy – 2y i dx +C với C = 2dy + (2b-1)dx là hằng số. Ta nhận xét rằng, nếu tại bước thứ i ta xác định được dấu của p i thì sẽ xác định được điểm cần tô ở bước i+1. Làm sao để tính giá trị của p i ? ta dùng phương pháp “lũy tiến” như sau. Ta có: p i+1 –p i = (2x i+1 dy – 2y i+1 dx +C) - (2x i dy – 2y i dx +C) = 2dy -2dx(y i+1 – y i ) • Nếu p i <0 thì điểm được chọn là S, tức là y i+1 = y i ⇒ p i+1 = p i +2dy • Nếu p i >0 thì điểm được chọn là P, tức là y i+1 = y i +1 ⇒ p i+1 = p i +2dy -2dx Cuối cùng, giá trị p 0 được tính từ điểm ảnh đầu tiên (x 0 , y 0 ) theo công thức sau p 0 = 2x 0 dy – 2y 0 dx + c Thay giá trị của c vào, chú ý rằng điểm đầu (x 0 , y 0 ) cũng thuộc đoạn thẳng thực nên y 0 = mx 0 + b = x 0 dy/dx + b, suy ra p 0 = 2dy -dx tóm lại là: x i +1 S y x i y i +1 y i d 1 d 2 (x i +1,y) P Đồ họa máy tính - Khoa CNTT - ĐHSPHN http://www.ebook.edu.vn 43 Ví dụ: Cho A(12,20) và B(22,27), ta có dx = 22 – 12 = 10 ; dy = 27 – 20 = 7; c1 = 2dy = 14 ; c2 = 2(dy-dx) = -6; p 0 = 2Dy – dx = 4 i x i y i p i 0 12 20 4 1 13 21 -2 2 14 21 12 3 15 22 6 4 16 23 0 5 17 24 -6 6 18 24 8 7 19 25 2 8 20 26 -4 9 21 26 10 10 22 27 4 p 0 y 1 y 0 p 1 y 2 p 2 Đồ họa máy tính - Khoa CNTT - ĐHSPHN http://www.ebook.edu.vn 44 Thuật toán Bresenham vẽ đoạn thẳng { Vẽ đoạn thẳng trong trường hợp 0<m<1, dx >0} uses crt,graph; var gd,gm:integer; i,x1,y1,x2,y2,dx,dy,p,c1,c2,x,y:integer; Begin gd:=detect; initgraph(gd,gm,''); Randomize; Repeat x1:=random(GetMaxX); x2:=x1+random(GetMaxX-x1); y1:=random(GetMaxY); y2:=y1+random(x2-x1); {vẽ đoạn thẳng (x1,y1) (x2,y2) } Begin x < x 2 ? Yes No End x:=x+1; PutPixel(x,y); p:=2dy - dx ; c1=2dy; c2=2(dy-dx); x:=x1; y:=y1 ; putpixel(x,y); p < 0 ? Yes p:=p+c1; p:=p + c2; y:=y+1; No Lưu đồ thuật toán Bresenham Đồ họa máy tính - Khoa CNTT - ĐHSPHN http://www.ebook.edu.vn 45 dx:=x2-x1; dy:=y2-y1; p:=2*dy - dx; c1:=2*dy; c2:=2*(dy-dx); x:=x1; y:=y1; putpixel(x,y,white); for i:=x1 to x2 do begin if p<0 then p:=p+c1 else begin p:=p+c2; y:=y+1; end; x:=x+1; putpixel(x,y,white); end; delay(1000); Until Keypressed; closegraph; End. 3. Thuật toán MidPoint vẽ đoạn thẳng Thuật toán này thực chất là 1 cách diễn giải khác của thuật toán Bresenham. Ta lựa chọn y i+1 là y i hay y i +1 bằng cách so sánh trung điểm của O của PS với đường thẳng thực • Nếu O nằm phía dưới đường thẳng, ta chọn P • Nếu O nằm phía trên, ta chọn S Phương trình đường thẳng thực: Ax + By + C = 0 với A = y 2 – y 1 ; B = x 1 – x 2 ; C = x 2 y 1 – x 1 y 2 ; Đặt F(x,y) = Ax + By + C, ta biết rằng • F(x,y) <0 nếu điểm (x,y) nằm phía trên đường thẳng • F(x,y) =0 nếu điểm (x,y) thuộc đường thẳng • F(x,y) >0 nếu điểm (x,y) nằm phía dưới đường thẳng vì vậy, vấn đề quy về việc xét dấu của p i = 2F(O) = 2F(x i +1,y i +1/2) • Nếu p i <0 tức là O nằm phía trên đường thẳng ⇒ ta chọn S x i +1 S x i y i +1 y i P O: điểm giữa Đồ họa máy tính - Khoa CNTT - ĐHSPHN http://www.ebook.edu.vn 46 • Nếu p i >0 tức là O nằm phía dưới đường thẳng ⇒ ta chọn P Làm sao để tính p i ? tương tự như thuật toán Bresenham, ta cũng dùng phương pháp “lũy tiến”, dùng giá trị ở bước trước p i để tính giá trị ở bước tiếp theo p i+1 Ta có: p i+1 – p i =2F(x i+1 +1,y i+1 +1/2) - 2F(x i +1,y i +1/2) = 2[A(x i+1 +1)+B(y i+1 +1/2)+C] - 2[A(x i +1)+B(y i +1/2)+C] = 2dy – 2dx(y i+1 – y i ) Như vậy • Nếu p i <0 thì ta chọn y i+1 = y i , do đó p i+1 = p i +2dy • Nếu p i >0 thì ta chọn y i+1 = y i +1 , do đó p i+1 = p i +2dy – 2dx Cuối cùng, giá trị đầu p 0 được tính như sau: nhận xét rằng điểm đầu (x 0 , y 0 ) thuộc đoạn thẳng thực tức là Ax 0 + By 0 +C = 0 p 0 = 2F(x 0 +1,y 0 +1/2) = 2[A(x 0 +1)+B(y 0 +1/2)+C] = 2(Ax 0 + By 0 +C) + 2A +B = 2A+B = 2dy –dx II Vẽ đường tròn Thuật toán MidPoint Đầu tiên ta nhận xét rằng, do tính đối xứng của đường tròn nên ta chỉ cần vẽ được cung AB là cung 1/8 đường tròn, sau đó lấy đối xứng qua các trục và các đường phân giác ta sẽ có cả đường tròn. Chẳng hạn như ở hình vẽ trên nếu xác định được điểm (x,y), lấy đối xứng qua đường phân giác của góc phần tư thứ nhất ta thu được điểm (y,x), lấy đối xứng qua trụ c hoành ta thu được 2 điểm (y,-x) và (x,-y) Nếu ta chia thành 16,32 phần thì việc xác định tọa độ 15,31 điểm đối xứng còn lại sẽ rất khó. Còn nếu chia thành 4 hay 2 phần thì số điểm lân cận cần phải loại trừ có thể nhiều hơn 2 điểm. (x,y) (y,x) (y, -x) (x, -y)(-x, -y) (-y, -x) (-y, x) (-x, y) A B Đồ họa máy tính - Khoa CNTT - ĐHSPHN http://www.ebook.edu.vn 47 Gọi R là bán kính đường tròn, ta xuất phát từ điểm A (0,R) để vẽ cung AB. Nhìn hình vẽ ta thấy, nếu (x i , y i ) là điểm ảnh đã vẽ được ở bước thứ i thì điểm ảnh (x i+1 , y i+1 ) ở bước tiếp theo chỉ có thể là S hoặc P, tức là • x i+1 = x i + 1 • y i+1 ∈ {y i , y i -1} Giống như thuật toán vẽ đoạn thẳng, ý tưởng chính để lựa chọn giữa S và P ở đây là căn cứ vào vị trí tương đối của điểm giữa M của SP với đường tròn. Nếu M nằm bên trong đường tròn như hình vẽ thì ta sẽ chọn S vì nó gần điểm thực Q hơn so với P. Ngược lại nếu M nằm ngoài đường tròn thì P sẽ được chọn. Đặt F(x,y) = x 2 + y 2 – R 2 , các định lý toán học cho ta biết rằng • F(x,y) <0 nếu điểm (x,y) nằm trong đường tròn • F(x,y) =0 nếu điểm (x,y) nằm trên đường tròn • F(x,y) >0 nếu điểm (x,y) nằm ngoài đường tròn Đặt p i = F(M) = F(x i +1,y i – ½) ta có • Nếu p i <0 tức là M nằm trong đường tròn, ta sẽ chọn S, tức là y i+1 = y i • Nếu p i ≥0 ta sẽ chọn P, tức là y i+1 = y i -1 Cách tính giá trị của p i cũng tương tự như ở thuật toán vẽ đoạn thẳng. Ta có: p i+1 – p i = F[x i+1 +1,y i+1 – ½] - F[(x i +1,y i – ½)] = [(x i+1 +1) 2 +(y i+1 – ½) 2 - R 2 ] - [(x i +1) 2 +(y i – ½) 2 - R 2 ] = 2x i +3+(y i+1 2 – y i 2 ) – (y i+1 - y i ) Do đó • Nếu p i <0 ta chọn y i+1 = y i ⇒ p i+1 = p i + 2x i +3 • Nếu p i ≥0 ta chọn y i+1 = y i -1 ⇒ p i+1 = p i + 2x i -2y i +5 Cuối cùng ta tính giá trị đầu p 0 ứng với điểm A(0,R) p 0 =F(x 0 +1,y 0 -1/2) = F(0,R-1/2) = 5/4 -R y i y i -1 x i +1 x i P S M: điểm giữa Q(x i +1,y) Đồ họa máy tính - Khoa CNTT - ĐHSPHN http://www.ebook.edu.vn 48 Thuật toán MidPoint vẽ đường tròn Uses crt,graph; Var gd,gm,x,y,R,p,mau:integer; Procedure PutPixel8(x,y,c:integer); Begin putPixel(x,y,c); putPixel(y,x,c); putPixel(y,-x,c); putPixel(x,-y,c); putPixel(-x,-y,c); putPixel(-y,-x,c); putPixel(-y,x,c); putPixel(-x,y,c); End; Begin gd:=detect; initgraph(gd,gm,''); SetViewPort(GetMaxX div 2, GetMaxY div 2, GetMaxX,GetMaxY,false); Randomize; R :=100 + random(200); Begin x < y ? Yes No End x:=x+1; PutPixel(x,y); p:=5/4 -R; x:=0; y:=R ; PutPixel8 ( x ,y); p < 0 ? Yes p:=p+2x+3; p:=p+2(x-y); y:=y-1; No Lưu đồ thuật toán MidPoint vẽ đường tròn [...]... đầu mút của các đoạn thẳng đó http://www.ebook.edu.vn 55 Đồ họa máy tính - Khoa CNTT - ĐHSPHN Ymax Ymin Các bước: - Xác định Ymax, Ymin của đa giác cần tô - Với mỗi dòng quét y = yi (Ymin ≤ yi ≤ Ymax), xác định hoành độ giao điểm với các cạnh của đa giác - Sắp xếp chúng theo thứ tự tăng dần thành các cặp (x0, x1) - Tô các đoạn (x0, x1), (x2, x3), (x4, x5) Tuy nhiên, có một ngoại lệ là khi dòng quét.. .Đồ họa máy tính - Khoa CNTT - ĐHSPHN mau:=random(GetMaxColor); {Vẽ đường tròn MidPoint màu ngẫu nhiên } x:=0; y:=R; PutPixel8(x,y,mau); p:=1-R; while (x . loại trừ có thể nhiều hơn 2 điểm. (x,y) (y,x) (y, -x) (x, -y)(-x, -y) (-y, -x) (-y, x) (-x, y) A B Đồ họa máy tính - Khoa CNTT - ĐHSPHN http://www.ebook.edu.vn 47 . y:=y+1; No Lưu đồ thuật toán Bresenham Đồ họa máy tính - Khoa CNTT - ĐHSPHN http://www.ebook.edu.vn 45 dx:=x2-x1; dy:=y2-y1; p:=2*dy - dx; c1:=2*dy; c2:=2*(dy-dx); x:=x1; . PutPixel(x,y); p:=5/4 -R; x:=0; y:=R ; PutPixel8 ( x ,y); p < 0 ? Yes p:=p+2x +3; p:=p+2(x-y); y:=y-1; No Lưu đồ thuật toán MidPoint vẽ đường tròn Đồ họa máy tính - Khoa CNTT - ĐHSPHN http://www.ebook.edu.vn

Ngày đăng: 22/07/2014, 09:20

Từ khóa liên quan

Tài liệu cùng người dùng

Tài liệu liên quan