Professional Documents
Culture Documents
C3 - Thuật toán vẽ đường
C3 - Thuật toán vẽ đường
Điểm
Đường thẳng
Tam giác
Đường tròn
Đường cong
2
Màn hình điểm
-Chúng ta cần tọa độ màn ảnh thực 2D để chỉ rõ vị trí các điểm ảnh.
-Các chi tiết của các hệ thống như vậy là biến đổi theo các API.
-Nhưng phổ biến nhất là sử dụng lưới giá trị nguyên cho các tâm
điểm ảnh, điểm ảnh trên ở vị trí trung tâm cách biên 0.5.
3
1
THUẬT TOÁN
VẼ ĐOẠN THẲNG
4
Khái niệm đoạn thẳng
5
Khái niệm đoạn thẳng
Chuyển đổi đường quét (Rasterization)
Biến đổi đường liên tục thành rời rạc (Sampling)
Scan conversion = Sampling
y 2 y1
y x x1 y1
x 2 x1
7
Khái niệm đoạn thẳng
Để đơn giản giải thuật chúng ta chỉ xét các đường
thẳng có hệ số góc dương và nhỏ hơn 1 để đảm bảo
sự thay đổi của x sẽ lớn hơn của y.
y1<y2 y1<y2
-1 > k > - 1<k<
x1<x2
0k1
x2<x1
0 k -1
(x2, y2)
y2<y1 y2<y1
1<k< -1 > k > -
8
Các thuật toán vẽ đoạn thẳng
9
1.1. Thuật toán DDA
DDA- Digital Defferencial Analyzer = Finite defferences
- Xét các đường thẳng có hệ số góc dương và nhỏ hơn 1 để đảm bảo sự thay
đổi của x sẽ lớn hơn của y.
- Giả sử tại bước thứ i ta đã xác định được xi và yi. Ta cần xác định bước thứ
i+1
xi+1=xi +1
- Giá trị của y sẽ tương ứng từ phương trình sau:
yi+1= yi+ k(xi+1- xi);
yi+1= yi+ k
10
1.1. Thuật toán DDA
11
1.1. Thuật toán DDA
12
1.1. Thuật toán DDA
13
1.2. Thuật toán Bresenham (line)
yi+1
Giả sử vừa vẽ điểm tại (xi, yi), bây giờ y = ax + b
14
1.2. Thuật toán Bresenham (line)
15
1.2. Thuật toán Bresenham (line)
Xét đoạn thẳng có hệ số góc 0k1.
Điểm vừa chọn là (x,y) -> điểm tiếp theo sẽ vẽ là
(x+1,y) hay (x+1, y+1).
16
1.2. Thuật toán Bresenham (line)
Nhận xét rằng do Dx >0 nên dấu của biểu thức d1-d2
cũng chính là dấu của pi. Hay nói một cách khác, nếu
tại bước thứ i ta xác định được dấu của pi thì xem
như ta xác định được điểm cần chọn ở bước (i+1).
17
1.2. Thuật toán Bresenham (line)
void LineBres (int x1, int y1, int x2, int y2)
{
int Dx, Dy, p, Const1, Const2;
int x, y;
Dx = x2 - x1; Dy = y2 - y1;
p = 2*Dy - Dx; // Dy <<1 - Dx
Const1 = 2*Dy; // Dy <<1
Const2 = 2*(Dy-Dx); // (Dy-Dx) <<1
x = x1; y = y1;
putpixel(x, y, Color);
19
1.2. Thuật toán Bresenham (line)
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 dấu pi để quyết
định điểm kế tiếp.
Sử dụng công thức truy hồi pi+1 - pi để tính pi bằng các phép
toán đơn giản trên số nguyên.
Thuật toán này cho kết quả tương tự như thuật toán DDA.
20
1.3. Thuật toán trung điểm (line)
Pitteway công bố 1967, Van Aken cải tiến 1984
Giả sử ta đã chọn P để vẽ, xác định pixel tiếp theo tại P hay S
Giao của đường thẳng với Xp+1 tại Q, M là trung điểm của P và S
Ý tưởng: M nằm phía nào của đường thẳng, nếu M phía trên
đường thẳng thì chọn S, ngược lại chọn P.
Nhiệm vụ: Xác định M ở đâu.
M”
yp+1/2
P
Q M’
M yp+1/2 yp+1/2
S
O=(xp, yp) xp+1 xp+2
21
1.3. Thuật toán trung điểm (line)
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 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 chọn P.
22
1.3. Thuật toán trung điểm (line)
23
1.3. Thuật toán trung điểm (line)
procedure MidpointLine(x0, y0, x1, y1, color: integer)
{
int: dx, dy, x, y, d, incrS, incrP; while x<x1
dx := x1 – x0; {
dy := y1 – y0; if d<=0 //Select S
d := 2*dy-dx; {
incrS := 2*dy; d := d+incrS;
incrP := 2*(dy-dx); x := x+1
}
x :=x0;
else //Select P
y :=y0;
{
putpixel(x, y, color);
d := d+incrP;
x :=x+1;
y :=y+1
Nhận xét rằng thuật toán MidPoint cho kết }
quả tương tự như thuật toán Bresenham putpixel(x, y, color);
} {while}
}
24
Thuộc tính của đường vẽ
25
2
CÁC THUẬT TOÁN
VẼ ĐƯỜNG TRÒN
Một số tính chất đường tròn
Thuật toán Bresenham
Thuật toán trung điểm
26
Tính chất của đường tròn
Tương tự như vẽ đoạn thẳng, đường
tròn đồ họa hình thành bởi các pixel
gần đường tròn toán học nhất
(Rasterization).
Một vài tính chất cơ bản:
Vẽ đường tròn tâm tại gốc tọa độ sau
đó dịch chuyển đến vị trí mong muốn
Tính đối xứng: khi biết tọa độ 1 điểm
(-y, x) (y, x)
dễ dàng suy ra tọa độ của 7 điểm
còn lại
(-x, y) (x, y)
Sử dụng phương trình để tính tọa độ 450
đường tròn -> dấu phảy động. (-x, -y)
Các thuật toán tối ưu khác (x, -y)
27
2.1. Thuật toán Bresenham
Ý tưởng
Giả sử tại bước thứ i ta đã xác định được (xi,yi)
Tại bước thứ i+1
Ta có xi+1 = xi +1
Gọi yi+1 là giá trị chính xác của tung độ tương ứng với điểm
có hoành độ là (xi +1)
d1 là khoảng cách giữa yi và yi+1
d2 là khoảng cách giữa yi+1 và (yi -1)
Khi đó nếu d1 < d2 thì yi+1 = yi
Ngược lại yi+1 = yi – 1
28
2.1. Thuật toán Bresenham
29
2.1. Thuật toán Bresenham
xi+1
30
2.2. Thuật toán trung điểm
Ý tưởng thuật toán: Khi đã vẽ điểm P tại (xp, yp), phải
quyết định điểm vẽ tiếp theo là E hay SE
Phương trình đường tròn
F ( x, y ) x 2 y 2 R 2 P=(xp, yp)
E
F(x,y)=0 -> (x,y) trên đường tròn ME
M
F(x,y)<0 -> (x,y) trong đường tròn
SE
F(x,y)>0 -> (x,y) ngoài đường tròn MSE
31
Thuật toán trung điểm vẽ đường tròn
Biến quyết định d: giá trị hàm tại điểm giữa M
d old F ( x p 1, y p 12 ) ( x p 1) 2 ( y p 12 ) 2 R 2
Nếu dold<0 thì chọn E, xp tăng 1, yp giữ nguyên.
d new F ( x p 2, y p 12 ) ( x p 2) 2 ( y p 12 ) 2 R 2
d new F ( x p 2, y p 3 2 ) SE
MSE
( x p 2) ( y p ) R
2 3 2
2
2
32
2.2. Thuật toán trung điểm
SE
MSE
Đặt biến quyết định mới h=d-1/4, ta có:
h 14 54 R
h 1 R
33
2.2. Thuật toán trung điểm
procedure MidpointCircle(radius, color: integer);
{Giả sử tâm đường tròn tại gốc tọa độ}
var
procedure CirclePoints(x, y,
x, y: integer; d: real;
color: interger); begin
begin x:=0;
y:=radius;
WritePixel(x,y, color);
d:=1-radius;
WritePixel(y,x, color); CirclePoints(x, y, color);
while y>x do
WritePixel(y,-x, color); begin
WritePixel(x,-y, color); if d<0 then {Chọn E}
begin
WritePixel(-x,-y, color); d:=d+2*x+3;
WritePixel(-y,-x, color); x:=x+1
end
WritePixel(-y,x, color); else { Chọn SE }
WritePixel(-x,y, color); begin
d:=d+2*(x-y)+5;
end; x:=x+1;
y:=y-1
end;
CirclePoints(x, y, color);
end {while}
end;
34
2.3. Thuật toán trung điểm (eclíp)
j component
Gradient vector
SE
Region 1
S SE
Region 2
i component
35
2.3. Thuật toán trung điểm (eclíp)
j component
Gradient vector
thành phần j
SE
a y b x
2 2 Region 1
S SE
Region 2
i component
36
2.3. Thuật toán trung điểm (eclíp)
Ý tưởng: Đánh giá hàm tại điểm giữa hai tọa độ pixel để chọn
vị trí tiếp theo để vẽ. Dấu của nó cho biết điểm giữa nằm trong
hay ngoài elíp.
Với vùng 1:
Tính biến quyết định d=F(x,y)=F(xp+1, yp-1/2)
Nếu d<0: chọn E, x tăng 1, y không thay đổi.
E
d old F ( x p 1, y p 12 ) b 2 ( x p 1) 2 a 2 ( y p 12 ) 2 a 2b 2
P1
d new F ( x p 2, y p 12 ) b 2 ( x p 2) 2 a 2 ( y p 12 ) 2 a 2b 2 SE
Region 1
d new d old b (2 x p 3) d old E
2
Region 2
S SE
37
2.3. Thuật toán trung điểm (eclíp)
Với vùng 2:
Tính biến quyết định d =F(x, y)=F(xp+1/2, yp-1)
Nếu d<0: chọn SE, x tăng 1, y giảm 1.
Nếu d0: chọn S, x không tăng, y giảm 1
Tìm số gia như vùng 1
S = a2(-2yp+3) E
SE= b2(2xp+2)+a2(-2y+3) SE
P1
Region 1
S SE
Region 2
38
2.3. Thuật toán trung điểm (eclíp)
4
Miền 2:
Phụ thuộc vào điểm giữa (xp+1, yp-1/2) của điểm tiếp theo điểm
cuối cùng của miền 1.
E
F ( x p , y p 1) b ( x ) a ( y 1) a b
1
2
2 1 2
2
2 2 2 2
P1
2 SE
b Region 1
b x b x a 2 ( y 1) 2 a 2b 2
2 2 2
S SE
4 Region 2
39
2.3. Thuật toán trung điểm (eclíp)
procedure draw_ellipse(a, b, color: integer); EllipsePoints (x, y, color);
var x, y: integer; d1, d2: real; end {Vùng 1}
begin
d2=b2(x+1/2)2+a2(y-1)2 –a2b2;
x:=0; {Khởi động}
while y>0 do {Vùng 2}
y:=b;
begin
d1:=b2-a2b+a2/4; if d2<0 then { Chon SE }
EllipsePoints(x, y, color); begin
while (a2(y-1/2)>b2(x+1)) do {Vùng 1} d2:=d2+b2(2*x+2)+a2(-2*y+3);
begin x:=x+1;
if d1<0 then {Chọn E} y:=y-1
begin end
d1:=d1+b2(2*x+3); else
x:=x+1 begin
d2:=d2+a2(-2*y+3);
end
y:=y-1
else {Chọn SE}
end
begin
EllipsePoints (x, y, color);
d1:=d1+b2(2*x+3)+a2(-2*y+2); end {Vùng 2}
x:=x+1; end
y:=y-1
end;
40
Bài tập chương 3
Kết hợp việc sử dụng OpenGL để cài đặt các giải thuật
sau đây:
41