Có ba cách vẽ, cần phải xác định tất cả các Trường hợp khi vẽ: Theo DDA: Cách vẽ này sẽ chia theo hai trường hợp hệ số góc nằm trongkhoảng từ -1 đến 1 và hệ số góc nằm ngoài khoảng đó
Trang 1TRƯỜNG ĐẠI HỌC CÔNG NGHIỆP HÀ NỘI
KHOA CÔNG NGHỆ THÔNG TIN
BÁO CÁO BÀI TẬP LỚN MÔN ĐỒ HỌA MÁY TÍNH
Đề tài CÀI ĐẶT HÀM VẼ ĐƯỜNG THẲNG BẰNG DDA, BRESENHAM, MIDPOINT ĐI QUA HAI ĐIỂM NHẬP TỪ BÀN PHÍM.
SỬ DỤNG CÁC PHÉP TỊNH TIẾN, PHÉP QUAY, CO DÃN, ĐỐI XỨNG VÀ
PHÉP KẾT HỢP
Nhóm thực hiện: Nhóm 18
Giảng viên: Th.s Nguyễn Thị Cẩm Ngoan.
Hà Nội, ngày 25 tháng 2 năm 2012
Trang 2TRƯỜNG ĐẠI HỌC CÔNG NGHIỆP HÀ NỘI
KHOA CÔNG NGHỆ THÔNG TIN
BÁO CÁO BÀI TẬP LỚN MÔN ĐỒ HỌA MÁY TÍNH
Đề tài: Đề tài CÀI ĐẶT HÀM VẼ ĐƯỜNG THẲNG BẰNG DDA, BRESENHAM, MIDPOINT ĐI QUA HAI ĐIỂM NHẬP TỪ BÀN PHÍM.
SỬ DỤNG CÁC PHÉP TỊNH TIẾN, PHÉP QUAY, CO DÃN, ĐỐI XỨNG VÀ
Trang 3MỤC LỤC
LỜI NÓI ĐẦU 4
I KHẢO SÁT 5
1 Vẽ đường thẳng 5
2 Các phép biến đổi 5
II PHÂN TÍCH 6
1 Vẽ đường thẳng 6
a) Vẽ đường thẳng theo DDA 6
b) Vẽ đường thẳng theo Bressenham 9
c) Vẽ đường thẳng theo Midpoint 15
2 Các phép biến đổi 21
a Phép tịnh tiến 21
b Phép quay 22
c Phép co dãn 23
d Phép đối xứng qua điểm 24
e Phép đối xứng qua đường thẳng y =ax + b 25
III Hình ảnh sau khi chạy 27
1 Vẽ đường thẳng 27
2 Các phép biến đổi 30
IV PHẦN CODE 33
1 Vẽ đường thẳng bằng DDA 33
2 Vẽ đường thẳng bằng bresenham 34
3 Vẽ đường thẳng bằng Midpoint 36
4 Hàm tịnh tiến 38
5 Hàm co dãn 38
6 Hàm đối xứng qua điểm 38
7 Hàm đối xứng qua đường thẳng y = ax + b 39
8 Hàm quay 39
Trang 4LỜI NÓI ĐẦU
Như chúng ta đã biết, việc vẽ một đường thẳng bất ký là phần đơn giản nhất trong quá trình vẽ một hình cầu kỳ và phức tạp hơn Nhất là vẽ một đa giác bất kỳ thì việc vẽ một đoạnthẳng đi qua hai điểm bất kỳ lại càng có ý nghĩa quan trọng hơn Khi đã vẽ và thực hiện được các phép biến đổi cho đoạn thẳng thì việc vẽ đa giác sẽ dễ hơn rất nhiều
Bản báo cáo này gồm có 5 phần chính, trong đó 4 phần đầu nói về quá trình khảo sát, xây dựng và chạy thử cũng như phần code của các hàm Phần cuối là tài liệu tham khảo
Trang 5I KHẢO SÁT.
1 Vẽ đường thẳng.
Có ba cách vẽ, cần phải xác định tất cả các Trường hợp khi vẽ:
Theo DDA: Cách vẽ này sẽ chia theo hai trường hợp hệ số góc nằm trongkhoảng từ -1 đến 1 và hệ số góc nằm ngoài khoảng đó (ngoài ra còn trườnghợp hệ số góc không xác định nữa, ta sẽ xét sau)
Theo Bresenham: Cách vẽ này ta chia thành bốn trường hợp tương ứng với cácđường thẳng tăng nhanh, tăng chậm, giảm nhanh và giảm châm Ngoài ra cũngnhư DDA ta sẽ xét trường hợp hệ số góc không xác định sau
Theo Midpoint: Giống như Bresenham
trường hợp hệ số góc không xác định ta sẽ xét chung cho tất cả các trường hợp
2 Các phép biến đổi.
Có năm phép biến đổi cần thực hiện:
Phép tịnh tiến: tịnh tiến theo một vecter cho trước
Phép quay: quay quanh một tâm quay bất kỳ với một góc quay nhập từ bànphím
Phép co dãn: co dãn theo một hệ số bất kỳ nhập từ bàn phím Ý tường phầnnày là thay vì co dãn một đoạn thẳng thì ta nên co dãn một tam giác hoặc hình
đa giác bất kỳ để thấy được sự thay đổi rõ nét
Phép đối xưng: ta sẽ chia phép đối xưng thành hai trường hợp là đối xứng qua
tâm và đối xưng qua đường thẳng có phương trình tổng quát là y = ax + b với
a, b nhập từ bàn phím
Phép kết hợp: là kết hợp tất cả các phép biến đổi trên lại với nhau, sẽ có 24trường hợp của phép kết hợp
Trang 6II PHÂN TÍCH.
1 Vẽ đường thẳng.
a) Vẽ đường thẳng theo DDA
Như chúng ta đã biết, tất cả các đường thẳng đề có một hệ số góc “m” riêng của nó Khiviết dưới dạng y = ax + b thì hệ số góc của đường thẳng cũng chính là hệ số “a”
Dựa vào hệ số góc thì ta sẽ có 6 trường hợp để vẽ đường thẳng bao gồm:
Tuy nhiên, khi vẽ đường thẳng ta có thể chia thành ba cách để vẽ đường thẳng như sau:
Trường hợp 1: Ta vẽ hệ số góc -1 <= m <=1 sở dĩ có thể gộp ba trường hợp trên lạivới nhau là vì tại vòng lặp ta để tăng theo x (do số điểm x nhiều hơn số điểm y khi vẽ).Trường hợp này ứng với các đường thẳng tăng chậm, giảm chậm và đường thẳng song songvới chục Ox
Trường hợp 2: Ta vẽ hệ số góc m <= -1 || m >=1 Trường hợp này ta không thể tăngtheo x được mà phải tăng theo y vì nếu tăng theo x thì số điểm y cần vẽ sẽ không đủ (VD:khi x tăng từ 10 đến 20 mà y lại cần tăng từ 10 lên 200 như vậy thì số điểm x của vòng lặp
sẽ chỉ là 10 điểm, tương ứng với điểm y cũng chỉ là 10 điểm, trong khi số điểm y ta cần vẽthực sự là 200-10=190 điểm, điều đó dẫn đến vẽ đường thẳng sai) Trường hợp này tươngứng với các đường thẳng tăng nhanh và giảm nhanh
Trường hợp 3: Đây là trường hợp với hệ số góc chưa xác định (đường thẳng songsong với chục Oy) Trong trường hợp này, vì x1 = x2 nên ta sẽ cho vòng lặp lặp theo y
*) Trường hợp 3 ta không chỉ áp dụng cho DDA mà còn cho cả bresenham và midpointnữa Vì thế chúng ta chỉ cần xây dựng một hàm cho trường hợp này để vẽ cho cả DDA,bresenham và midpoint
Sau đây ta sẽ xét từng trường hợp của hàm DDA khi vẽ:
i Trường hợp 1 (-1 <= m <= 1)
Với thuận toán DDA nói chung, việc quyết định chọn yi+1 là yi hay yi + 1 (ở trườnghợp 2 là xi+1), dựa vào phường trình của đoạn thẳng y = mx + b Nghĩa là ta sẽ tính tọa độcủa điểm (xi+1,y) thuộc về đoạn thẳng thực Tiếp đó, yi+1 sẽ là giá trị khi làm tròn giá trịcủa tung độ y
Như vậy ta có thể viết gọn như sau:
y = m(xi + 1) + b
yi+1 = round(y)
Trang 7Nếu tính trực tiếp giá trị thực y ở mỗi bước từ phương trình y = mx + b thì phải cầnmột phép toán nhân và một phép toán cộng số thực để cải thiện tốc độ, ta có thể tính giátrị thực của ysau theo ytrước.
Lúc đó: ysau = ytrước + m
Lưu đồ của thuật toán theo trường hợp 1
ii Trường hợp 2 (m < -1 hoặc m > 1)
Trường hợp này cơ bản cũng giống như trường hợp 1 nhưng việc tính toán có phầnngược lại (do vòng lặp ta không lặp theo x mà lặp theo y)
Trang 8Về cơ bản ngoài vòng lặp và việc tăng x, y có phần ngược nhau thì nó cũng khôngkhác so với Trường hợp 1 là bao nhiêu.
iii Trường hợp 3 (hệ số góc không xác định)
*) Như đã nói ở trên, trường hợp này ở ba cách vẽ DDA, bresenham và midpoint đềugiống nhau cả nên ta sẽ không cần phải viết lại mà viết một hàm dùng cho cả ba cách vẽ.Đây là trường hợp x1 = x2 nên ta chỉ cần vòng lặp theo y từ y1 đến y2 là được (y1 <y2)
Lưu đồ của trường hợp 3 như sau:
Trang 9 Sau khi đã xét xong tất cả các trường hợp của DDA thì hàm chính của DDA tachỉ cần gọi lại các hàm con đã viết là được.
b) Vẽ đường thẳng theo Bressenham
Ý tưởng của thuật toán bresenham trong việc chọn yi+1 là yi hay yi + 1 là dựa vàotrung điểm của hai điểm sẽ chọn này (nếu là giảm nhanh và tăng nhanh hoặc hệ sốgóc không xác định thì sẽ tăng theo y)
Cũng tương tự như DDA, t cũng có 6 Trường hợp để vẽ đường thẳng nhưng cũngchỉ cần xây dựng 5 hàm để vẽ đường thẳng Một trong ba hàm là giống với DDA đãđược xây dựng trong “Trường hợp 3” ở trên
Nếu d1 – d2 < 0, sẽ chọn điểm yi+1 là yi
Nếu d1 – d2 >= 0, chọn điểm yi+1 là yi + 1
y = y + 1;
Putpixel(x,y,color);
end
no
Trang 10Xét pi = dx(d1 – d2) = dx(2y – 2yi – 1)
pi = dx(2(m(xi + 1) + b) - 2yi – 1)
Thay m = dy/dx vào phương trình trên ta được:
pi = 2dyxi – 2dxyi + c, với c = 2dy + (2b – 1)dx
Vì dx > 0 nên dấu của biểu thức phụ thuộc hoàn tàn vào dấu của d1 – d2 Đây cũng chính
là dấu của pi Nghĩa là tại bước này ta đã xác định được pi tại điểm đầu tiên cần vẽ Việc tiếptheo ta chỉ cần tính pi sao cho nhanh nhất
Ta có:
Pi+1 – pi = (2dyxi+1 – 2dxyi+1 + c) – (2dyxi – 2dxyi + c)
<=> Pi+1 – pi = 2dy(xi+1 - xi) – 2dx(yi+1 - yi)
<=> Pi+1 – pi = 2dy – 2dx(yi+1 – yi), do xi+1 = xi + 1
Từ đây ta có thể suy ra cách tính pi+1 từ pi như sau:
Nếu pi < 0 thì pi+1 = pi + 2dy do ta chọn yi+1 = yi
Ngược lại thì pi+1 = pi + 2(dy – dx) do ta chọn yi+1 = yi + 1
Giá trị của p0 được tính từ điểm đầu tiên (x0, y0) theo công thức:
p0 = 2dyx0 – 2dxy0 + c = 2dyx0 – 2dxy0 + 2dy – (2b - 1)dx
Do (x0, y0) là điểm nguyên thuộc về đoạn thẳng nên ta có:
Y0 = mx0 + b = (dy/dx)x0 + b Thế vào phương trình trên ta suy ra: p0 = 2dy – dx
Lưu đồ thuật toán bresenham
Trang 12vì yi+1 = yi + 1
từ đây ta có thể suy ra cách tính pi+1 từ pi như sau:
Nếu pi < 0 thì pi+1 = pi + 2dx do ta chọn xi+1 = xi
Ngược lại thì pi+1 = pi + 2(dx – dy) do lúc này ta chọn xi+1 = xi + 1
Tiếp theo ta tính giá trị p0 Giá trị này được tính từ điểm vẽ đầu tiên (x0, y0) theo côngthức:
P0 = 2dxy0 – 2dyx0 + c
Tương tự như cách tính trong Trường hợp 1, ca sẽ tính được: p0 = 2dx – dy
Lưu đồ thuật toán bresenham trong Trường hợp 2 như sau:
Trang 13Trường hợp này cũng xây dựng tương tự như trường hợp 1, tuy nhiên vì đây là hệ
số góc nhỏ hơn -1 nên ta sẽ thay vì việc ta tăng y++ sẽ là việc ta giảm y Cụ thể ta cóquá trình xây dựng hàm như sau:
Gọi (xi + 1, y) là điểm thuộc đoạn thẳng Ta có y = m(xi + 1) + b
Nếu d1 – d2 < 0, sẽ chọn điểm yi+1 là yi
Nếu d1 – d2 >= 0, chọn điểm yi+1 là yi – 1
Xét pi = dx(d1 – d2) = dx(2yi – 2y – 1)
pi = dx(2yi – 2(m(xi + 1) + b) – 1)
Thay m = dy/dx vào phương trình trên ta được:
pi = 2dxyi – 2dyxi + c, với c = dx – (b+1)dy
vì dx > 0 nên dấu của biểu thức phụ thuộc hoàn tàn vào dấu của d1 – d2 Đây cũng chính
là dấu của pi Nghĩa là tại bước này ta đã xác định được pi tại điểm đầu tiên cần vẽ Việc tiếptheo ta chỉ cần tính pi sao cho nhanh nhất
Ta có:
Pi+1 – pi = (2dxyi+1 – 2dyxi+1 + c) – (2dxyi – 2dyxi + c)
<=> Pi+1 – pi = 2dy(xi - xi+1) – 2dx(yi+1 - yi)
<=> Pi+1 – pi = –2dy – 2dx(yi+1 – yi), do xi+1 = xi + 1
Từ đây ta có thể suy ra cách tính pi+1 từ pi như sau:
Nếu pi < 0 thì pi+1 = pi – 2dy do ta chọn yi+1 = yi
Ngược lại thì pi+1 = pi –2(dx + dy) do ta chọn yi+1 = yi – 1
Giá trị của p0 được tính từ điểm đầu tiên (x0, y0) theo công thức:
p0 = 2dxy0 – 2dyx0 + c = 2dxy0 – 2dyx0 + dx – (b+1)dy
Do (x0, y0) là điểm nguyên thuộc về đoạn thẳng nên ta có:
y0 = mx0 + b = (dy/dx)x0 + b Thế vào phương trình trên ta suy ra: p0 = dx – 2dy
Lưu đồ thuật toán bresenham
Trang 14iv Trường hợp 4 (m < -1)
Tương tự như trường hợp 2 Tuy nhiên thay vì ta tăng x++ thì ta sẽ giảm y
Ta gọi (x, yi + 1) là điểm thuộc đoạn thẳng
Trang 15vì yi+1 = yi + 1
từ đây ta có thể suy ra cách tính pi+1 từ pi như sau:
Nếu pi < 0 thì pi+1 = pi - 2dx do ta chọn xi+1 = xi
Ngược lại thì pi+1 = pi - 2(dy + dx) do lúc này ta chọn xi+1 = xi - 1
Tiếp theo ta tính giá trị p0 Giá trị này được tính từ điểm vẽ đầu tiên (x0, y0) theo côngthức:
P0 = 2dyx0 – 2dxy0 + c
Tương tự như cách tính trong trường hợp 1, ca sẽ tính được: p0 = -2dx + dy
Lưu đồ thuật toán bresenham trong trường hợp 2 như sau:
c) Vẽ đường thẳng theo Midpoint
Cũng tương tự như thuật toán bresenham, thuật toán midpoint cũng dựa trên tínhchất trung điểm để xây dựng thật toán Thuật toán midpoint đưa ra cách chọn yi+1 là yi
Trang 16hay yi+1 bằng cách so sánh điểm thực Q(xi+1, y) với chung điểm midpoint là chungđiểm của S(xi+1,yi) và P(xi+1,yi+1).
i Trường hợp 1 (0 <= m <=1)
Ta có:
a Nếu điểm Q nằm dưới điểm midpoint ta chọn điểm S
b Nếu ngược lại ta chọn điểm P
Ta có dạng tổng quát của phương trình đường thẳng: Ax + By + C = 0
Với A =y2– y1, B = -(x2 – x1), C = x2y1 – x1y2
Đặt F(x,y) = Ax + By + C, ta có
Nếu F(x,y) < 0 thì (x,y) nằm phía trên đưởng thẳng
Nếu F(x,y) = 0 thì (x,y) thuộc đường thẳng
Nếu F(x,y) > 0 thì (x,y) nằm phía dưới đường thẳng
Lúc này việc xét dấu của pi = 2F(midpiont) = 2F(xi + 1, yi + 1/2) sẽ cho chúng ta biếtđiểm pi+1 cần chọn là điểm nào
o Nếu pi < 0, pi+1 = pi do ta chọn yi+1 = yi
o Nếu pi < 0, pi+1 = pi + 1 do ta chọn yi+1 = yi + 1
Ta tính giá trị p0 ứng với điểm ban đầu (x0, y0) với nhận xét rằng điểm (x0, y0) là điểmthuộc về đoạn thẳng, tức là Ax0 + By0 + C = 0
p0 = 2F(x0 + 1, y0 + ½) = 2(A(x0 + 1) + B(y0 + ½) + C)
p0 = 2(Ax0 + By0 + C) + 2A + B = 2A + B = 2dy – dx
Dễ nhận thấy rằng thuật toán midpoint cho kết quả cũng giống như thuật toán bresenham.Lưu đồ của thuật toán:
Trang 17ii Trường hợp 2 (m > 1)
Cũng đặt tương tự như trường hợp 1, nhưng ở trường hợp hai ta lựa chọn x chứ khôngphải lựa chọn y Việc lựa chọn xi+1 là xi hay xi + 1 cũng được dựa vào vị trí trung điểm của yi
và yi + 1, nó có phần ngược lại với Trường hợp 1
Lúc này việc xét dấu của pi = 2F(midpiont) = 2F(xi + 1/2, yi + 1) sẽ cho chúng ta biếtđiểm pi+1 cần chọn là điểm nào
o Nếu pi < 0, pi+1 = pi + 1 do ta chọn xi+1 = xi + 1
o Nếu pi < 0, pi+1 = pi do ta chọn xi+1 = xi
Trang 18Ta tính giá trị p0 ứng với điểm ban đầu (x0, y0) với nhận xét rằng điểm (x0, y0) là điểmthuộc về đoạn thẳng, tức là Ax0 + By0 + C = 0.
a Nếu điểm Q nằm dưới điểm midpoint ta chọn điểm S
b Nếu ngược lại ta chọn điểm P
Ta có dạng tổng quát của phương trình đường thẳng: Ax + By + C = 0
Trang 19 Nếu F(x,y) = 0 thì (x,y) thuộc đường thẳng
Nếu F(x,y) > 0 thì (x,y) nằm phía dưới đường thẳng
Lúc này việc xét dấu của pi = 2F(midpiont) = 2F(xi + 1, yi - 1/2) sẽ cho chúng ta biếtđiểm pi+1 cần chọn là điểm nào
o Nếu pi < 0, pi+1 = pi + 2dy do ta chọn yi+1 = yi
o Nếu pi < 0, pi+1 = pi + 2(dy + dx) do ta chọn yi+1 = yi - 1
Ta tính giá trị p0 ứng với điểm ban đầu (x0, y0) với nhận xét rằng điểm (x0, y0) là điểmthuộc về đoạn thẳng, tức là Ax0 + By0 + C = 0
p0 = 2F(x0 + 1, y0 -+ ½) = 2(A(x0 + 1) + B(y0 - ½) + C)
p0 = 2(Ax0 + By0 + C) + 2A - B = 2A - B = 2dy + dx
Dễ nhận thấy rằng thuật toán midpoint cho kết quả cũng giống như thuật toán bresenham.Lưu đồ của thuật toán:
Trang 20o Nếu pi <= 0, pi+1 = pi – 2dx do ta chọn xi+1 = xi - 1
o Nếu pi > 0, pi+1 = pi – 2dx – 2dx do ta chọn xi+1 = xi
Trang 21Ta tính giá trị p0 ứng với điểm ban đầu (x0, y0) với nhận xét rằng điểm (x0, y0) là điểmthuộc về đoạn thẳng, tức là Ax0 + By0 + C = 0.
Lư đồ của thuật toán:
Trang 22Lưu đồ của thuật toán là:
Trang 23B1) ta tịnh tiến tâm quay về góc tọa độ.
B2) tìm tọa độ sau khi co dãn của các đỉnh
B3) tịnh tiến lại tâm quay
B4) kẻ đường thẳng nối hai điểm sau khi tịnh tiến lại với nhau
Lưu đồ của thuật toán:
Trang 24d Phép đối xứng qua điểm
Để đối xứng một điểm qua gốc tọa độ ta chỉ việc thêm dấu – vào trước tọa độ củacác điểm là được:
Trang 25e Phép đối xứng qua đường thẳng y =ax + b
Việc đầu tiên ta cần làm là tìm đối xứng của một điểm qua một đường thẳng chotrước Để làm được việc này, đầu tiên ta kẻ một đường thẳng đi qua điểm đã cho và
vuông góc với đường thẳng y = ax + b, đường thẳng này sẽ có dạng y = (-1/a)x + c.
Sau khi viết được phương trình tổng quát của đường thẳng này, ta chỉ việc thay tọa
độ điểm ban đầu cần đối xứng vào để tính ra c Phương trình này sau khi tính ra c sẽ
có dạng: y = (-1/a)x + y0 + (1/a)x0
Việc tiếp theo ta cần làm là tìm giao điểm của đường thẳng ban đầu với đường
thẳng vừa tìm được, giao điểm này chính là điểm trung trực M của điểm ban đầu và điểm đối xứng mà ta cần tìm Điểm M này sẽ có tọa độ là:
xm = (ay0 + x0 – ab)/(a2 + 1)
ym = ax + b (y được tính bằng cách thay x vào phương trình đường thẳng đầu tiên)
Vì M là điểm trung trực của hai điểm đối xứng nhau nên điểm đối xứng ta cần tìm
Trang 26f Hàm hợp
Về cơ bản thì việc xây dựng hàm hợp là việc tổng hợp các hàm trên lại với nhau Tuynhiên cần khai báo thêm các biến để chỉ số lượng các hàm cần hợp lại với nhau, cần cóvòng lặp để gọi từng hàm nhỏ trong quá trình hợp
Trang 27III Hình ảnh sau khi chạy
1 Vẽ đường thẳng
Trường hợp 1:
VD: A(-2;1) và B(5;3)
VD: A(-1;1) và B(8;1)
Trang 28 Trường hợp 2
VD: A(-1;-2) và B(2;6)
VD: A(-4;1) và B(5;-2)
Trang 29 Trường hợp 4
VD: A(-2;8) và B(1;-1)
Trường hợp 5 (Trường hợp trung gian)
VD: A(-1;-1) và B(-1;8)
Trang 31VD co dãn tam giác: A(-1;-1), B(0;4), C(4;1), tâm co I(-4;5), tỷ lệ co S(0,4;1,2)
Phép đối xứng qua điểm
VD: A(1;-1), B(-3;6), điểm đối xứng I(2;1)