TRƯỜNG ĐẠI HỌC ĐIỆN LỰCKHOA CÔNG NGHỆ THÔNG TIN BÁO CÁO CHUYÊN ĐỀ HỌC PHẦN ĐỒ HỌA MÁY TÍNH ĐỀ TI: XÂY DỰNG CHƯƠNG TRÌNH VẼ ĐỒNG HỒ ĐIỆN TỬ Sinh viên thực hiện : ĐỖ CHÍ ĐỨC - 2081031031
Trang 1TRƯỜNG ĐẠI HỌC ĐIỆN LỰC
KHOA CÔNG NGHỆ THÔNG TIN
BÁO CÁO CHUYÊN ĐỀ HỌC PHẦN
ĐỒ HỌA MÁY TÍNH
ĐỀ TI:
XÂY DỰNG CHƯƠNG TRÌNH VẼ ĐỒNG HỒ ĐIỆN TỬ
Sinh viên thực hiện : ĐỖ CHÍ ĐỨC
- 20810310313 Giảng viên hướng dẫn : NGÔ NGỌC THNH
Trang 2PHIẾU CHẤM ĐIỂM
Sinh viên thực hiện:
Họ và tên sinh viên Nội dung thực hiện Điểm Chữ ký
Đỗ Chí Đức -
20810310313
Giảng viên chấm:
Giảng viên chấm 1 :
Giảng viên chấm 2 :
Trang 3MỤC LỤC
CHƯƠNG 1: TÌM HIỂU CHƯƠNG TRÌNH 1
1 Nền tảng của chương trình 1
2 Vẽ đường thẳng (thuật toán midpoint) 2
3 Vẽ đường tròn (thuật toán midpoint) 5
4 Thuật toán tô màu (Tô màu tràn(Đệ quy)) 8
CHƯƠNG 2: CHƯƠNG TRÌNH V KẾT QUẢ THỰC NGHIỆM 10
1 Mã code chương trình 10
2 Kết quả thực nghiệm 13
KẾT LUẬN 14
Trang 4MỞ ĐẦU
Đồ họa không còn là điều quá đỗi lạ lẫm đối với người dùng máy tính, bạn có thể thấy hình ảnh từ 2D cho tới 3D ở bất cứ đâu, và các lĩnh vực đặc biệt
là thiết kế đều sử dụng hình ảnh này để làm việc, làm hoạt họa hay thậm chí là dùng trong các công việc liên quan tới giải tích, hình học
Vậy đồ họa máy tính là gì Đồ họa máy tính là phương pháp và công nghệ dùng trong việc chuyển đổi qua lại giữa dữ liệu và hình ảnh bằng máy tính Đồ 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ề ở toán họ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ực như đạ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 vỉ mạch đồ họa )
Từ những gì học được từ đồ họa máy tính, nhóm em muốn xây dựng được một chương trình ứng dụng được kiến thức của đồ họa máy tính, vậy nên em chọn đề tài “Xây dựng chương trình vẽ đồng hồ điện tử” là chương trình đúc kết kiến thức của mình
Có lẽ rằng chương trình và báo cáo của em chưa được chuyên nghiệp, hoàn chỉnh nhất, còn có những thiếu xót Vì thế em rất mong thầy cô và các bạn
có thể góp ý để nhóm em xây dựng đề đạt kết quả tốt nhất có thể
Trang 5CHƯƠNG 1: TÌM HIỂU CHƯƠNG TRÌNH
1 Nền tảng của chương trình
Đồ họa máy tính là tất cả những gì liên quan đến việc sử dụng máy tính
để phát sinh ra hình ảnh Các vấn đề liên quan tới công việc này bao gồm: tạo, lưu trữ, thao tác trên các mô hình (các mô tả hình học của đối tượng) và các ảnh
Theo định nghĩa này thì đồ họa máy tính bao gồm việc thiết kế phần cứng như thiết bị hiển thị, các thuật toán cần thiết để phát sinh trên các thiết
bị này, các phần mềm được sử dụng cho cả người lập trình hệ thống và người lập trình ứng dụng đồ họa, và các chương trình ứng dụng tạo ảnh bằng máy tính
Đồ họa máy tính cung cấp một trong những phương cách tự nhiên nhất cho việc truyền đạt thông tin với máy tính Ngày nay, trong nhiều quá trình thiết kế, cài đặt và xây dựng, thông tin về lĩnh vực này không thiếu, và các chương trình có thể được viết bằng nhiều ngôn ngữ
Trong bộ môn “Đồ họa máy tính” này, em xây dựng chương trình bằng ngôn ngữ lập trình C++ Chương trình được sử dụng thư viện graphics.h
Do thư viện đồ họa graphics không được tích hợp sẵn trong thư viện của trình biên dịch C/C++ nên ta phải tự thêm thư viện trên nếu muốn sử dụng chúng
Sau đây, là cách cài đặt thư viện graphics.h
Bước 1: Đầu tiên vào link http://winbgim.codecutter.org/ và tải WinBGIm về Bước 2: Giải nén tập tin đã tải xuống Sẽ có ba tệp:
graphics.h
winbgim.h
libbgi.a
Bước 3: Copy hai file graphics.h và winbgim.h vào thư mục include của
trình biên dịch(thường là MinGw), còn vị trí của thư mục này ở đâu thì còn tùy vào lúc các bạn cài MinGw Thư mục đó có thể là 1 trong các đường dẫn sau:
C:\Program Files(x86)\Dev-cpp\MinGW\include
C:\Program Files(x86)\ Dev-cpp \MinGW\include
1
Trang 6Bước 4: Copy file libbgi.a vào thư mục lib của thư mục trình biên
dịch(thường là MinGw)
Bước 5: Mở Code::Blocks Chọn Settings >> Compiler >> Linker settings Bước 6: Click vào Add, tìm đến file libbgi.a vừa copy ở bước 4
Bước 7: Trong phần bên phải (other linker options) dán các lệnh sau vào đó:
-lbgi -lgdi32 -lcomdlg32 -luuid -loleaut32 -lole32
Bước 8: Nhấn OK
Bước 9: Hầu hết sau bước này các bạn đã làm thành công Hãy thử biên dịch
chương trình graphics.h trong C hoặc C++ để kiểm tra Có một vài trường hợp vẫn sẽ lỗi Để giải quyết nó, hãy mở tệp graphics.h (đã dán trong thư mục bao gồm trong bước 3) Chuyển đến dòng số 302 và thay thế dòng đó bằng dòng này:
int left = 0, int top = 0, int right = INT_MAX, int bottom = INT_MAX,
Bước 10: lưu tệp.
2 Vẽ đường thẳng (thuật toán midpoint)
Đường thẳng trên một màn hình máy tính là một tập hợp các điểm có kích thước gần đúng với các điểm trên thực tế Để thu được đường thẳng tốt nhất thì ta cần lựa chọn được các điểm ảnh gần đúng với đường thẳng thực tế nhất Đó là vấn đề có thể giải quyết được bằng thuật toán Midpoint
Trong toán học, khái niệm đường thẳng là 1 đường kéo dài vô cùng mỏng, thẳng tuyệt đối; qua hai điểm bất kì chỉ có một đường thẳng đi qua nó Trên một màn hình máy tính lại bao gồm nhiều điểm ảnh với các kích thước cụ thể khác nhau Vì vậy, khái niệm đường thẳng ở đây lại là một tập hợp các điểm có kích thước xấp xỉ gần đúng với các điểm trên thực tế
Để thu được đường thẳng tốt nhất thì cần lựa chọn được các điểm ảnh gần đúng với đường thẳng thực tế nhất Do đó, các thuật toán vẽ đường thẳng ra đời nhằm giải quyết bài toán trên
Để vẽ được đường thẳng nối từ hai điểm (x1, y1), (x2, y2), cần tính toán được điểm vẽ tiếp theo sau khi vẽ điểm đầu tiên (x0, y0)
2
Trang 7Recommandé pour toi
PET Speaking visuals Hình thi nói PET part 3
Life A2B1 Wordlist tiếng anh 1 đại học điện lực
Dap an multiple choise - tiếng anh
FRS Sample fastval
Suite du document ci-dessous
10
13
4
14
Trang 8Với thuâ ‚t toán Midpoint, có thể tìm được điểm cần tìm dựa vào vị trí trung điểm của các đối tượng đang nằm trong vùng lựa chọn so với đường thẳng đang được vẽ
Mô tả thuật toán midpoint:
Đối với việc lựa chọn điểm vẽ tiếp theo sau A, có hai lựa chọn đó là điểm P và Q với M là trung điểm giữa chúng Việc quyết định chọn điểm nào
để vẽ tiếp theo phụ thuộc vào vị trí của M so với đường thẳng đang vẽ Nếu M nằm phía dưới đường thẳng, chọn điểm Q Ngược lại, nếu M nằm phía trên đường thẳng ta chọn điểm P
Xét trường hợp 0 < m < 1
Phương trình đường thẳng là:
y = m * x + b, m = d / dy x
⇔ y = d / d * x + bx x
⇔ d * x + (-d * y) + b * d = 0 (1)y x x
Mà:
F(x, y) = a * x + b * y + c = 0 (2)
(1), (2) a = d , b = -d , c = b * d⇒ y x x
Tìm d
3
Trang 9F(M) = F(x + 1, y + 1 / 2)i i
= F(x , y ) + a + b / 2 = 0 + d + d / 2 = d + d / 2i i y x y x
Tìm dmax
Đă ‚t d = F(M)
Nếu d > 0, chọn điểm Q để vẽ
Nếu d < 0, chọn điểm P để vẽ
Trường hợp 1 - chọn Q
Mnew * (x + 2, y + 1 / 2) d = F(x + 2, y + 1 / 2)i i ⇒ new i i
(Δd)Q = d - dnew old
= F(x + 1, y + 1 / 2) - F(x + 2, y + 1 / 2) = ai i i i
= dy
⇒ d = d + dnew old y
Trường hợp 2 - chọn P
Mnew * (x + 2, y + 3 / 2) d = F(x + 2, y + 3 / 2)i i ⇒ new i i
(Δd)P = d - dnew old
= F(x + 1, y + 1 / 2) - F(x + 2, y + 3 / 2) = a + bi i i i
= d - dy x
⇒ d = d + d - dnew old y x
Thuâ ‚t giải
Thuật giải dưới đây chỉ nêu và hiện thực thuật toán trong trường hợp 0 < m <
1, các trường hợp còn lại có thể suy luận tương tự như trên
Input: (x1, y1), (x2, y2)
Output: Tâ ‚p hợp điểm có tọa đô ‚ nguyên
Các bước thực hiê ‚n chính:
Bước 1
dx = x2 – x1, dy = y2 – y1;
d = dy – dx/2;
x = x1, y = y1;
// Vẽ điểm (x, y)
Bước 2
4
Trang 10while (x <= x2)
{
Nếu d > 0 thì:
x = x + 1;
y = y;
d = d + dy;
Nếu d < 0 thì:
x = x + 1;
y = y + 1;
d = d + dy – dx;
// Vẽ điểm (x, y)
}
Hiê ‚n thực
void midpointLine(int x1, int y1, int x2, int y2)
{
int Dx = x2 - x1;
int Dy = y2 - y1;
int x = x1;
int y = y1;
putpixel(x1, y1, MAGENTA);
float D = Dy - (Dx >> 1); // ~ float D = Dy - Dx/2;
while(x <= x2)
{
x++;
if (D < 0 )
{
D = D + Dy;
}
else
{
D = D + (Dy - Dx);
y++;
}
putpixel(x, y, MAGENTA);
}
}
3 Vẽ đường tròn (thuật toán midpoint)
Đường tròn có tâm O(xc, yc) = (0, 0), bán kính r có phương trình:
x2 + y = r => x + y - r = 02 2 2 2 2
5
Trang 11Đặt f(x, y) = x + y - r
Với mọi điểm P(x, y) nằm trong hệ tọa độ Oxy:
P(x, y) nằm trên đường tròn O nếu f(x, y) = 0
P(x, y) nằm ngoài đường tròn O nếu f(x, y) > 0
P(x, y) nằm trong đường tròn O nếu f(x, y) < 0
Do đường tròn có tính đối xứng qua các cung 1/8, nghĩa là ứng với một điểm có tọa độ (x, y) thuộc 1 cung bất kỳ, có thể hoàn toàn xác định được tọa
độ 7 điểm còn lại bằng cách lấy đối xứng qua các cung
Từ tính chất đó nên chỉnh cần vẽ 1/8 đường tròn là đủ, sau đó sẽ lấy đối xứng để được đường tròn hoàn chỉnh
Điểm đầu tiên vẽ là điểm (x = 0, y = R)
Trong cung 1/8 thứ nhất do khoảng biến thiên của x lớn hơn khoảng biến thiên của y, nên x = x + 1.i+1 i
Giả sử đã vẽ được (Xi, Yi) ở bước thứ i, cần xác định (X , Y ) ở bước i+1 i+1 thứ i + 1
Xi+1 = Xi+1
Yi+1 {Y , Y - 1}∈ i i
6
Trang 12Tính Fi
Đặt F = F(X, Y - 1/2):i
F(Xi + 1, Y - 1/2) = (X + 1) + (Y - 1/2) - Ri i 2 i 2 2
Fi = X + 2X + Y - Y + 5/4 - Ri2 i i2 i 2
Nếu F < 0 (X , Y) gần với Y Y = Yi ⇔ i+1 i⇒ i+1 i
Nếu F ≥ 0 (X , Y) gần với Y Y = Yi ⇔ i+1 i -1⇒ i+1 i-1
Tính Fi +1 theo Fi
Fi+1 - F = 2X + 3 + (Y + 12 - Y )+ (Y - Y ) (*)i i i i2 i+1 i
Nếu F < 0 thì F = F + 2X + 3, do thay thế Y = Y vào (*)i i+1 i i i+1 i
Nếu F ≥ 0 thì F = F + 2(X - Y ) + 5, do thay thế Y = Y vào (*)i i+1 i i i i+1 i-1 Tính giá trị F đầu tiên
F(Xi + 1, Y - 1/2) = (X + 1) + (Y - 1/2) - Ri i 2 i 2 2
Fi = X + 2X + Y - Y + 5/4 - Ri2 i i2 i 2
Thay X = 0 và Y = R trong công thức trên:i i
F = 5/4 - R
Hiện thực thuật toán Midpoint
Hàm vẽ 8 điểm đối xứng nhau
7
Trang 13void put8pixel(int xc, int yc, int x, int y, int color)
{
putpixel(x + xc, y + yc, color);
putpixel(-x + xc, y + 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(y + xc, -x + yc, color);
putpixel(-y + xc, -x + yc, color);
}
Hàm vẽ đường tròn
void drawCircleMidpoint(int xc, int yc, int r, int color)
{
int x = 0, y = r;
int f = 1 - r;
put8pixel(xc, yc, x, y, color);
while (x < y)
{
if (f < 0) f += (x << 1) + 3;
else
{
y ;
f += ((x - y) << 1) + 5;
}
x++;
put8pixel(xc, yc, x, y, color);
}
}
Chương trình chính
int main()
{
int gd = DETECT, gm;
initgraph(&gd, &gm, "c:\\tc\\bgi");
drawCircleMidpoint(200, 200, 100, colors::BLUE);
Sleep(3000);
closegraph();
return 0;
}
8
Trang 144 Thuật toán tô màu (Tô màu tràn(Đệ quy))
Có hai hướng thực thi thuật toán: đó là sử dụng đệ quy và không đệ quy a) Thuật toán đệ quy:
- Bước 1: Kẻ vùng biên cần tô
- Bước 2: Xác định một điểm (x,y) bên trong vùng cần tô
- Bước 3: Tô điểm (x,y) sau đó tô loang những điểm lân cận
Hàm đệ quy:
(coi như các bạn đã hiểu cách thực hiện của hàm đệ quy, mình không cần phải demo lại thứ tự thực thi của hàm đệ quy nữa nha Còn nếu bạn nào chưa
rõ thì comment nha)
1
2
3
4
5
6
7
8
9
1
0
11
void DeQuy(int x,int y,int Color)
{
If((x,y) S)&&((x,y)chưa tô)) ∈
{
putpixel(x,y,Color);
DeQuy(x+1,y,Color);
DeQuy(x-1,y,Color);
DeQuy(x,y+1,Color);
DeQuy(x,y-1,Color);
}
}
=>Nhận xét về hàm đệ quy:
Ưu điểm:
+ Có thể tô vùng có hình dạng bất kỳ
+ Cài đặt thuật toán dễ dàng
Khuyết điểm:
+ Không thể tô các vùng có kích thước lớn do tràn bộ nhớ khi sử dụng đệ quy
+ Việc gọi đệ quy, thuật toán cho 4 điểm lân cận của điểm hiện hành không quan tâm tới một trong bốn điểm đó đã được xét ở bước trước hay chưa (tức
là sẽ có những điểm bị xét đi xét lại nhiều lần) Điều này khiến tốc độ chậm, không hiệu quả
Chính vì đệ quy phức tạp như vậy nên hầu như ở các bài toán có tính đệ quy, chúng ta đều phải tìm cách khử đệ quy Chúng ta sẽ tiến hành loang dần và lần lượt tô từng đoạn giao theo dòng quét ngang, thay vì tô theo 4 điểm lân cận
9
Trang 15b) Thuật toán khử đệ quy:
Áp dụng hàng đợi Queue, BFS
- Bước 1: Cất điểm hạt giống đầu tiên vào kho
- Bước 2: Lặp nếu kho không rỗng
+ Lấy điểm hạt giống
+ Tô điểm hạt giống, sau đó tô loang sang 2 bên
+Bổ sung những điểm hạt giống mới vào kho từ dòng trên và dòng dưới Tiêu chuẩn để làm điểm hạt giống: điểm này chưa được tô màu và không phải điểm biên
CHƯƠNG 2: CHƯƠNG TRÌNH V KẾT QUẢ THỰC NGHIỆM
1 Mã code chương trình
Hình 2.1 Cấu trúc chương trình
Để xây dựng chương trình vẽ đồng hồ điện tử, ta xây dựng 2 hàm findPoints và secondPoints
Với hàm findPoints, ta thực hiện viết logic tìm vị trí 12 tọa độ tương ứng với 12 giờ Từ đường tròn ta chia mỗi tọa độ 30 đơn vị, nên dựa vào công thức lượng giác ta sẽ tính được vị trị của từng tọa độ
Với hàm secondPoints, thực hiện viết logic tìm ra 60 tọa độ tương ứng với
số giây, phút trong đồng hồ, vì đường tròn có tổng góc là 360 độ nên ta chia đều mỗi tọa độ sẽ là 6 độ, dựa vào công thức lượng giác ta tính đước các vị trí tương ứng
10
Trang 16Hình 2.2 Hàm findPoints
Hình 2.2 Hàm secondPoints
Hình 2.3 Cấu trúc chương trình chính
11
Trang 17- Để mô phỏng chương trình vẽ đồng hồ, ta sử dụng thời gian của hệ thống – sử dụng thư viện ctime.h, ứng với hour ta xây dựng kim giờ, min ta xây dựng kim phút, sec ta xây dựng kim giây
- x[12], y[12] ta sử dụng lưu tọa độ 12 điểm ứng với 12 số giờ trên đồng hồ, mục địch vẽ 12 số tương ứng trên đường tròn
- minx[60], miny[60], secx[60], secy[60] ta sử dụng lưu tọa độ 60 điểm tương ứng với tổng số giây, phút trên đồng hồ ứng với thời gian hệ thống
- hrx[12], hry[12] lưu tọa độ 12 giờ ứng với thời gian hệ thống
- midx, midy ta sử dụng lấy tọa độ trung tâm của màn hình
Hình 2.4 Chương trình chính
12
Trang 18Những hàm được sử dụng:
+ circle(x, y, radius) với x,y là tọa độ vẽ, radius là bán kính đường tròn
+ line(int x1, int y1, int x2, int y2)
Trong đó: x1, y1 là tọa độ điểm bắt đầu vẽ
x2, y2 là tọa độ điểm kết thúc nét vẽ
+ setlinestyle(int linestyle, unsigned upattern,int thickness);
Trong đó:
- linestyle chỉ định kiểu nào trong số các kiểu tiếp theo sẽ được
vẽ (chẳng hạn như nét liền, chấm chấm, căn giữa, nét đứt)
- upattern là một mẫu 16 bit chỉ áp dụng nếu kiểu dòng là
USERBIT_LINE (4)
- Thickness là độ dày của đường thẳng
+ settextjustify(int horiz, int vert) là hàm căn chỉnh text với horiz là hướng text chỉnh theo chiều ngang, vert là hướng text chỉnh theo chiều dọc
+ setcolor(int color) là hàm chỉnh màu
+ settextstyle(int font, int direction, int font_size)
Trong đó:
- Font: kiểu chữ
- Direction: hướng chữ hiển thị
- Font_size: Cỡ chữ
+ outtextxy(int x, int y, char *string) hàm hiển thị chữ
Trong đó:
- x, y là tọa độ chữ hiển thị
- string là chữ cần hiển thị
2 Kết quả thực nghiệm
13
Trang 19Hình 2.5 Kết quả thực nghiệm
KẾT LUẬN
Qua việc thực hiện nghiên cứu đề tài “Xây dựng chương trình đồng hồ điện tử” Em đã được biết thêm rất nhiều về môn đồ họa máy tính Đặc biệt hiểu
rõ hơn về các thuật toán xây dựng bên cạnh chương trình, việc làm nghiên cứu giúp em đoàn kết hơn, rèn luyện cho em kỹ năng làm việc nhóm
Trong quá trình thực hiện đề tài có rất nhiều ý tưởng hay, độc đáo Nhưng
do kiến thức của em hạn hẹp và thời gian không cho phép nên em
Chưa thể thực hiện được những ý tưởng đó Tuy nhiên em đã cố gắng để xây dựng chương trình hoàn trỉnh nhất, đẹp nhất Trong quá trình xây dựng chương trình nhóm em khó tránh khỏi những sai sót Vì vậy em rất mong rằng thầy và các bạn cùng góp ý với em để có thể hòa thành sản phẩm một cách hoàn chỉnh nhất
Em xin cảm ơn thầy Ngô Ngọc Thành đã tận tình giảng dạy em trong môn
Đồ họa máy tính Giúp đỡ em trong quá trình nghiên cứu đề tài Chia sẻ những tài liệu hay
14