Bài giảng Ngôn ngữ lập trình C/C++ - Phạm Hồng Thái - Chương 6: Đồ họa và âm thanh
Màn hình ở chế độ đồ hoạ là tập hợp các điểm (pixel-picture elements) ảnh. Số điểm ảnh và cách bố trí theo chiều ngang, dọc của màn hình được gọi là độ phân giải (resolution). Vì vậy độ phân giải thường được đặc trưng bởi một cặp số chỉ định số điểm ảnh theo chiều ngang và chiều dọc của màn hình. Ví dụ màn hình VGA ở mode 2 có độ phân giải là 640x480, tức trên mỗi dòng ngang của màn hình có thể vẽ được 640 điểm ảnh và trên mỗi cột dọc vẽ được 480 điểm ảnh. Các cột và dòng được đánh số từ 0, theo chiều từ trái sang phải (đối với cột) và từ trên xuống dưới (đối với dòng). Một điểm ảnh hay còn gọi là pixel là giao điểm của một cột và một dòng nào đó trên màn hình và vị trí của nó được thể hiện bởi cặp toạ độ (x,y) với x biểu diễn cho cột và y biểu diễn cho dòng. Ví dụ với màn hình trên điểm ảnh “đầu tiên” nằm ở góc trên bên trái của màn hình có toạ độ (0,0) và điểm “cuối cùng” ở góc dưới bên phải có toạ độ (639,479). Điểm có toạ độ (150,200) là giao điểm của cột thứ 150 và dòng 200.
x = 2*pi*i*tileX/200; y = sin(2*pi*i/200)*tileY; putpixel(x, y, 1); } setviewport(0, 0, maxx, maxy, 0); } void Sinoverx() // Ham Sinx/x { float t; float tileX = 50/pi; float tileY = 80; int x, y; for (x = 30; x < maxx-30; x++) { t = ((x==midx)? 1 : (x-midx))/tileX; y = midy - int(sin(t)/t*tileY); putpixel(x, y, 2); } } Ve do thi theo tham so (x = x(t), y = y(t)) void Hypocycloide() // Ham x = cos3t, y = sin3t { // t Î [0, 2p] float t; int i, x, y; for (i = 0; i<1000; i++) { t = (pi/500)*i; x = int(120*pow(cos(t), 3)) + midx; y = int(120*pow(sin(t), 3)) + midy; putpixel(x, y, 3); } } void Trocoide() // Ham (2t-3sint, 2-3cost) { // t Î [-9, 9] float t; int i, x, y; for (i = -1000; i<=1000; i++) { t = 0.01*i; x = int(15*(2*t-3*sin(t))) + midx; y = -int(10*(2-3*cos(t))) + midy; putpixel(x, y, 4); } } void So3() // x = sintcos2t + sint { // y = sin2tcost, t Î [0, 2p] float t; int i, x, y; for (i = 0; i<=1000; i++) { t = (pi/500)*i; x = int(150*(sin(t)*(1+cos(t)*cos(t)))) + midx; y = int(200*sin(t)*sin(t)*cos(t)) + midy; putpixel(x, y, 5); } } Ve do thi theo toa do cuc r = j(q) void Archimede() // Ham r = q, q Î [0, 40] { int i, x, y; float r, t; for (i = 0;i<=2500;i++) { t = 0.02*i; x = int(3*t*cos(t))+midx; y = -int(3*t*sin(t))+midy; putpixel(x, y, 6); } } void Hoahong() // Ham r = sin2q, q Î [0, 2p] { int i, x, y; float r, t; for (i = 0;i<=2000;i++) { t = (pi/500)*i; x = int(150*(sin(2*t)*cos(t)))+midx; y = int(150*sin(2*t)*sin(t))+midy; putpixel(x, y, 7); } } Chương trình dưới đây cho phép vẽ hai mặt trong không gian 3 chiều được cho bởi hai hàm f = sinx.siny và g = typedef struct TOADO { int OX, OY, UX, UY, UZ; // truc hoanh, tung va don vi cac truc double Xx, Xy; // goc (OX, ox), (OY, oy) }; TOADO gr3 = { 320, 20, 20, 20, 20, 0.8*pi, 0.2*pi }; void Vetruc() // Ve truc Ox, Oy { setviewport(0, 0, maxx, maxy, 0); settextstyle(DEFAULT_FONT, HORIZ_HUONG, 0); setcolor(WHITE); line(0, midy, maxx, midy); line(maxx-7, midy-3, maxx, midy); line(maxx-7, midy+3, maxx, midy); line(midx, 0, midx, maxy); line(midx-3, 7, midx, 0); line(midx+3, 7, midx, 0); outtextxy(midx+6, midy+6, "(0, 0)"); outtextxy(maxx-18, midy+6, "x"); outtextxy(midx+8, 6, "y"); setbkcolor(CYAN); setcolor(RED); settextstyle(TRIPLEX_FONT, HORIZ_HUONG, 2); outtextxy(10, 0, "DO THI KHONG GIAN 3 CHIEU"); } int X(double x, double y, double z) // doi toa do xyz sang truc X { return gr3.OX + x*gr3.UX*cos(gr3.Xx) + y*gr3.UY*cos(gr3.Xy); } int Y(double x, double y, double z) // doi toa do xyz sang truc Y { return gr3.OY + x*gr3.UX*sin(gr3.Xx) + y*gr3.UY*sin(gr3.Xy) - z*gr3.UZ; } double f(double x, double y) // Ham f(x, y) can ve { return 4*sin(x)*sin(y); } double g(double x, double y) // Ham g(x, y) can ve { return 5*sin(sqrt(x*x+y*y))/sqrt(x*x+y*y); } void Vehamf() { double x, y, z; double xa = -6.28, xb = 6.28; double ya = -6.28, yb = 6.28; double xp = 0.2, yp = 0.2; int mat[8]; settextstyle(TRIPLEX_FONT, HORIZ_HUONG, 1); outtextxy(10, 20, "Ham z = sinx.siny"); setviewport(0, midy, maxx, maxy, 0); for (x = xa; x <= xb; x+=xp) // ve mat an for (y = ya; y <= yb; y+=yp) { if (kbhit()) return; z = f(x, y); // diem A mat[0] = X(x, y, z); mat[1] = Y(x, y, z); z = f(x, y+yp); // diem B mat[2] = X(x, y+yp, z); mat[3] = Y(x, y+yp, z); z = f(x+xp, y+yp); // diem C mat[4] = X(x+xp, y+yp, z); mat[5] = Y(x+xp, y+yp, z); z = f(x+xp, y); // diem D mat[6] = X(x+xp, y, z); mat[7] = Y(x+xp, y, z); if ((mat[3]-mat[1]) * (mat[6]-mat[0]) - (mat[7]-mat[1]) * (mat[2]-mat[0]) < 0) setfillstyle(1, YELLOW); else setfillstyle(1, GREEN); fillpoly(4, mat); delay(10); } getch(); } void Vehamg() { double x, y, z; double xa = -10, xb = 10; double ya = -10, yb = 10; double xp = 0.1, yp = 0.1; settextstyle(TRIPLEX_FONT, HORIZ_DIR, 1); outtextxy(10, 20, "Ham z = sin(sqrt(x*x+y*y))"); outtextxy(100, 30, "------------"); outtextxy(115, 40, "sqrt(x*x+y*y)"); setviewport(0, midy, maxx, maxy, 0); setcolor(BLUE); for (x = xa; x <= xb; x+=xp) for (y = ya; y <= yb; y+=yp) { if (kbhit()) return; z = g(x, y); lineto(X(x, y, z), Y(x, y, z)); delay(10); } getch(); } void main() { Initgraph(); Vetruc(); Vehamf(); cleardevice(); Vetruc(); Vehamg(); closegraph(); } ÂM THANH Âm thanh được đặc trưng bởi cao độ (tần số) và trường độ (độ dài). Việc tạo ra một chuỗi âm (bài hát chẳng hạn), là sự kết hợp lặp đi lặp lại của các hàm sau với các tham số n và t được chọn thích hợp. - sound(n): phát âm ra loa máy tính với tần số n. - delay(t): kéo dài trong t miligiây. - nosound(): tắt âm thanh đã phát. : Tiếng còi báo động void coi(int cao; int thap) { do { sound(cao); delay(400); sound(thap); delay(400); } while (!kbhit()) nosound(); } : Tiếng bóng nảy void bong(int cao; int thap) { int sodem = 20; while (sodem > 1) { sound(thap-2*sodem); delay(sodem*500/20); nosound(); delay(100); sound(cao); delay(sodem*500/15); nosound(); delay(150); sodem --; } } : Tiếng bom void bong(int cao; int thap; int t) { int sodem = thap; while (sodem <= cao) { sound(sodem); delay(t/sodem*75); sodem += 10; } for (sodem =1 to 3) { nosound(); sound(40); delay(500); nosound(); delay(100); } sound(40); delay(3000); nosound(); } Để tạo âm phát của một nốt nhạc có tần số (cao độ) n và dài trong t miligiây cần viết hàm : void not(unsigned n, float t); { sound(n); delay(t); nosound(); } : Chơi bài hát Tiến quân ca trên nền cờ đỏ sao vàng. #include #include #include #include // cao độ của các nốt nhạc #define do1 66 #define dod1 70 #define re1 73 #define red1 78 #define mi1 82 #define fa1 86 #define fad1 91 #define sol1 96 #define sold1 102 #define la1 108 #define lad1 115 #define si1 122 #define do2 130 #define dod2 139 #define re2 148 #define re2 148 #define red2 156 #define mi2 164 #define fa2 176 #define fad2 188 #define sol2 196 #define sold2 209 #define la2 230 #define lad2 233 #define si2 247 #define do3 264 #define dod3 281 #define re3 297 #define red3 313 #define mi3 330 #define fa3 352 #define fad3 374 #define sol3 396 #define sold3 415 #define la3 440 #define lad3 468 #define si3 495 #define do4 528 #define dod4 565 #define re4 594 #define red4 625 #define mi4 660 #define fa4 704 #define fad4 748 #define sol4 792 #define sold4 836 #define la4 880 #define lad4 935 #define si4 990 #define lang 30000 void not(unsigned caodo, float truongdo) { sound(caodo); delay(truongdo); nosound(); } void main() { int gdriver = DETECT, gmode; initgraph(&gdriver, &gmode, "c:\\borlandc\\bgi"); int star[20] = {320, 150, 285, 225, 200, 225, 270, 270, 240, 350, 320, 300, 390, 350, 360, 270, 430, 225, 345, 225}; setbkcolor(RED); setcolor(YELLOW); // Vẽ lá cờ đỏ sao vàng setfillstyle(SOLID_FILL, YELLOW); fillpoly(10, star); // Trường độ các nốt nhạc float d = 300; // đen float tr = 2*d; // trắng float tro = 4*d; // tròn float md = d/2; // móc đen float mk = d/4; // móc kép float m3 = d/8; // móc 3 float m4 = d/16; // móc 4 float dc = 3*d/2; // đen chấm float trc = 3*d; // trắng chấm float troc = 6*d; // tròn chấm // Choi bai TQC not(re2, d); not(mi2, d); not(re2, d); not(sol2, tr); not(sol2, tro); not(la2, d); not(sol2, d); not(si2, tr); not(si2, tro); not(la2, d); not(sol2, d); not(mi2, tr); not(sol2, tr); not(sol2, d); not(mi2, tro); not(re2, d); not(si2, d); not(re2, tro); not(sol2, d); not(la2, d); not(si2, tr); not(si2, tr); not(si2, tr); not(la2, d); not(sol2, d); not(re3, tro); not(si2, d); not(sol2, d); not(la2, tr); not(la2, tr); not(si2, tr); not(fad2, d); not(re2, d); not(sol2, tro); not(si2, d); not(do3, d); not(re3, tr); not(re3, tr); not(mi3, tro); not(re3, d); not(si2, tro); not(si2, tr); not(la2, d); not(sol2, tr); not(re2, tr); not(fad2, tr); not(fad2, d); not(la2, d); not(sol2, tr); not(si2, d); not(do3, d); not(re3, tr); not(re3, tr); not(mi3, tro); not(re3, d); not(si2, tro); not(si2, tr); not(la2, d); not(sol2, tr); not(sol2, tr); not(re2, tro); not(re3, tro); not(si2, tr); not(sol2, tr); not(mi3, tro); not(re3, tr); not(si2, d); not(la2, d); not(re2, d); not(la2, tr); not(la2, tro); not(si2, tr); not(sol2, tro); closegraph(); } BÀI TẬP Vẽ hai hình chữ nhật, lần lượt cho mất từng hình, rồi hiện lại cả hai. Biểu diễn dãy 5 giá trị (được nhập từ bàn phím) bằng biểu đồ bar. Biểu diễn dãy 5 giá trị (được nhập từ bàn phím) bằng biểu đồ hình quạt. Vẽ một bàn cờ quốc tế với các ô đen trắng. Viết chương trình vẽ đồ thị hàm số y = 100*sin(x/4.8) trong khoảng x Î [0, 60] với giá trị mỗi bước Dx = 0,1. Yêu cầu : nền màn hình mầu đen. trục tọa độ màu xanh lá cây đồ thị màu trắng. Viết chương trình vẽ tam giác với các tọa độ đỉnh lần lượt là A(300, 20), B(100, 220), C(500, 220) và đường tròn ngoại tiếp của nó. Yêu cầu : nền màn hình mầu đen. các cạnh tam giác màu xanh lá cây đường tròn ngoại tiếp màu đỏ tươi. Viết chương trình vẽ hình chữ nhật có tọa độ đỉnh góc trên bên trái là (100,150), chiều ngang 120, chiều dọc 90 và đường tròn ngoại tiếp nó. Yêu cầu : nền màn hình mầu đen. các cạnh hình chữ nhật màu xanh da trời. đường tròn ngoại tiếp màu đỏ tươi. Vẽ tam giác nội tiếp trong hình tròn, hình tròn nội tiếp trong elip. Tô các màu khác nhau cho các miền tạo bởi các đường trên. Vẽ một đài phát sóng. Các vòng sóng phát từ đỉnh của tháp ở tâm màn hình lan tỏa ra chung quanh. Quá trình lặp đến khi ấn phím bất kỳ thì dừng. Vẽ hai hình người đi vào từ 2 phía màn hình với tốc độ khác nhau. Gặp nhau hai hình người xoay lại và đi ngược về 2 phía màn hình. Chương trình dừng khi cả hai đã đi khuất vào hai phía của màn hình.
File đính kèm:
- Bài giảng Ngôn ngữ lập trình CC++ - Phạm Hồng Thái - Chương 6 Đồ họa và âm thanh.doc