B ắ t đầu từ điểm Px,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 t
Trang 1void put8pixel(int xc, int yc, int X, int y)
putpixel(x+xc, y+yc, color);
putpixel(y+xc, x+yc, color);
puipỉxel(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);
l.Thuâc toán Bresenham
Trang 2G iả 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à:
y 2 = 1-2 - (xi +1)2
G ọi d l = yi2 - y2 = yi2 -r 2 +(xi +1)2
d2= y2 - (yi -1)2 = r2 - (xi +1)2 - (yi -1)2
Pi = d l-d 2 = yi2 - r2 +(xi +1)2 -r 2 + (xi +1)2 + (y i-l)2
= 2(xi +1 )2 + yi2 +(yi -1)2 -2r2
Pi+1 - pi = 2 (x i+ l +1)2 + yi+12 + (yi+1 -1)2 - 2r2 - 2(xi +1)2
- yi2 - (yi -1)2 + 2r2
= 4xi + 6 + 2(yi+12 - y i 2 ) -2 (y i+ l-y ỉ)
^ Pi+1 = pi+4xi + 6 + 2(yi+12 - yi2) -2(yi+1-yi)
V ậ y :
+ n ê u pi < 0 thì y i + 1 = y i , khi đó p i + 1 = p i + 4 x i + 6
+N êu pi > = thì yi+1 = yi-1, khi đó pi+1 = pi + 4(xi-yi)+10
Giá trị pi tại điểm đầu tiên (x l,y l) = (0,r) là:
P1 = 2 + r2 + (r-l)2 - 2r2=3-2r
void CircleBres(int xc, int yc, int r)
Trang 32.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 Irong đường tròn
= 0 nếu (x,y) thuộc đường tròn
>0 nếu (x,y) nằm ngoài đường tròn
Chọn điểm b ắt đầu v ẽ là (0,r)
G iả sử đã v ẽ được điểm (xi,yi),
Đ iểm cần v ẽ k ê tiếp ( x i+ l,y i+ l) là s hay p
Trang 4V iệ c chọn điểm s hau p dựa trên dấu của:
Pi=F(M idpoint) = F (x i+ l,y i-l/2 )
+ Nêu pi<0 = > chọn s
+ Nêu p i>=0 = > chọn p
M ặ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 - Vì)2 - r2] - [(x i+ l)2 + (y i-l/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 p i>=0 thì y i+ l= yi -1, khi đó pi+1 = pi + 2(xi-yi) +5
Giá trị pi tạ i điểm đẳu tiên (x l, y l)= (0 ,r) là:
Trang 5B ắ 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 lô đượ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 T01oang(int X, int y, int mauto, int mauvien)
{ int mau;
mau=getpixel(x,y);
Trang 6if(mau != mauvien)& (mau != mauto)
{ Putpixel(x, y.mauto);
T oloang(x-l,y, mauto, mauvien);
Toloang(x, y+1, mauto, mauvien);
T o loan g(x+l, y, mauto, mauvien);
Toloang(x, y-1, mauto, m auvien);}}
=>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 Stack
B ư ớ c 1: khởi tạo hang đợi (hoặc stack) với
phần lử đắu tiên là P(x,y) đã được tô
B ư ớ c 2: khi hàng đợi (h oặ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 (h oặc stack) rỗng
struct DS { int x,y;
Trang 8Void toloang_stack(int xO, int yO,
int mauto, int mauvien){ int x,y;
tolancan(x-l, y, mauto, mauvien);
tolancan(x+l, y, mauto, mauvien);
tolancan(x, y +1, mauto, mauvien);
tolancan(x, y-1, mauto, m auvien);}}
Thuật toán rời
Trang 9Yê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ớn
Yêu cắn stack nhỏ
G iả 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>xmax
0, ngược lại
0, ngược lạ i
Pbottom={ 1, nêu Py<ymin
Ptop= { 1, nếu Py>ymax
0, ngược lại
0, ngƯỢc lại
Trang 10X ét đoan thẳng A B ta có các trường hơp sau:
1.N êu (M a(A )=0000) và (M a(B )=000)
{hay(M a(A ) or M a (B )=0000} thì
=>C lip D (F)=A B
2 N êu (M a(A) and M a (B ))*0000) thì
= > ClipD(F) = 0
3.N êu ((M a(A) and M a(B ))=0000) và
(M a(A )*0000 h oặc Ma(B)*OOỮO) thì
G iả sử M a(A )*0000 { nêu m a(A)=0
ta đổi vai trò A và B }
-N êu A x =B x (A B thẳng đứng ) thì
+N êu Ay>ymax (A ở trên) thì Ay=ym ax’
Trang 11ngưỢc lại (A ở dưới) Ay=ymin
= > C lipD (F)=A B
-NgƯỢc lạ i (trường hợp A x^Bx):
+Tính h ệ sô góc m =(By-A y)/(Bx-A x)
{đ ể tính giao của A B với HCN}
Vì A nằm ngoài hình chữ nhật nên:
+N êu Ax<xmin thì thay A
bởi điểm giao của AB với cạnh trái(nối dài) của HCN
+N êu Ax>xm ax thì thay A
bởi điểm giao của Ab với cạnh phải(nối dài) cua HCN
+N êu Ay<ymin thì thay A
bởi điểm giao của AB với cạnh dưới(nối dài) của HCN
+N êu Ay>ymax thì thay A
bởi giao điểm của Ab với cạnh trên(nối dài) của HCN
Quá trình lặp lại này
dừng khi x ả y ra m ột trong hai trường hỢp lhay 2
void ClipCohen(Point A, oint B, Point wmin, Point wmax)
{ int thoat,ve; double m;
thoat=0; v e = l;
Trang 12{ if((ma(A) I m a(B )==0) thoat=l;
else if((m a(A )& m a(B ))!=0){th oat=l; v e=0}
else { if(m (A )==0) hoanvi(&A,&B);
if(A x==B x)
{ if(A.y>w max.y) A.y=wmax.y;
else A.y=wm in.y;}
else{ m =(double)(B.y-A.y)/(b.x-A.x);
if(A x<w m in.x){ A y=A y+(w m in.x-A x)*m ;
A,x=wm in.x; }
Else if(A x>w m ax.x){
A.y=A y+(w m ax.x-A x)*m ;
Trang 13A.y=wmax.y; } } } }//end while
if (ve) veduongthang(A.B);}
2.Thuât toán chia nhi 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
Trang 14-Ý nghĩa hình học của mệnh đề:
Nêu cả ba điểm A, B, M đều ở ngoài hình chữ
nhật thì có ít nhất m ột đoạn hoàn toàn nằm ngoài hình chữ nhật
Trong khi |xP - xQI + lyP - yQ|>=2 thì:
L â y trung điểm M của PQ
Trang 15P:=A; Q :=B ;
L ấy M: trung điểm PQ;
Khi (Mã(M)^OOOO) và (|xP-xQ| + |yP-yQ|>=2) thi:
if((M a(A )|M a(B))==0) VeDuongThang(A,B);
if((M a(A )& M a(B))!=0) return;
if((M a(A )!=0)& & (M a(B )=0)) H oanVi(&A,&B);
if((M a( A )= = 0 )& & (M a (B )!=0))
{ P=A; Q =B ;
w hile((abs(P.x-Q x)+abs(P.y-Q y)).2)
Trang 16w hile((M a(M )!=0)& & ((abs(P.x-Q x)+abs(P y-Q y))>2))
{ if((M a(P)& M a(M )!=0) P=M ;
Mô hình khung k ết nối (W F-W ireFrame model)
thể hiện hình dáng của m ột đôi tƯỢng 3D bởi 2 danh sách:
Trang 17-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,
typedef slrucl loado3D
{ int x; int y; int z; }
typedef slrucl KieuCanh
{ int dau; int cuoi; }
typedef struct WireFrame
Trang 18Mô hình các m ặt đa giác(Polygon Mesh model)
thể hiện hình dáng của một đối tượng 3D bởi 2 danh sách
-Danh sách các đỉnh
-Danh sách các m ặt: lưu thứ tự các đỉnh tạo nên m ặt đó
(hình v ẽ)
Chúng ta có thể đưa ra nhiều cấu trúc dữ
liệu khác nhau đ ể lull trữ cho đa giác Dưới
đây là một kiểu cấu trúc:
typedef struct loado3D
{ int x; int y; int z; }
V B iểu d iễn đ ư ờ n g và m á t cong:
Trang 19Ỉ.D ư ờ n ạ cong Benzier
Bài toán: Cho n+1 điểm pO, p Ị p 2, ,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 Caste]jau
Đ ể 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 trên m ộl
dãy các b ư ớ c nội suy tuyến tính hay nội suy
khoảng giữa(In-Betweening)
với 3 điểm PO, P l, P2 ta có thể xây dựng
một Parabol nội suy từ 3 điểm này bằng cách chọn
một giá trị t e [0,1] rồi chia đoạn P0P1 theo tỉ lệ t,
ta được điểm P01, trên P0P1 Tương t ự , ta chia
tiếp P1P2 cũng theo tỉ lệ t, ta được P l l Nôi P01 và P l l
lạ i lấ y điểm trên P 01P11 chia theo tỉ lệ t, ta được P02
Trang 20-Tổng quát hóa ta có thuật toán
Casteljau cho (n+1) điểm kiểm
soát:
G iả sử ta có tập điểm : P0,P1,P2,
,P n
v ớ i mỗi giá trị t cho trước, ta tạo
ra điểm Pir(t) ở thê ệ thứ r, từ thê
hệ thứ (r-1) trước đó, ta có:
Pir(t)= (l-t).P ir-l(t)+ t.P i+ lr-l(t)
( r = 0 ,l, ,n và i= 0 , ,n -r)
Trang 21T h ê hệ cuối cùng: POn(t)=X P i.(l-
t)n-i.ti.Cni
ĐƯỢc gọi là dường cong benzier
của các điểm P 0 ,P l,P 2 , ,P n
Các điểm pi, i= 0 ,l , ,n gọi là các
điểm kiểm soát hay các điểm beier
Đa gics tạo bởi các điểm kiểm soát
gọi là đa giác kiểm soát hay đa giác
benziei
Đ ường cong benzier dựa trên (n+1)
điểm kiểm soát P 0,P l,P 2, ,P n
được cho bưởi công thức:
POn ( t)=P(t)= Xpk.B nk(t)
Trong đó: P(t): là m ột điểm trong
m ặt phẳng h oặc trong không gian
B nk(t): gọi là đa thức Bernstrin,
được cho bởi coog thức:
B nk(t)=Cnk (l-t)n-k.tk =(n!/k!(n-
k)! )(l-t)n-t.tk với n>=k
M ỗi đa thức Bernstein có b ậ c là n
thong thuowgf ta còn gọi các B
nk(t) là các hàm trộn
Trang 22Đường cong Benzier dực trên (n+1)
điểm kiểm soát pO,pl, ,pn được
cho bưởi coog thức:
POn ( 0 = P (t)= £ P k B nk(t)
Tư ơng tự, đối với m ặt benzier ta
có phương trình sau:
P(u,v)— X ỵ p I,k Bim (u) Bkn(V)
Trong trường hỢp này khôi đa
diện kiểm soát sẽ có (m + l)(n + l)
Trang 23CPoint TPt(CPonit p[ ],float t,int n)
{CPoint Pt; float B;int K;
Trang 24M ặt trụ là m ặt được tạo ra khi m ột
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
P l(u )là đáy trên
Suy ra d= P0(u)- Pl(u)p(u,v)= (1-
Trang 25với (0 < = V < = 1 ; 0 < =u< = 2tt
thủ tụ c m ặ t tr ụ :
void DrawCylinder( float R,floal h){
Point3D P; Point2D P1 ; doule
theo một đường cong phawmgr cho
trước các duowgf thẳng luôn di
qua m ột điểm cố định gọi là đỉnh
của m ặt nón
P0(u) tròng với gốc tọa độ o
Trang 26P l(u ) là đường trong tâm (0,0,h)
void DrawCone( float R ,float h)
{ Point3D P; Point2D P1 ; doule
Trang 27void DrawSphere( float R)
{ Point3D P; Point2D P1 ; doule