ĐỒ HỌA MÁY TÍNHTìm hiểu và cài đặt các thuật toán vẽ đường cho trường hợp tổng quát... Tất cả các trường hợp của đoạn thẳng còn lại được vẽ dựa trên thuật toán DDA bằng việc hoán đổi vị
Trang 2ĐỒ HỌA MÁY TÍNH
Tìm hiểu và cài đặt các thuật toán vẽ đường cho trường hợp tổng quát
Trang 5(x2,y2)
y2-y1 x2-x1 y1-mx1
x b
Trang 61.Tăng chậm 2.Tăng nhanh
3 Giảm chậm ngược 4 Giảm nhanh ngược
Trang 7- Đối tượng mô tả trong hệ tọa độ thực là đối tượng liên tục, còn đối tượng trong hệ tọa độ thiết bị là đối tượng rời rạc Nên cần thực
hiện việc rời rạc hóa và việc nguyên hóa một cách tối uư nhất.
-Từ đó hình thành các thuật toán khác nhau với những uư thế riêng của nó để tối uư về
mặt tốc độ và sự chính xác.
Trang 8Digital Differential Analyzer
Trang 9Để hiển thị trên lưới nguyên được liền nét
các điểm có tọa độ (xi+1; yi+1) sẽ phải chọn 1
trong 8 điểm có tọa độ (xi + 1;yi + 1 )
Trang 11Lưu đồ thuật toán DDA vẽ đoạn thẳng qua 2 điểm (x1,y1) và (x2,y2) trong trương hợp 1
Trang 12Cài đặt thuật toán DDA trong trường hợp 1
} }
Trang 14Lưu đồ thuật toán DDA vẽ đoạn thẳng qua 2 điểm (x1,y1) và (x2,y2) trong trường hợp 2
Trang 15Cài đặt thuật toán DDA trong trường hợp 2
}
Trang 16Trường hợp 3
Đoạn thẳng giảm chậm với điểm đầu A(x1;y1) ở bên phải trên
và điểm cuối B(xk; yk) ở bên trái dưới và đối xứng của nó qua
Trang 17Lưu đồ thuật toán DDA vẽ đoạn thẳng qua 2 điểm (x1,y1) và (x2,y2) trong trường hợp 3
Trang 18Cài đặt thuật toán DDA trong trường hợp 3
}
Trang 20Lưu đồ thuật toán DDA vẽ đoạn thẳng qua 2 điểm (x1,y1) và (x2,y2) trong trường hợp 4
Trang 21Cài đặt thuật toán DDA trong trường hợp 4
}
Trang 22Luư đồ thuật toán DDA trong tất cả các trường hợp vẽ đường thẳng
step = abs(Dx) step = abs(Dy)
x = x + xinc
y = y + yinc Putpixel(Round(x),Round(y),c)
NO
Trang 23Cài đặt thuật toán DDA trong trường hợp Tổng quát
Void DDA_line1(int x1,int y1,int x1,int y2, Color color){
double x,y; int step;
if(abs(x2-x1)>abs(y2-y1)) step=abs(x2-x1);
x+=m;
y+=n;
putpixel(Round(x),Round(y),color); }
}
Trang 24Ví dụ Demo vẽ đường thẳng từ điểm A(2, 10) đến điểm B(21, 16) (0 < m < 1)
điểm A(9, 1) đến điểm B(17,12) (m > 1) bằng thuật toán DDA.
Trang 25Tất cả các trường hợp
của đoạn thẳng còn lại được vẽ dựa trên thuật toán DDA bằng việc
hoán đổi vị trí của điểm đầu và điểm cuối hoặc lấy đối xứng qua các
trục tọa độ của 4 trường hợp trên.
Trang 26• Việc sử dụng công thức để tính giá trị y tại mỗi bước đã giúp cho thuật toán DDA nhanh hơn hẳn so với
cách tính y từ phương trình y=mx +b do khử được phép
nhân trên số thực Tuy nhiên, việc cộng dồn giá trị thực m vào y có thể sẽ tích lũy sai số làm cho hàm làm tròn có kết quả sai dẫn tới việc xác định vị trí của điểm vẽ ra bị chệch hướng so với đường thẳng thực Điều này chỉ xảy ra khi vẽ đoạn thẳng khá dài
• Tuy đã khử được phép nhân số thực nhưng thuật toán DDA vẫn còn bị hạn chế về mặt tốc độ do vẫn còn phép toán cộng
số thực và làm tròn Có thể khắc phục thao tác cộng số thực
m và làm tròn trong thuật toán bằng cách nhận xét
m=Dy/Dx với Dy, Dx là các số nguyên
sau truoc
Trang 28- Thuật toán Bresenham đưa ra cách chọn
yi+1 là yi hay yi+1 theo một hướng khác sao cho có thể tối ưu hóa về mặt tốc độ so với thuật toán DDA Vấn đề mấu chốt ở đây là làm thế nào để hạn chế tối đa các phép
toán trên số thực trong thuật toán.
- Ý tưởng chính của thuật toán Bresenham
là việc so sánh khỏang cách giữa tọa độ y thực tại vị trí x i+1 với các tọa độ y nguyên trên và dưới nó.
Trang 29*** Phương pháp của thuật toán Bresenham
• Xét các hiệu khoảng cách của tung độ thực y so với các
Trang 30pi +1 - pi= (2Δx (dy.xi+1 - 2Δx (dx.yi+1+ C) - (2Δx (dy.xi - 2Δx (dx.yi+ C )
=> Pi +1 = pi + 2Δx (dy - 2Δx (dx ( yi+1 - yi)
- Nếu pi< 0 : chọn điểm S, tức là yi +1= yi và pi +1 = pi + 2Δx (dy
- Nếu pi≥ 0 : chọn điểm P, tức là yi +1= yi +1 và pi +1 = pi + 2Δx (dy - 2Δx (dx
- Giá trị p0được tính từ điểm vẽ đầu tiên (x0,y0) theo công thức :
Trang 32Giải thuật trong trường hợp 1:
Trang 33Luư đồ thuật toán Bresenham trường hợp 1: |Dy|<=|Dx|
Trang 34Cài đặt thuật tóan Bresenham trong trường hợp 1
int Dx = x2 – x1, Dy = y2 – y1; int x = x1, y = y1;
int p = 2 * Dy – Dx ; int const1 = 2 * Dy , const2 = 2 * (Dy-Dx); putpixel(x, y, color) ;
int dx =(Dx>0)? 1:-1 ,dy=(Dy>0)? 1:-1;
if(abs(Dy) <= abs(Dx)) {
while(x != x2) {
}
Trang 35AB
Trang 36Giải thuật trong trường hợp 2
Trang 37Luư đồ thuật toán Bresenham trong trường hợp 2: |Dy|>|Dx|
Trang 38Cài đặt thuật toán Bresenham trong trường hợp 2
int Dx = x2 – x1, Dy = y2 – y1; int x = x1, y = y1;
int p = 2 * Dx – Dy ; int const1 = 2 * Dx , const2 = 2 * (Dx-Dy); putpixel(x, y, color) ;
int dx =(Dx>0)? 1:-1 ,dy=(Dy>0)? 1:-1;
if(abs(Dy) > abs(Dx)) {
while(y != y2) {
}
Trang 39Ví dụ Demo vẽ đường thẳng bằng thuật toán Bresenham qua hai điểm A(5,8) và B(20,13)
Ta có Dy=5, Dx=15; p=2Dy-Dx=-5 const1=2Dy=10, const2=2(Dy-Dx)=-20
-5+1 0=5
Trang 40• Thuật toán Bresenham chỉ làm việc trên số nguyên và các thao tác trên số nguyên chỉ là phép cộng và phép dịch bit (phép nhân 2) điều này là một cải tiến làm tăng tốc độ đáng kể so với thuật toán DDA.
• Ý tưởng chính của thuật toán nằm ở chỗ xét
bằng các phép toán đơn giản trên số nguyên
• Tuy nhiên thuật toán Bresenham xây dựng phức tạp hơn thuật toán DDA.
Trang 42Thuật toán MidPoint đưa ra cách chọn yi+1 là yi hay yi +1 bằng cách so sánh điểm thực Q với điểm MidPoint là trung điểm của S
và P Ta có :
-Nếu điểm Q nằm dưới điểm MidPoint, ta chọn S
- Ngược lại nếu điểm Q nằm trên điểm MidPoint ta chọn P
Ta có dạng tổng quát của phương trình đường thẳng là :
Ax + By + C = 0 Với A = y2 –y1; B = - (x2 – x1) ; C = x2y1 -x1y2
Đặt F(x,y)=Ax + By + C thì ta có nhận xét F(x,y) <0,nếu (x,y) nằm phía trên đường thẳng
F(x,y) = 0 nếu (x,y) nằm thuộc đường thẳng
F(x,y) > 0 nếu (x,y)nằm phía dưới đường thẳng
Lúc này việc chọn điểm S hay P được đưa về việc xét dấu của pi =
2F(midpoint) = 2F(xi+1;yi+1/2 )
Trang 43Xây dựng pi trong trường hợp 0<=m<=1, và Dx <0
Giống như một số thuật toán khác, ta không tính toán trực tiếp các giá trị pi
để chọn điểm tiếp theo mà tính toán dựa trên kết quả của bước trước.
Xét pi+1-pi=2F(xi+1+1,yi+1+1/2)-2F(xi+1,yi+1/2)
Thay F(x,y)=Ax+By+C với A=Dy, B=-Dx vào ta được kết quả 2Dx(yi+1-yi) (1)
pi+1-pi=2Dy-Nhận xét:
Khi yi+1=yi ta có (1) pi+1=pi+2Dy
Khi yi+1=yi+1 ta có (1) pi+1=pi+2Dy-2Dx=pi+2(Dy-Dx)
Giá trị p0 ứng với điểm ban đầu được tính:
p0=2F(xđầu+1, y đầu+1/2)=2[A(xđầu+1)+B(yđầu+1/2)+C] =2Dy-Dx
Trang 45Giải thuật bằng thuật toán Midpoint trong trường hợp 1
Trang 46Luư đồ thuật toán Midpoint trường hợp 1: |Dy|<=|Dx|
Trang 47Cài đặt thuật tóan Midpoint trong trường hợp 1
int Dx = x2 – x1, Dy = y2 – y1; int x = x1, y = y1;
int p = 2 * Dy – Dx ; int const1 = 2 * Dy , const2 = 2 * (Dy-Dx); putpixel(x, y, color) ;
int dx =(Dx>0)? 1:-1 ,dy=(Dy>0)? 1:-1;
if(abs(Dy) <= abs(Dx)) {
while(x != x2) {
}
Trang 48AB
Trang 49Giải thuật bằng thuật toán MidPoint trong trường hợp 2
Trang 50Luư đồ thuật toán Midpoint trong trường hợp 2: |Dy|>|Dx|
Trang 51Cài đặt thuật toán Midpoint trong trường hợp 2
int Dx = x2 – x1, Dy = y2 – y1; int x = x1, y = y1;
int p = 2 * Dx – Dy ; int const1 = 2 * Dx , const2 = 2 * (Dx-Dy); putpixel(x, y, color) ;
int dx =(Dx>0)? 1:-1 ,dy=(Dy>0)? 1:-1;
if(abs(Dy) > abs(Dx)) {
while(y != y2) {
}
Trang 52Mở rộng thuật toán Midpoint trong các trường hợp vẽ
đường thẳng với m bất kì
•***Trường hợp đặc biệt m = : Đoạn thẳng song song trục tung nên rất đơn giản khi vẽ.
•***Trường hợp -1<=m<=1 :Sử dụng các công thức của thuật toán vẽ
trong trường hợp 0 < = m <=1, Dx >0 và thay đổi một số điểm sau:
• Nếu Dx < 0 thì bước nhảy của x sẽ thay bằng -1 tương tự nếu Dy <0,
bước nhảy của y cũng sẽ là -1.
•Thay Dx bằng abs(Dx), Dy = abs(Dy) trong tất cả các công thức có
chứa Dx,Dy
•*** Trường hợp m<= -1 hay m>=1
•Thay đổi vai trò của x và y cho nhau, thay đổi vai trò của Dx và Dy
cho nhau trong tất cả các công thức
•Thực hiện nguyên tắt về bước nhảy và thay đổi Dx, Dy như trong
trường hợp -1< = m < =1
Trang 53Dựa vào tính chất đối
xứng của đường tròn ta
có thể mở rộng các
thuật toán Bresenham
và Midpoint cho việc vẽ đường tròn
Trang 55(-x,-y) (-y,-x)
Trang 56THUẬT TOÁN VẼ ĐƯỜNG TRÒN
BẰNG MIDPOINT
Do tính đối xứng của đường tròn nên ta chỉ cần vẽ 1/8 cung tròn, sau đó lấy đối xứng là vẽ được cả đường tròn.
Thuật toán MidPoint đưa ra cách chọn yi+1 là yi hay yi-1
bằng cách so sánh điểm thực Q(xi+1,y) với điểm giữa MidPoind là trung điểm của S1 vàS2.
Chọn điểm bắt đầu để vẽ là (0,R) Giả sử (xi, yi) là điểm nguyên đã tìm được ở bước thứ i (xem hình 1.8), thì điểm (xi+1, yi+1) ở bước i+1 là sự lựa chọn giữa S1 và S2.
• Xi+1 = x + 1
• yi+1= yi – 1 hoặc yi;
Trang 57THUẬT TOÁN VẼ ĐƯỜNG TRÒN
BẰNG MIDPOINT
Đặt F(x,y) = x2 + y2 - R2 , ta có :
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.
Xét Pi = F(MidPoint) = F(xi +1, yi - 1/2) Ta có :
- Nếu Pi < 0 : điểm MidPoint nằm trong đường tròn
Khi đó, điểm thực Q gần với điểm
S1 hơn nên ta chọn yi+1 = yi
- Nếu Pi>= 0 : điểm MidPoint nằm ngòai đường tròn Khi đó, điểm thực Q gần với điểm
S2 hơn nên ta chọn yi+1 = yi - 1.
Trang 58- Nếu Pi < 0 : chọn yi+1 = yi Khi đó Pi+1 = Pi+ 2xi +3
- Nếu Pi >= 0 : chọn yi+1 = yi - 1 Khi đó Pi+1 = Pi+ 2xi - 2yi +5
- Piứng với điểm ban đầu ( x0 , y0 ) = (0,R) là:
(xi,yi)
Trang 59Luư đồ thuật toán Midpoint cho đường tròn
Trang 60Cài đặt thuật toán Midpoint cho đường tròn
void MidpointCircle(int a,int b,int r,Color c){
} else { p+=2*(x-y)+5;
y ;
} x++;
put8pixel(x,y,a,b,c);
}
}
Trang 61Ví dụ Demo đường tròn bằng thuật toán Midpoint
Midpointcircle(15,16,13,Color(255,0,0));
Trang 62Vẽ đường tròn bằng thuật toán
(xi,yi)
d1 d2
Trang 63XÂY DỰNG THUẬT TOÁN BRESENHAM VẼ ĐƯỜNG TRÒN
Ta có :
d1 = (yi)2 - y2 = (yi)2 - (R2- (xi + 1)2 )
d2 = y2 - (yi - 1)2 = (R2- (xi + 1)2 ) - (yi - 1)2Pi = d1 - d2
* Tính Pi+1 - Pi
=> Pi+1 = Pi + 4xi + 6 + 2((yi+1)2 - (yi)2 ) - 2(yi+1 - yi)
- Nếu Pi < 0 : chọn yi+1 = yi Khi đó Pi+1 = Pi+ 4xi +6
- Nếu Pi >= 0 : chọn yi+1 = yi - 1 Khi đó Pi+1 = Pi+ 4(xi
- yi ) + 10
- P0ứng với điểm ban đầu ( x0 , y0 ) = (0,R) là: P0= 3 - 2R.
Trang 64Luư đồ thuật toán Bresenham cho đường tròn
begin
P= 3 - 2R x=0 ; y= R;
Putpixel8(x,y,c);
P= 3 - 2R x=0 ; y= R;
Trang 65Cài đặt thuật toán Bresenham cho đường tròn
void Bres_circle(int a,int b,int r,Color c){
if(p<0) { p+=4*x+6;
} else { p+=4*(x-y)+10;
y ;
} x++;
put8pixel(x,y,a,b,c);
} }
Trang 66Ví dụ Demo thuật toán Bresenham vẽ đường tròn
Bres_circle(25,26,17,Color(225,0,0));
Trang 67Ngoài ra ta còn có thể
mở rộng thuật toán
Bresenham cho việc vẽ
đường tròn và các đường conic
Trang 69XÂY DỰNG THUẬT TOÁN
=> Pi+1 = Pi + 2((yi+1)^2 - (yi)^2 ) - 2(yi+1 - yi)+2b^2/a^2(2xi+3)
- Nếu Pi < 0 : chọn yi+1 = yi Khi đó Pi+1 = Pi+2b^2/a^2(2xi+3)
- Nếu Pi >= 0 : chọn yi+1 = yi - 1
Khi đó Pi+1 = Pi+2b^2/a^2(2xi+3)+4(1-yi)
- Pi ứng với điểm ban đầu ( x0 , y0 ) = (0,b) là:
P0=2b^2/a^2-2b+1
Trang 70putpixel4(x,y,color)
y++;
putpixel4(x,y,color)
Trang 71Cài đặt thuật toán Bresenham cho Elip
Trang 72Ví dụ Demo vẽ đường Elip bằng thuật toán Bresenham
ellipse(23,28,22,10,Color(0,225,0));
Trang 74Đề tài của nhóm 9 đến đây xin kết thúc Vì thời gian và kiến thức có hạn nên chắc
chắn đề tài của chúng em còn nhiều vấn đề sai sót, rất mong được sự giúp đỡ và việc
đóng góp ý kiến của thầy Điều đó giúp
chúng em hoàn thành những đề tài sau này tốt hơn Chúng em xin cảm ơn thầy Kính chúc thầy sức khỏe dồi dào.
Cảm ơn