Tải bản đầy đủ (.pdf) (51 trang)

BÁO CÁO CHUYÊN ĐỀ HỌC PHẦN ĐỒ HỌA MÁY TÍNH ĐỀ TÀI MÔ PHỎNG CHUYỂN ĐỘNG TÀ U VŨ TRỤ

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (577.7 KB, 51 trang )

TRƯỜNG ĐẠI HỌC ĐIỆN LỰC
KHOA CÔNG NGHỆ THÔNG TIN

BÁO CÁO CHUN ĐỀ HỌC PHẦN

ĐỒ HỌA MÁY TÍNH
ĐỀ TÀI: MƠ PHỎNG CHUYỂN ĐỘNG TÀU VŨ TRỤ
Sinh viên thực hiện

: LÊ VIỆT LÂM
HỒNG MINH DUY
NGUYỄN MẠNH DŨNG

Giảng viên hướng dẫn

: NGƠ TRƯỜNG GIANG

Ngành

: CÔNG NGHỆ THÔNG TIN

Chuyên ngành

: CÔNG NGHỆ PHẦN MỀM

Lớp

: D13CNPM4

Khóa


: 2018-2023

Hà Nội, tháng 6 năm 2020.

0


PHIẾU CHẤM ĐIỂM
STT

Họ và tên sinh viên

1

LÊ VIỆT LÂM

2

HOÀNG MINH DUY

3

NGUYỄN MẠNH
DŨNG

Họ và tên giảng viên

Nội dung thực hiện

Chữ ký


Điểm

Chữ


Ghi chú

Giảng viên chấm 1:

Giảng viên chấm 2:

1


Contents

Chương 1: Các Thuật Toán Cơ Bản........................................................................................................4
1.

2.

3.

4.

Thuật toán Bressenham...................................................................................................................4
1.1.

Ý tưởng thuật toán Bressenham..............................................................................................4


1.2.

Áp dụng thuật toán Bressenham để vẽ đường thẳng..............................................................4

1.3.

Áp dụng thuật tốn Bressenham để vẽ đường trịn................................................................8

1.4.

Áp dụng thuật tốn Bressenham để vẽ hình elip...................................................................13

Thuật tốn Midpoint......................................................................................................................16
2.1.

Thuật tốn Midpoint vẽ đường thẳng...................................................................................16

2.2.

Thuật tốn Midpoint vẽ đường trịn......................................................................................19

2.3.

Thuật tốn midpoint vẽ hình elip...........................................................................................23

Thuật tốn tơ màu loang...............................................................................................................28
3.1.

Khái niệm...............................................................................................................................28


3.2.

Giải thuật...............................................................................................................................29

Thuật tốn tơ màu qt.................................................................................................................32
4.1.

Khái niệm...............................................................................................................................32

4.2.

Thuật giải...............................................................................................................................32

Chương 2: Phát triển ứng dụng..............................................................................................................33
1.

2

Phân tích bài tốn..........................................................................................................................33
1.1

u cầu bài tốn....................................................................................................................33

1.2

Các bước thực hiện................................................................................................................33

Giải quyết bài tốn.........................................................................................................................33
2.1 Khởi tạo mơi trường 3D và thiết lập hiệu ứng............................................................................33

2.2.

3

Vẽ các đối tượng đồ họa........................................................................................................34

Kết quả thực nghiệm.....................................................................................................................48

2


LỜI NĨI ĐẦU
Đồ họa máy tính là một trong những lĩnh vực hấp dẫn và phát triển rất mau lẹ,
nó làm thay đổi hoàn toàn việc tương tác giữa người và máy. Nhờ vào đồ họa máy
tính mà một hoạt động các ứng dụng máy tính ra đời, đồ họa giúp cho việc giao
tiếp với máy tính trở nên dễ dàng hơn, nó được ứng dụng trong nhiều lĩnh vực như
khoa học cơng nghệ, y học, kiến trúc, giải trí…
Trên cơ sở đó, mơn đồ họa máy tính đã được đưa vào giảng dạy ở chuyên
ngành công nghệ thông tin và các lĩnh vực liên quan khác trong các trường đại học.
Môn này là tiền đề cung cấp cho sinh viên các lý thuyết cơ sở nhằm kiến tạo và xử
lý thơng tin dưới dạng hình ảnh giúp cho việc giao tiếp với máy tính dễ dàng hơn
trong các mơn ngành khác như: xử lý ảnh, kỹ thuật CAD.
Báo cáo được chia làm 2 chương, chương I các thuật toán cơ bản, chương II
phát triển ứng dụng :”Mô phỏng chuyển động tàu vũ trụ” .
Chương I : Cài đặt thuật tốn Midpoint, bressenham vẽ đường thẳng (hệ số góc
bất kỳ - nhập tọa độ điểm đầu , điểm cuối ), đường trịn (nhập tọa độ tâm và bán
kính). Xây dựng dưới dạng hàm và gọi thực thi trong chương trình chính.Cài đặt
thuật tốn tơ màu tràn, tơ màu theo đường quét.
Chương II: Phát tiển ứng dụng sử dụng các hàm trong OpenGL để phát triển ứng
dụng 3D phản ánh các kỹ thuật trong đồ họa 3D: Tô màu, chiếu sáng, textmaping,

phản chiếu, chuyển động...

3


Chương 1: Các Thuật Toán Cơ Bản

1.

Thuật toán Bressenham

1.1.

Ý tưởng thuật toán Bressenham
- Thay thế các phép toán các phép toán trên số thực bằng các phép
toán trên số nguyên
- Giảm thời gian của thuật toán hơn so với DDA.
- Hạn chế phép toán được thực hiện để giảm tải thời gian.

1.2.

Áp dụng thuật toán Bressenham để vẽ đường thẳng

1.2.1. Đặt vấn đề
Cho 2 điểm A (x1, y1) và B (x2, y2). Vẽ đường thẳng đi qua A, B.
1.2.2. Thuật giải
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. Đó là so sánh khoảng cách giữa điểm thực y với
2 điểm gần kề nó nhất. Nếu điểm nào nằm gần điểm thực hơn thì
sẽ được chọn làm điểm vẽ tiếp theo.


4


Hình 1.1: Mơ tả thuật tốn Bressenham
Ta có phương trình đường thẳng có dạng:
y = mx +b, m = ∆y / ∆x
Gọi d1 là khoảng cách từ điểm M đến điểm Q
Gọi d2 là khoảng cách từ điểm M đến điểm P
Ta có:
Nhìn vào hình bên ta thấy:
d1 = yi +1 -y = yi +1 – m(xi+1) – b
d2 = y- yi = m(xi+1) + b - yi
Ta xét (d1-d2):
d1-d2 > 0 => d1>d2 => Yi+1 = Yi +1
Ngược lại: d1 ≤ d2 => Yi+1 = Yi
5


d1 – d2 = [m(xi + 1) + b - yi] – [yi + 1 - m(xi + 1) - b]
= m(xi + 1) + b – yi - yi – 1 + m(xi + 1) + b
= 2m(xi +1) – 2yi + 2b -1
Dễ thấy d1-d2 tồn tại phép toán với số thực m = dy/dx. Và để tuân thủ theo
đúng ý tưởng thuật toán chỉ thực hiện các phép toán trên số nguyên, ta khử
phân số (triệt tiêu mẫu số) bằng cách nhân 2 vế với dx:
Đặt pi = dx(d1 -d2)
 Pi = dx[2m(xi +1) + 2b – 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 )
Mặt khác dx ≥ 0 với mọi trường hợp

 Dấu của pi cùng dấu với (d1-d2)
 pi > 0 => yi+1 = yi +1
pi ≤ 0 => yi+1 = yi
ta có Pi+1 = 2dyxi+1 – 2dxyi+1 + c
Pi = 2dyxi - 2dxyi + c
 Pi+1 - Pi = 2dy(xi+1 - xi) – 2dx(yi+1- yi)
= 2dy – 2dx(yi+1 – yi ) với (xi+1 – xi) = 1
Pi+1 = Pi + 2dy – 2dx(yi+1 – yi )
Nếu Pi < 0 => yi+1 = yi => Pi+1 = Pi + 2dy
Ngược lại Pi < 0 => yi+1 = yi +1 => Pi+1 = Pi + 2(dy – dx)
Ta có P1 = 2x1dy – 2y1dx + c
= 2x1dy -2((dy/dx)x1 + b)dx + 2dy + (2b -1)dx
= 2dy -dx
Lưu đồ thuật toán:

6


Hình 1.2: Lưu đồ thuật tốn Bressenham vẽ đường thẳng
Code minh họa:
{

void BrePoint(int x1, int y1, int x2, int y2)
glColor3f(1, 0, 0);
glBegin(GL_POINTS);
int dx = abs(x2 - x1);
int dy = abs(y2 - y1);
int p = 2 * dy - dx;
int c1 = 2 * dy;
int c2 = 2 * (dy - dx);

int x = x1; int y = y1;
glVertex2i(x, y);
while (x < x2)
{
7


if (p < 0)
{
p = p + c1;
}
else
{
p = p + c2;
y++;
}
x++;
glVertex2i(x, y);

}
glEnd();
return;
}

1.3.

Áp dụng thuật toán Bressenham để vẽ đường trịn

1.3.1. Thuật giải
Cho đường trịn tâm (xc,yc) bán kính R: (x-xc)^2 + (y-yc)^2 = R^2

Xét đường tròn tâm (xc,yc) ta có :
Đường trịn có tính đối xứng nên ta chỉ cần vẽ 1/8 cung tròn và lấy
đối xứng qua các điểm: (-x,y), (x,y), (y,x), (y,-x), (x,-y), (-x,-y), (y, -x), (-y,x)

8


Hình 1.3: Hình trịn với các điểm đối xứng
Ta có xi+1 = xi +1 và yi+1 = yi hay yi+1 = yi -1
Phương trình đường trịn tâm (xc,yc) bán kính R : (x-xc)2 + (y-yc)2 = R2
Đặt d1 = yi 2 – y2 và d2 = y2 – (yi -1)2
Đặt pi = d1-d2 do đó việc chọn tọa độ của yi+1 phụ thuộc và dấu của pi:

Hình 1.4: Xác định và vẽ các tọa độ
9


d1 = yi 2 – y2 = yi 2 – (R2 – (xi +1)2)
d2 = y2 – (yi -1)2 = (R2 – (xi +1)2) - (yi -1)2
Xét pi = d1-d2 = (yi)2+(yi-1)2-2(R2 – (xi+1)2)
Tính pi+1 - pi = 4xi + 6 + 2((yi-1)2 – (yi)2) – 2(yi+1 – yi))
 pi+1 = pi + 4xi + 6 + 2((yi-1)2 – (yi)2) – 2(yi+1 – yi))
Xác định dấu của pi thì ta sẽ xác định được yi+1
Nếu pi < 0 thì yi+1 = yi khi đó pi+1 = pi + 4xi + 6
Nếu pi >= 0 thì yi+1 = yi-1 nên pi+1 = pi + 4(xi – yi) + 10
Gía tri p đầu tiên được tính tại điểm (x1,y1) = (0,R) là p1 = 3-2R

10



Hình 1.5: Lưu đồ thuật tốn Bressenham vẽ hình trịn

11


Code minh họa :
void BresCircle(int xc ,int yc, int r)
{
glColor3b(1, 1, 0.5);
glBegin(GL_POINTS);
int p1;
p1 = 3 - 2 * r;
int x = 0;
int y = r;
glVertex2i(x, y);
while (x <= y)
{
if (p1 < 0)
{
p1 += 4 * x + 6;
}
else
{
p1 += 4 * (x - y) + 10;
y--;
}
x++;
glVertex2i(x + xc, y + yc);
glVertex2i(-x + xc, y + yc);
glVertex2i(x + xc, -y + yc);

glVertex2i(-x + xc, -y + yc);
glVertex2i(y + xc, x + yc);
glVertex2i(-y + xc, x + yc);
glVertex2i(y + xc, -x + yc);
glVertex2i(-y + xc, -x + yc);
}
glEnd();
return;
}

12


1.4.

Áp dụng thuật tốn Bressenham để vẽ hình elip
1.4.1 Thuật giải:
Tính khoảng cách từ điểm thực đến 2 điểm vẽ được, xem
khoảng cách nào ngắn hơn.
Vẽ 1 nửa elip, sau đó lấy đối xứng qua các đường phân giác.
Phương trình đường elip có dang:
x2/a2 + y2/b2 =1
=> y2 = -(b2 / a2).x2 + b2
=> x2 = -( a2 / b2).y2+ a2
Chúng ta sẽ đi vẽ từng nửa elip. Ở mỗi nửa elip, chúng ta lại
phải vẽ theo hai nhánh khác nhau. Đó là một nhánh từ trên xuống, và
một nhánh từ dưới lên. Hai nhánh này cắt nhau tại giao điểm mà ở đó
hệ số góc của tiếp tuyến với Elip bằng -1.Chúng ta dễ dàng thấy được
nhánh vẽ từ trên xuống : khi x tăng lên 1 đơn vị thì y chỉ tăng lên rất ít
; và ngược lại với nhánh vẽ từ dưới lên: khi y tăng lên 1 đơn vị thì x

chỉ tăng lên rất ít. Nếu như chúng ta chọn cách vẽ liền một mạch thì
việc tăng lên không đồng đều của tọa độ x và y sẽ khiến đường elip
không mịn, đứt gãy, rất xấu. Do đó, muốn vẽ được đường elip mịn
nét, chúng ta sẽ phải chia elip thành 2 nhánh để vẽ.

Hình 1.6: Vẽ elip theo 2 hướng
13


Xét nhánh 1 từ trên xuống :
Giả sử giao điểm (xi,yi) đã được vẽ điểm tiếp theo cần được vẽ
là điểm (xi+1, yi) hoặc (xi+1, yi-1)
Thay (xi+1) vào phương trình ta được: y2 = -(b2 / a2).(xi +1)2 + b2
Đặt
d1 = yi2 – y2 = yi2 + (b2 / a2).(xi +1)2 + b2
d2 = y2 – (yi – 1)2 = -(b2 / a2).(xi +1)2 + b2 – (yi – 1)2
=> pi = d1 - d2 = 2[b2/a2.(xi + 1)2-b2] + 2(yi2 + yi) -1
pi+1 = 2[b2/a2.(xi+1 + 1)2-b2] + 2((yi+1)2 + yi+1) -1
Suy ra
pi+1 - pi = 2 b2/a2[(xi+1 + 1)2 - (xi + 1)2] + 2[(yi+1)2 + yi+1 - yi2 - yi] (*)
pi<0: chọn yi+1 = yi
từ (*) => pi+1 = pi + 2.(b2/a2).(2x+3)
pi ≥ 0 chọn yi+1 = yi – 1
từ (*) => pi+1 = pi + 2.(b2/a2).(2x+3) – 4yi
với điểm đầu tiên (0,b) ta có:
pi = 2(b2 / a2) – 2b + 1
Xét nhánh 2 từ dưới lên :
Giả sử giao điểm (xi,yi) đã được vẽ điểm tiếp theo cần được vẽ
là điểm (xi, yi+1) hoặc (xi-1, yi+1)
Thay (yi+1) vào phương trình ta được: x2 = -( a2 / b2).y2+ a2

Đặt
d1 = xi2 – x2 = xi2 + (a2 / b2).(yi +1)2 + a2
d2 = x2 – (xi – 1)2 = -(a2 / b2).(yi +1)2 + a2 – (xi – 1)2
=> pi = d1 - d2 = 2[a2/b2.(yi + 1)2-a2] + 2(xi2 + xi) -1
pi+1 = 2[a2/b2.(yi+1 + 1)2-a2] + 2((yi+1)2 + yi+1) -1
Suy ra
pi+1 - pi = 2 a2/b2[(yi+1 + 1)2 - (yi + 1)2] + 2[(xi+1)2 + xi+1 - xi2 - xi] (*)
pi<0: chọn xi+1 = xi
từ (*) => pi+1 = pi + 2.(a2/b2).(2y+3)
pi ≥ 0 chọn xi+1 = xi – 1
từ (*) => pi+1 = pi + 2.(a2/b2).(2y+3) – 4xi
với điểm đầu tiên (a,0) ta có:
pi = 2(a2 / b2) – 2a + 1
code minh họa:
void BreElip(int xc, int yc, int a, int b)// ve elipse
14


{

glColor3f(1, 0, 0);
glBegin(GL_POINTS);
float p, a2, b2;
int x, y;
a2 = pow(a, 2);
b2 = pow(b, 2);
x = 0;
y = b;
p = 2 * ((float)b2 / a2) - (2 * b) + 1;
//ve nhanh thu 1(tu tren xuong )

while (((float)b2 / a2) * x <= y)
{
glVertex2i(xc + x, yc + y);
glVertex2i(xc - x, yc + y);
glVertex2i(xc - x, yc - y);
glVertex2i(xc + x, yc - y);
if (p < 0)
{
p = p + 2 * ((float)b2 / a2) * (2 * x + 3);
}
else {
p = p - 4 * y + 2 * ((float)b2 / a2) * (2 * x + 3);
y--;
}
x++;
}
//ve nhanh thu 2(tu duoi len )
y = 0;
x = a;
p = 2 * ((float)a2 / b2) - 2 * a + 1;
while (((float)a2 / b2) * y <= x)
{
glVertex2i(xc + x, yc + y);
glVertex2i(xc - x, yc + y);
glVertex2i(xc - x, yc - y);
glVertex2i(xc + x, yc - y);
if (p < 0)
15



{
}
else
{

p = p + 2 * ((float)a2 / b2) * (2 * y + 3);

p = p - 4 * x + 2 * ((float)a2 / b2) * (2 * y + 3);
x = x - 1;

}
y = y + 1;

}
glEnd();
return;

}

2. Thuật toán Midpoint
2.1. Thuật toán Midpoint vẽ đường thẳng
Thuật giải:
Cho 2 điểm A(x1,y1) và B(x2,y2). Vẽ đường thẳng đi qua 2 điểm A,B

Hình 1.7 : Vẽ đường thẳng bằng thuật toán midpoint

16


Thuật toán Midpoint đưa ra cách chọn điểm 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.
Nếu điểm Q nằm dưới điểm Midpoint thì ta chọn điểm S là điểm vẽ tiếp theo.
Ngược lại , nếu điểm Q nằm trên điểm Midpoint thì ta chọn P.
Ta có dạng tổng qt của PT đường thẳng :
Ax + By +C=0
Với A= yo –y1 ; B= -(x2 –x1) ; C=x2y1 –x1y2
Đặt F(x,y)= Ax+ By +C
Đặt F(x,y)= Ax+ By +C
Ta có nhận xét:
Vị trí tương đối của điểm Midpoint (x,y) với đường thẳng:
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) thuộc về đườ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 các điểm S, P ở trên được đưa về việc xét dấu của
pi = 2F(Midpoint) = 2F(xi +1 , yi +1/2)


Nếu pi < 0 ⇒ Midpoint nằm phía trên đường thẳng ⇒Lúc này điểm thực Q
nằm phía dưới điểm Midpoint  ⇒ Chọn S(xi+1,yi) .



Nếu pi >= 0 ⇒ Midpoint nằm phía dưới đường thẳng ⇒ Lúc này điểm thực
Q nằm trên điểm Midpoint ⇒ Chọn P(xi+1,yi+1).

Mặt khác:
pi+1 –pi = 2F(xi+1 +1 , yi+1 +1/2) – 2F(xi +1 , yi +1/2)
⇒ pi+1 –pi =2[A(xi+1  +1) + B(yi+1  +1/2) +C] – 2[A(xi +1) + B(yi+1/2) +C]
⇒ pi+1 –pi = 2A + 2B(yi+1   – yi)
⇒ pi+1 –pi = 2Dy  – 2Dx(yi+1   – yi)

Vậy
17


pi+1 =pi + 2Dy  nếu pi <0 do ta chọn yi+1 =yi
pi+1 =pi + 2Dy  – 2Dx nếu pi >=0 do ta chọn  yi+1 =yi  +1
Ta tính giá trị p1  ứng với điểm ban đầu (x1, y1) với nhận xét rằng điểm (x1, y1) là
điểm thuộc đường thẳng, tức là có Ax1 + By1 + C =0.
p1 = 2F(x1 +1, y1 +1/2) = 2[A(x1 +1) +B(y1 +1/2) +C]
⇒ p1 = 2(Ax1 + By1 +C) +2A +B
⇒ p1 = 2A + B
⇒ p1 = 2Dy-Dx
Lưu đồ thuật tốn:

Hình 1.8: Lưu đồ thuật tốn midpoint vẽ đường thẳng
18


Code minh họa :
void Midpoint(int x1, int y1, int x2, int y2) {
//Truong hop 0glColor3f(1, 0, 0);
glBegin(GL_POINTS);
int a, b, pi, x, y, p;
a = y2 - y1;
b = -(x2 - x1);
y = y1;
x = x1;
glVertex2i(x, y); //Ve diem pixel dau tien
p = 2 * a + b;

//tinh vi tri tuong doi cua diem Midpoint so voi duong
thang
while (x < x2) {
if (p < 0) {
p += 2 * a; // ta chon chon diem yi
}
else {
y++;
p += 2 * (a + b);//ta chon diem yi +1
}
x++;
glVertex2i(x, y);

}

}
glEnd();
return;

2.2.

Thuật tốn Midpoint vẽ đường trịn
Thuật giải:
Đường trịn có tâm O(xc, yc) = (0, 0), bán kinh r có phương trình:
x2 + y2 = r2 => x2 + y2 - r2 = 0
Đặt f(x, y) = x2 + y2 - r2
19




×