LỜI NÓI ĐẦUĐồ họa máy tính là một lĩnh vực của khoa học máy tính nghiên cứu về cơ sở toánhọc, các thuật toán cũng như các kĩ thuật để cho phép tạo, hiển thị và điều khiển hìnhảnh trên mà
Trang 1TRƯỜNG ĐẠI HỌC CÔNG NGHIỆP HÀ NỘI
KHOA CÔNG NGHỆ THÔNG TIN
Nhóm sinh viên thực hiện: Nhóm 9
1 Nguyễn Văn Long
2 Nguyễn Chí Thanh
3 Phạm Đình Chiến
Lớp: ĐH KTPM – K6
Giáo viên hướng dẫn: THS Nguyễn Thị Cẩm Ngoan
Hà Nội, ngày 26 tháng 02 năm 2013
Trang 2LỜI NÓI ĐẦU
Đồ họa máy tính là một lĩnh vực của khoa học máy tính nghiên cứu về cơ sở toánhọc, các thuật toán cũng như các kĩ thuật để cho phép tạo, hiển thị và điều khiển hìnhảnh trên màn hình máy tính Đồ họa máy tính có liên quan ít nhiều đến một số lĩnh vựcnhư đại số, hình học giải tích, hình học họa hình, quang học, và kĩ thuật máy tính,đặc biệt là chế tạo phần cứng (các loại màn hình, các thiết bị xuất, nhập, các vi mạch
đồ họa )
Trong bài tập lớn bộ môn đồ họa máy tính nhóm em được giao đề tài: “Vẽ mặt trời đứng yên tại tâm màn hình, trái đất quay quanh mặt trời quỹ đạo ellip, mặt trăng quay quanh trái đất quỹ đạo hình tròn” Được sự hướng dẫn của cô giáo bộ
môn cũng như qua các cổng thông tin Internet, tài liệu và sự tìm tòi trên các cuốn sáchtài liệu liên quan tới đề tài nhóm em đã hoàn thành bài tập lớn được giao Trong quátrình hoàn thành nhóm đã gặp được một số khó khăn cũng như thuận lợi và còn nhiềuhạn chế Nhóm em rất mong được sự đóng góp, bổ sung ý kiến để bài tập lớn củanhóm em có thể hoàn thành tốt các đề tài tiếp theo cũng như đề tài của nhóm sau này
Trang 3MỤC LỤC
1 PHÂN TÍCH KHẢO SÁT MỤC TIÊU ĐỐI TƯỢNG 4
1.1 Định nghĩa các hằng số 4
1.2 Mặt trời 4
1.3 Trái đất 6
1.4 Mặt trăng 9
2 CÁC THUẬT TOÁN SỬ DỤNG 10
2.1 Thuật toán vẽ đường tròn: 10
2.1.1 Thuật toán Bresenham: 10
2.1.2 Thuật toán MidPoint: 12
2.2 Thuật toán tô màu 14
2.2.1 Theo dòng quét: 14
2.2.2 Tô màu lân cận: 16
2.3 Phép quay: 17
3 GIAO DIỆN CHƯƠNG TRÌNH 20
4 CHƯƠNG TRÌNH CÀI ĐẶT 21
5 TÀI LIỆU THAM KHẢO 26
Trang 41 PHÂN TÍCH KHẢO SÁT MỤC TIÊU ĐỐI TƯỢNG.
1.1 Định nghĩa các hằng số
#define SUNRADIUS 80 // bán kính mặt trời 80 pixel
#define EARTHRADIUS 10 // bán kính trái đất 10 pixel
#define MOONRADIUS 3 // bán kính mặt trăng 3 pixel
#define SUNEARTH 200 // khoảng cách từ tâm mặt trời đến tâm trái đất 200 pixel
#define EARTHMOON 30 // khoảng cách từ tâm trái đất đến tâm mặt trăng 30 pixel
#define DELAY 20 // Tốc độ chuyển động
1.2 Mặt trời
Để vẽ được mặt trời đứng yên tại tâm màn hình Đầu tiên cần phải xác định tọa
độ xsun, ysun Tọa độ xsun=getmax()/2; và ysun=getmaxy()/2; tức trả về nửa chiều
rộng (theo x) và nửa chiều cao (theo y) tối đa của chế độ màn hình đang dùng Tiếp
theo ta vẽ đường tròn bằng thuật toán Bresenham khi biết tọa độ xsun, ysun:
void Duongtron_BRE(int xc, int yc, int R, int color)
Trang 5- Khi gọi hàm: Duongtron_BRE(xsun,ysun,60,14);//ve mat troi
Với xsun, ysun là tọa độ tâm đường tròn, bán kính 60 pixel, hệ số màu là 14 (màu vàng)
- Cuối cùng để tô màu cho Mặt trời ta dùng thuật toán tô màu đường biên với hàm tô màu:
void FloodFill (int x, int y, int in_color, int new_color)// hàm tô màu
{
if (getpixel(x, y) == in_color)
{
putpixel(x, y, new_color);
FloodFill(x-1, y, in_color, new_color);
FloodFill(x+1, y, in_color, new_color);
FloodFill(x, y-1, in_color, new_color);
Trang 6FloodFill(x, y+1, in_color, new_color);
Để vẽ được trái đất quay quanh mặt trời với quỹ đaọ ellip, đầu tiên ta khởi tạo tọa
độ tâm trái đất ở một vị trí xác định xearth, yearth, sau đó thực hiện phép quay quanh tâm mặt trời Với xearth = xsun + SUNEARTH; yearth= getmaxy()/2;
- Vẽ và tô màu cho trái đất:
setcolor(GREEN); // Vẽ màu viền trái đất màu xanh
setfillstyle(SOLID_FILL, GREEN); // Tô màu trái đất bằng nét liền màu xanh
fillellipse(xearth, yearth, EARTHRADIUS, EARTHRADIUS); // Vẽ và tô màu trái đấtdạng đặc, với EARTHRADIUS là bán kính ellip theo x và y)
- Sử dụng phép quay trái đất quay quanh mặt trời quỹ đạo ellipse:
Xác định quỹ đạo di chuyển của trái đất với quỹ đạo là hình ellipse ta có hàm vẽ đường ellipse dùng thuật toán Midpoint:
void plot(int xc, int yc, int x, int y, int color)
{
putpixel(xc+x, yc+y, color);
putpixel(xc-x, yc+y, color);
putpixel(xc+x, yc-y, color);
Trang 7putpixel(xc-x, yc-y, color);
Trang 9earth_angle += 1; //dieu chinh toc do quay cua trai dat
xearth = xsun + SUNEARTH * cos(M_PI * earth_angle / 180);
yearth = ysun + SUNEARTH * sin(M_PI * earth_angle / 180);
}
while(!kbhit()); //chuong trinh se dung lai khi ta bam mot phim bat ki
1.4 Mặt trăng
Để vẽ được mặt trăng quay quanh trái đất với quỹ đạo hình tròn, đầu tiên ta khởi
tạo tọa độ tâm mặt trăng ở một vị trí xác định xmoon, ymoon, sau đó thực hiện phép quay quanh tâm mặt trời Với xmoon = xearth + EARTHMOON; ymoon= getmaxy()/2;
- Vẽ và tô màu cho mặt trăng:
setcolor(WHITE);
setfillstyle(SOLID_FILL, WHITE);
fillellipse(xmoon, ymoon, MOONRADIUS, MOONRADIUS);//ve mat trang
- Sử dụng phép quay mặt trăng quay quanh trái đất quỹ đạo hình tròn:
xmoon = xearth + EARTHMOON * cos(M_PI * moon_angle / 180);
ymoon = yearth + EARTHMOON * sin(M_PI * moon_angle / 180);
} while (!kbhit()); //chuong trinh se dung lai khi ta bam mot phim bat ki
Trang 102 CÁC THUẬT TOÁN SỬ DỤNG
2.1 Thuật toán vẽ đường tròn:
Xét đường tròn (C) tâm O(xc,yc) bán kính R
Phương trình tổng quát của đường tròn có dạng:
Do tính đỗi xứng của đường tròn nên nếu điểm (x,y) (C) thì các điểm (y,x),
(-y,x), (-x,y), (-x,-y), (-y,-x), (y,-x), (x,-y) cũng (C)
Vì vậy, ta chỉ cần vẽ một phần 8 cung tròn sau đó lấy đối xứng qua gốc O và 2 trục tọa
độ thì ta có được toàn bộ đường tròn
2.1.1 Thuật toán Bresenham:
Giả sử (x ,y ) đã vẽ được Cần chọn điểm kế tiếp là (x +1, y ) hoặc (xi +1,yi 1)
-Từ phương trình: x2 + y2 = R2
ta tính được giá trị y thực ứng với tọa độ xi +1 là: y2 = R2 - (xi +1)2
đặt d1 = yi2 - y2= yi2 - R2 + (xi + 1)
d2 = y2 - (yi - 1)2 = R2 - (xi + 1)2 - (yi - 1)2
suy ra
pi = d1 - d2 = 2.(xi + 1)2 + yi2 + (yi - 1)2 - 2R2 (2)
pi+1 = 2.(xi+1 + 1)2 + y2i+1 + (yi+1 - 1)2 - 2R2 (3)
Từ (2) và (3) ta có:
pi+1 - pi = 4xi + 6 + 2.(y - y ) - 2.(y - y )
pi+1 = pi + 4xi + 6 + 2.(y - y ) - 2.(y - y ) (4)
Trang 11Nhận xét:
Nêu pi < 0: chọn yi+1 = yi (4) pi+1 = pi + 4xi + 6
Nêu pi 0: chọn yi+1 = yi - 1 (4) pi+1 = pi + 4.(xi - yi) + 10
Ta chọn điểm đầu tiên cần vẽ (0,R), theo (2) ta có: p1 = 3 - 2R
Tóm lại ta có thuật toán vẽ đường tròn:
Bước 1 chọn điểm đầu cần vẽ: (x1,y1) = (0,R)
Bước 2 Tính P đầu tiên: p1 = 3 – 2R
Nêu p < 0: chọn điểm kê tiếp là (xi +1,yi) Ngược lại thì chọn điểm (xi + 1,yi - 1)Bước 3 x:=x+1 tính lại p
Nêu pi < 0: pi+1 = pi + 4xi + 6 Ngược lại: pi+1 = pi + 4.(xi - yi) + 10
Khi đó :
Nêu pi+1 < 0: chọn điểm kê tiêp là (x ,y ) Ngược lại chọn điểm (x ,y -1)
Bước 4 Lặp lại bước 3 cho đên khi x = y.
Sau đây là thủ tục để cài đặt thuật toán:
Trang 122.1.2 Thuật toán MidPoint:
Do tính đối xứng của đường tròn (C) nên ta chỉ cần vẽ cung (C1/8) là cung 1/8 đườngtròn, sau đó lấy đối xứng Cung (C1/8) được mô tả như sau (cung của phần tô xám tronghình vẽ) :
Trang 13Hình 2.1 – Các vị trí đối xứng trên đường tròn (C) tương ứng với (x,y)
Như vậy nếu có (x, y) Î (C1/8) thì các điểm : (y, x), (y,-x), (x,-y), (-x,-y), (-y,-x), (-y,x),(-x,y) sẽ thuộc (C)
Chọn điểm bắt đầu để vẽ là điểm (0,R) Dựa vào hình vẽ, nếu là điểm nguyên đãtìm được ở bước thứ i, thì điểm ở bước thứ (i+1) là sự lựa chọn giữa S và P
Như vậy :
Tương tự như thuật toán MidPoint vẽ đoạn thẳng, việc quyết định chọn một trong haiđiểm S và P sẽ được thực hiện thông qua việc xét dấu của một hàm nào đó tại điểmMidPoint là điểm nằm giữa chúng
Hình 2.2 – Thuật toán MidPoint vẽ đường tròn
Trang 14Ta tính giá trị ứng với điểm ban đầu
2.2 Thuật toán tô màu
Trang 15đa giác, sau đó các giao điểm này sẽ được sắp theo thứ tự tăng dần của hoành độ giaođiểm Các đoạn giao chính là các đoạn thẳng được giới hạn bởi từng cặp giao điểmmột, ví dụ như (0,1), (2,3), ….
Hình 2.3 – Thuật toán scan-line với một dòng quét nào đó
Ta có thể tóm bắt các bước chính của thuật toán :
Tìm , lần lượt là giá trị lớn nhất, nhỏ nhất của tập các tung độ của các
Ứng với mỗi dòng quét , với k thay đổi từ đến , lặp :
Tìm tất cả các hoành độ giao điểm của dòng quét với các cạnh của đa giác
Sắp xếp các hoành độ giao điểm theo thứ tự tăng dần : x0, x1, …
Tô màu các đoạn thẳng trên đường thẳng lần lượt được giới hạn bởi các
Nếu chỉ dừng ở mức này và chuyển sang cài đặt, chúng ta sẽ gặp một số vấn đề sau :
Nhận xét rằng, ứng với mỗi dòng quét, không phải lúc nào tất cả các cạnh của
đa giác cũng tham gia cắt dòng quét Do đó để cải thiện tốc độ cần phải có mộtcách nào đó để hạn chế được số cạnh cần tìm giao điểm ứng với mỗi dòng quét
Việc tìm giao điểm của cạnh đa giác với mỗi dòng quét sẽ gặp các phép toánphức tạp như nhân, chia, … trên số thực nếu ta dùng cách giải hệ phương trìnhtìm giao điểm Điều này sẽ làm giảm tốc độ thuật toán khi phải lặp đi lặp lạinhiều lần thao tác này khi dòng quét quét qua đa giác
Trang 16 Nếu số giao điểm tìm được giữa các cạnh đa giác và dòng quét là lẻ thì việcnhóm từng cặp giao điểm kế tiếp nhau để hình thành các đoạn tô có thể sẽkhông chính xác Điều này chỉ xảy ra khi dòng quét đi ngang qua các đỉnh của
đa giác Nếu tính số giao điểm tại đỉnh dòng quét đi ngang qua là hai thì có thể
sẽ cho kết quả tô không chính xác như trong trường hợp của hình 2.19 Ngoài
ra, việc tìm giao điểm của dòng quét với các cạnh nằm ngang là một trường hợpđặc biệt cần phải có cách xử lí thích hợp
2.2.2 Tô màu lân cận:
Lây P(x,y) S, tô màu P
Xét các điểm lân cận của P
Nêu các điểm lân cận đó vẫn còn thuộc S và chưa được tô màu thì tô màu cho các điểm lân cận đó
Thuật toán trên có thê được minh học bằng thử tục đệ quy sau:
Procedure Tomaulancan(x,y:Integer; Color:Word);
Trang 172.3 Phép quay:
Phép quay làm thay đổi hướng của đối tượng Một phép quay đòi hỏi phải có tâmquay, góc quay Góc quay dương thường được quy ước là chiều ngược chiều kim đồng
hồ Ta có công thức biến đổi của phép quay điểm quanh gốc tọa độ một góc góc
a tạo thành điểm ảnh Q(x*,y*) có công thức như sau:
Hình 2.4 – Phép quay một đối tượng quanh gốc tọa độ một góc 60 0
Phép quay quanh một điểm bất kỳ
Hình 2.5 - Phép quay quanh một điểm
1800
Trang 18Hình 2.6 : Phép quay quanh một điểm bất kỳ.
Xét điểm P(P.x,P.y) quay quanh điểm V(V.x, V.y) một góc -0- đến điểm Q(Q.x,Q.y)
Ta có thể xem phép quay quanh tâm V được kết hợp từ phép các biến đổi cơ bản sau:
- Phép tịnh tiến (-V.x, -V.y) để dịch chuyển tâm quay về gốc tọa độ
- Quay quanh gốc tọa độ O một góc
-0 Phép tịnh tiến (+V.x, +V.y) để đưa tâm quay về vị trí ban đầu
Ta cần xác định tọa độ của điểm Q (xem hình 3.3)
- Từ phép tịnh tiến (-V.x,-V.y) biến đổi điểm P thành P' ta được:
Trang 19Q = Q' + V
hay
Vậy Q = P.M + tr
Với
Thuật toán cài đặt
void Quay(float &x,float &y,float goc)
Trang 203 GIAO DIỆN CHƯƠNG TRÌNH
Hình 3.1 – Giao diện khi chạy chương trình
Hình 3.2 – Giao diện khi chạy chương trình.
Trang 22FloodFill(x-1, y, in_color, new_color);
FloodFill(x+1, y, in_color, new_color);
FloodFill(x, y-1, in_color, new_color);
FloodFill(x, y+1, in_color, new_color);
}
}
void plot(int xc, int yc, int x, int y, int color)
{
Trang 23putpixel(xc+x, yc+y, color);
putpixel(xc-x, yc+y, color);
putpixel(xc+x, yc-y, color);
putpixel(xc-x, yc-y, color);
Trang 24int earth_angle = 0, moon_angle = 0;
rectangle(0, 0, getmaxx(), getmaxy());//getmaxy la ham lay do dai chieu doc cua manhinh
Trang 25//getmaxx() la ham lay gia tri do dai chieu ngang cua man hinh
xsun = getmaxx() / 2;
ymoon = yearth = ysun = getmaxy() / 2;
xearth = xsun + SUNEARTH;
xmoon = xearth + EARTHMOON;
Duongtron_BRE(xsun,ysun,60,14);//ve mat troi
setcolor(GREEN);//ve mau vien cua trai dat
setfillstyle(SOLID_FILL, GREEN);//to mau trai dat
fillellipse(xearth, yearth, EARTHRADIUS, EARTHRADIUS);//trai dat
setcolor(WHITE);
setfillstyle(SOLID_FILL, WHITE);
fillellipse(xmoon, ymoon, MOONRADIUS, MOONRADIUS);//ve mat trang
//tao chuyen dong cho trai dat va mat trang
Trang 26fillellipse(xmoon, ymoon, MOONRADIUS, MOONRADIUS);//to mau den cho mattrang.
earth_angle += 1;//dieu chinh toc do quay cua trai dat
moon_angle -= 12;//dieu chinh toc do quay cua mat trang
//cac gia tri cua trai dat va mat trang se thay doi lam cho trai dat va mat trang quay xearth = xsun + SUNEARTH * cos(M_PI * earth_angle / 180);
yearth = ysun + SUNEARTH * sin(M_PI * earth_angle / 180);
xmoon = xearth + EARTHMOON * cos(M_PI * moon_angle / 180);
ymoon = yearth + EARTHMOON * sin(M_PI * moon_angle / 180);
Trang 275 TÀI LIỆU THAM KHẢO
GIÁO TRÌNH: KỸ THUẬT ĐỒ HỌA - THS TRỊNH THỊ VÂN ANH
GIÁO TRÌNH ĐỒ HỌA MÁY TÍNH – THS NGUYỄN THỊ CẨM NGOAN
http://d.violet.vn/uploads/resources/50/1557698/preview.swf
http://www.vn-zoom.com/f174/cac-ban-giup-minh-bai-pascal-nay-voi-1173071.html#post6921914