Thuật toán vẽ đường tròn trong lập trình
I.Thuật toán vẽ đường trònPhương trình đường tròn có dạng:(x-xc)2 + (y-yc)2 = r2Pt đường tròn có tâm ở gốc tọa độ:x2+y2 =r2Do tính đối xứng của đường tròn nên ta chỉ cần vẽ cung ¼ hoặc 1/8void put8pixel(int xc, int yc, int x, int y){putpixel(x+xc, y+yc, color);putpixel(y+xc, x+yc, color);putpixel(y+xc, -x+yc, color);putpixel(x+xc, -y+yc, color);putpixel(-x+xc, -y+yc, color);putpixel(-y+xc, -x+yc, color);putpixel(-y+xc, x+yc, color);putpixel(-x+xc, y+yc, color);}1.Thuật toán Bresenham1 Giả sử tại bước i đã vẽ được điểm (xi,yi)Điểm cần vẽ kế tiếp (xi+1, yi+1) là:(xi +1, yi) hay (xi +1, yi -1)Giá trị y thực sự thuộc đường tròn ứng với xi là:y2 = r2 – (xi +1)2Gọi d1 = yi2 – y2 = yi2 –r2 +(xi +1)2d2= y2 - (yi -1)2 = r2 – (xi +1)2 – (yi -1)2Pi = d1-d2 = yi2 – r2 +(xi +1)2 –r2 + (xi +1)2 +(yi-1)2 = 2(xi +1)2 + yi2 +(yi -1)2 -2r2Pi+1 – pi = 2(xi+1 +1)2 + yi+12 + (yi+1 -1)2 – 2r2 – 2(xi +1)2 – yi2 – (yi -1)2 + 2r2 = 4xi + 6 + 2(yi+12 – yi2) -2(yi+1-yi) Pi+1 = pi+4xi + 6 + 2(yi+12 – yi2) -2(yi+1-yi)Vậy:+ nếu pi < 0 thì yi+1 = yi, khi đó pi+1 = pi+4xi+6+Nếu pi >= thì yi+1 = yi-1, khi đó pi+1 = pi + 4(xi-yi)+10Giá trị pi tại điểm đầu tiên (x1,y1) = (0,r) là:P1 = 2+r2+(r-1)2 – 2r2=3-2rvoid CircleBres(int xc, int yc, int r)2 {int x,y,p;x=0; y=r; p=3-2*r;while (x<=y) {put8pixel(xc,yc,x,y);if(p<0) p+ =4*x+6;else{ p+ = 4*(x-y) +10; y--; }x++;}}2.Thuật toán MidpointGọi F(x,y) = x2+y2-r2, ta có:F(x,y){<0 nếu (x,y) nằm trong đường tròn=0 nếu (x,y) thuộc đường tròn>0 nếu (x,y) nằm ngoài đường trònChọn điểm bắt đầu vẽ là (0,r)Giả sử đã vẽ được điểm (xi,yi),Điểm cần vẽ kế tiếp (xi+1,yi+1) là S hay P3 Việc chọn điểm S hau P dựa trên dấu của:Pi=F(Midpoint) = F(xi+1,yi-1/2)+ Nếu pi<0 => chọn S+ Nếu pi>=0 => chọn PMặt khác:pi+1 – pi = F(xi+1 +1, yi+1 -1/2)- F(xi+1, yi-1/2) = [(xi+1 +1)2 + (yi+1 – ½)2 – r2] – [(xi+1)2 + (yi-1/2)2 – r2]= 2xi + 3 (yi+12 – yi2) – (yi+1 – yi)Vậy: + Nếu pi<0 thì yi+1 = yi, khi đó pi+1 = pi + 2xi + 3+ Nếu pi>=0 thì yi+1= yi -1, khi đó pi+1 = pi + 2(xi-yi) +5Giá trị pi tại điểm đầu tiên (x1, y1)=(0,r) là:p1= F(x1+1, y1 -1/2) = f(1, r-1/2) = 5/4 – rvoid CircleMidpoint(int xc, int yc, int r){int x,y,p;x=0; y=r; p=5/4;while (x<=y0{put8pixel(xc,yc,x,y);4 if(p<0) p+ = 2*x +3;else{ p+=2*(x-y0+5; y--; }x++;} }II.Thuật toán tô màu theo đường biên:Ý tưởng:Bắt đầu từ điểm P(x,y) nằm bên trong vùng tô, kiểm tra các điểm lân cận cảu P đã được tô màu hay có phải là điểm biên hay không, nếu không phải là điểm đã tô và không phỉa là điểm biên thì ta sẽ tô màu nó. Quá trình này được lặp laijcho đến khi không còn tô được diểm nào nữa thì dừng.Có hai cách chọn điểm lan cận, đó là chọn 4 hoặc 8 điểm lân cận dối với điểm đang xét.Thủ tục minh hoajthuaatj toán tô màu theo đường biên:Void TOloang(int x, int y, int mauto, int mauvien){ int mau;mau=getpixel(x,y);5 if(mau != mauvien)& (mau != mauto){ Putpixel(x, y,mauto);Toloang(x-1,y, mauto, mauvien);Toloang(x, y+1, mauto, mauvien);Toloang(x+1, y, mauto, mauvien);Toloang(x, y-1, mauto, mauvien);}}=>Nhược điểm của phương pháp đệ quy là =>không thực hiện được khi vùng loang có diện =>tích lớn( dẫn đến tràn Stack1.Phương pháp đệ quy:Bước 1: khởi tạo hang đợi (hoặc stack) với phần tử đầu tiên là P(x,y) đã được tôBước 2: khi hàng đợi (hoặc stack) không rỗng thì:+ Lấy ra từ hang đợi(hoặc stack) một điểm Q.+ tìm các điểm lân cận của Q chưa tô thì tô chúng và đưa chúng vào hang đợi(hoặc stack)Bước 3 này được lặp đi lặp lại cho đến khi hang đợi (hoặc stack) rỗngstruct DS { int x,y;6 struct DS*next; };struct DS*dau;void push(int x, inty){ struct DS*P;P=(DS*) calloc(1,sizeof(DS));P->x=x; P->y=; P->next=NULL;if(dau !=NULl)P->next= dau;dau=P;}Void pop(int *x, int*y){ struct DS*P;P=dau; dau=dau->next;*x=P->x; *y= P->y;free(P);}void tolancan(int x, inty, int mauto, int mauvien){ int mau;mau=getpixel(x,y);if((mau != mauto)&&(mau !=mauvien)){ putixel(x,y,mauto);7 push(x,y);}}Void toloang_stack(int x0, int y0, int mauto, int mauvien){ int x,y;putpixel(x0,y0,mauto);dau=NULL;push(xo,yo);while(dau != NULL){ pop(&x,&y);tolancan(x-1, y, mauto, mauvien);tolancan(x+1, y, mauto, mauvien);tolancan(x, y+1, mauto, mauvien);tolancan(x, y-1, mauto, mauvien);}}Flood Fill/boundary fillScan line fill/ scan conversionĐơn giản Phức tạp hơnThuật toán rời rạc hóa trong không gian màn hìnhThuật toán rời rạc hóa trong đối tượng hoặc/và không gian màn hình8 Yêu cầu gọi hệ thống GetPixel/ValĐộc lập với thiêt bịĐòi hỏi điểm seed Không đòi hỏi điểm seedYêu cầu stack rất lớnYêu cầu stack nhỏIII.Các thuật toán xén hình1.Thuật toán Cohen-sutherlandChia mặt phẳng thành 9 vùng: cửa sổ và 8 vùng xung quanh nó. Mỗi vùng được gán bởi một mã nhị phân 4 bit Giả sử có điểm P(x,y), lúc đó gán mã cho điểm P:Pleft={ 1, nếu Px < xmin Pright={ 1, nếu Px>xmax0, ngược lại 0, ngược lạiPbottom={ 1, nếu Py<yminPtop= { 1, nếu Py>ymax0, ngược lại 0, ngược lại9 Hàm tính mãint ma(point M){ int m=0;if(M.x<min.x) ml=1;if(M.x>max.x) ml=2;if(M.y<min.y) ml=4;if(M.y>max.y) ml=8;return m;}Xét đoạn thẳng AB, ta có các trường hợp sau:1.Nếu (Ma(A)=0000) và (Ma(B)=000) {hay(Ma(A) or Ma(B)=0000} thì=>ClipD(F)=AB2.Nếu (Ma(A) and Ma(B))≠0000) thì=> ClipD(F) = Ø3.Nếu ((Ma(A) and Ma(B))=0000) và (Ma(A)≠0000 hoặc Ma(B)≠0000) thìGiả sử Ma(A)≠0000 { nếu ma(A)=0 ta đổi vai trò A và B}-Nếu Ax=Bx(AB thẳng đứng ) thì+Nếu Ay>ymax (A ở trên) thì Ay=ymax’ 10 [...]... =4*x+6; else { p+ = 4*(x-y) +10; y ; } x++; }} 2 .Thuật toán Midpoint Gọi F(x,y) = x2+y2-r2, ta có: F(x,y){<0 nếu (x,y) nằm trong đường trịn =0 nếu (x,y) thuộc đường trịn >0 nếu (x,y) nằm ngồi đường trịn Chọn điểm bắt đầu vẽ là (0,r) Giả sử đã vẽ được điểm (xi,yi), Điểm cần vẽ kế tiếp (xi+1,yi+1) là S hay P 3 Yêu cầu gọi hệ thống GetPixel/Val Độc lập với thiêt bị Đòi hỏi điểm seed Khơng địi hỏi... ckn,kq; 22 1 .Đường cong Benzier Bài toán: Cho n+1 điểm p0, p1, p2,…,pn được gọi là các điểm kiểm soát (điểm điều khiển). Xây dựng đường cong trơn đi qua 2 điểm p và pn được giới hạn trong bao lồi do n+1 điểm trên tạo ra Thuật toán Casteljau Để xây dựng đường cong P(t), ta dựa trên một dãy các điểm cho trước rồi tạo ra giá trị P(t) ứng với mỗi giá trị t nào đó. Phương pháp này tạo ra đường congdựa... dường thẳng (đường sinh) được quét dọc theo một đường cong P0(u) (đường chuẩn). đường cong P0(u) nằm trên một mặt phẳng nào đó . Gọi d là đường sinh,d=const. P0(u) là đáy dưới. P1(u)là đáy trên. Suy ra d= P0(u)- P1(u)p(u,v)= (1- v).P0(u)+v.P1(u) = P0(u)+(P1(u) -P0(u)).v= P0(u) +d.v Vậy: p(u,v)= P0(u)+d.v Pt mặt trụ : p(u,v)= P0(u)+d.v Dạng quen thuộc của mặt trụ là mặt trụ trònL trong mặt phẳng.. .Đường cong Benzier dực trên (n+1) điểm kiểm soát p0,p1,…,pn được cho bưởi coog thức: P0n ( t)= P(t)= ∑Pk.B nk(t) Tương tự, đối với mặt benzier ta có phương trình sau: P(u,v)= ∑ ∑ P I,k . Bim (u) Bkn(V) Trong trường hợp này khối đa diện kiểm sốt sẽ có (m+1)(n+1) đỉnh. Minh họa vẽ đường cong benzier trong mặt phẳng. Typedef struct { int x; int y; } CPoint; int... hoặc 8 điểm lân cận dối với điểm đang xét. Thủ tục minh hoajthuaatj tốn tơ màu theo đường biên: Void TOloang(int x, int y, int mauto, int mauvien) { int mau; mau=getpixel(x,y); 5 Giả sử tại bước i đã vẽ được điểm (xi,yi) Điểm cần vẽ kế tiếp (xi+1, yi+1) là: (xi +1, yi) hay (xi +1, yi -1) Giá trị y thực sự thuộc đường tròn ứng với xi là: y2 = r2 – (xi +1)2 Gọi d1 = yi2 – y2 = yi2 –r2 +(xi +1)2 d2= y2... Fill/boundary fill Scan line fill/ scan conversion Đơn giản Phức tạp hơn Thuật tốn rời rạc hóa trong khơng gian màn hình Thuật tốn rời rạc hóa trong đối tượng hoặc/và khơng gian màn hình 8 -Danh sách các đỉnh (vertices): lưu tọa đọ các đỉnh. -Danh sách các cạnh (edges) nối gữa các đỉnh đó: lưu 2 đỉnh đầu và cuối của từng cạnh. (hình vẽ) Có nhiều cách để lưu trữ một mo hình WF trên máy tính. Có thể... (ve) veduongthang(A,B);} 2 .Thuật toán chia nhị phân Chia mặt phẳng thành 9 vùng, mỗi vùng được gán bởi một mã nhị phân 4 bit -Ý tưởng của thuật toán như sau: Lấy trung điểm của đoạn thẳng và kiểm tra mã của nó để loại dần các đoạn con khơng chứa giao điểm, và cuối cùng cho điểm giữa hội tụ về giao điểm của đoạn thẳng với hình chữ nhật, kết quả là ta thu được đoạn con nằm trong hình chữ nhật(nếu... int x,y; 6 if(p<0) p+ = 2*x +3; else{ p+=2*(x-y0+5; y ; } x++; } } II .Thuật tốn tơ màu theo đường biên: Ý tưởng: Bắt đầu từ điểm P(x,y) nằm bên trong vùng tô, kiểm tra các điểm lân cận cảu P đã được tơ màu hay có phải là điểm biên hay không, nếu không phải là điểm đã tơ và khơng phỉa là điểm biên thì ta sẽ tơ màu nó. Q trình này được lặp laijcho đến khi khơng cịn tơ được diểm nào nữa thì dừng. Có... P0(u) +d.v Vậy: p(u,v)= P0(u)+d.v Pt mặt trụ : p(u,v)= P0(u)+d.v Dạng quen thuộc của mặt trụ là mặt trụ trònL trong mặt phẳng xoy, lấy P0(u) là đường trịn tâm o bán kính r. Ta có:d=(0,0,h) P0(u)=(r.cos(u),r.sin(u),0) Vậy: {X(u,v)=r.cos(u) Y(u,v)=r.sin(u) 24 P1(u) là đường trong tâm (0,0,h) bán kính r. P0(u)=(r.cos(u),r.sin(u),h) Ta có: p(u,v)=(1-v). P0(u)+ v. P1(u)=v. P0(u) Vạy: p(u,v)= v. P0(u). Hay: {X(u,v)=v.r.cos(u) Y(u,v)=v.r.sin(u) Z(u,v)=h.v với... ngồi hình chữ nhật thì có ít nhất một đoạn hồn tồn nằm ngồi hình chữ nhật. -Thuật tốn: 1.Nếu (Mã(A) = 0000) và Mã(B)=0000) thì =>ClipD(F) = AB 2.Nếu (Mã(A) AND Mã(B))≠0000 thì =>ClipD(F)= Ø 3.Nếu (Mã(A)≠0000) và Mã(B) = 0000) thì: đỏi vai trị của A, B và áp dụng 4 4.Nếu (Mã(A) = 0000) và (Mã(B) ≠0000) thì: P:=A; Q:=B; Trong khi |xP – xQ| + |yP – yQ|>=2 thì: Lấy trung điểm M của PQ Nếu Mã(M)≠0000 . I .Thuật toán vẽ đường trònPhương trình đường tròn có dạng:(x-xc)2 + (y-yc)2 = r2Pt đường tròn có tâm ở gốc tọa độ:x2+y2 =r2Do tính đối xứng của đường tròn. }x++;}}2 .Thuật toán MidpointGọi F(x,y) = x2+y2-r2, ta có:F(x,y){<0 nếu (x,y) nằm trong đường tròn= 0 nếu (x,y) thuộc đường tròn& gt;0 nếu (x,y) nằm ngoài đường