Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 41 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
41
Dung lượng
1,08 MB
Nội dung
ĐỀ THI CÓ 2 CÂU ĐƯỢC CHỌN TRONG 2 PHẦN MỖI CÂU 5 ĐIỂM SINH VIÊN KHÔNG ĐƯỢC XEM TÀI LIỆU PHẦN I 16 CÂU, CHỌN 1 TRONG 16 CÂU, MỖI CÂU 5 ĐIỂM Câu 1: Xây dựng và cài đặt thuật toán vẽ đoạn thẳng đi qua hai điểm ),( 11 yx và ),( 22 yx . Quy ước vẽ từ ),( 11 yx đến ),( 22 yx Đáp án: Ta phân biệt các trường hợp: Đường ngang và 21 xx ≤ hoặc 21 xx > Đường dọc và 21 yy ≤ hoặc 21 yy > Trị tuyệt đối hệ số góc 1|| ≤m và 21 xx ≤ hoặc 21 xx > Trị tuyệt đối hệ số góc 1|| >m và 21 yy ≤ hoặc 21 yy > Ta có phương trình đường thẳng đi qua 2 điểm ),( 11 yx và ),( 22 yx là 12 1 12 1 yy yy xx xx − − = − − . hay 11 12 12 )( yxx xx yy y +− − − = , đặt 12 12 xx yy m − − = và 11 ymxb +−= . Vậy ta có phương trình bmxy += . int Round(double a) { return (int)(a+0.5); } void Line(HDC hdc, int x1, int y1, int x2, int y2) { int x, y; double m, b; COLORREF Color = RGB(255,0,0); // Duong ngang if (y1 == y2) if (x1 <= x2) for (x=x1; x<=x2; x++) SetPoint(hdc,x,y1,Color); else for (x=x1; x>=x2; x ) SetPoint(hdc,x,y1,Color); // Duong doc else if (x1 == x2) if (y1 <= y2) for (y=y1; y<=y2; y++) SetPoint(hdc,x1,y,Color); else for (y=y1; y>=y2; y ) SetPoint(hdc,x1,y,Color); else { m = 1.0*(y2-y1)/(x2-x1); b = -m*x1 + y1; if (fabs(m) <= 1) if (x1 <= x2) for (x=x1; x<=x2; x++) { y = Round(m*x+b); SetPoint(hdc,x,y,Color); } else for (x=x1; x>=x2; x ) { y = Round(m*x+b); SetPoint(hdc,x,y,Color); } else { m = 1.0*(x2-x1)/(y2-y1); b = -m*y1 + x1; if (y1 <= y2) for (y=y1; y<=y2; y++) { x = Round(m*y+b); SetPoint(hdc,x,y,Color); } else for (y=y1; y>=y2; y ) { x = Round(m*y+b); SetPoint(hdc,x,y,Color); } } } return; } Câu 2: Xây dựng và cài đặt thuật toán vẽ đường tròn có phương trình là 222 ryx =+ ra chính giữa màn hình. Đáp án: Ta có phương trình đường tròn là 222 ryx =+ Do tính đối xứng của đường tròn, nên ta chỉ cần vẽ cung I, các cung còn lại đều suy ra từ cung I. Quan sát trên hình vẽ, ta thấy ở cung I, x tăng nhanh hơn y, nên ta dùng phương trình )(xfy = , hay 22 xry −= , tức là khi lập trình ta cho x chạy rồi tính y. int Round(double a) { return (int)(a+0.5); } void Circle(HWND hWnd) { HDC hdc; RECT rt; int xc, yc; hdc = GetDC(hWnd); GetClientRect(hWnd,&rt); xc = rt.right/2; yc = rt.bottom/2; int x, y, r = 100; x = 0; y = r; SetPixel(hdc,xc+x,yc-y,RGB(255,0,0)); SetPixel(hdc,xc+y,yc-x,RGB(255,0,0)); SetPixel(hdc,xc+y,yc+x,RGB(255,0,0)); SetPixel(hdc,xc+x,yc+y,RGB(255,0,0)); SetPixel(hdc,xc-x,yc+y,RGB(255,0,0)); SetPixel(hdc,xc-y,yc+x,RGB(255,0,0)); SetPixel(hdc,xc-y,yc-x,RGB(255,0,0)); SetPixel(hdc,xc-x,yc-y,RGB(255,0,0)); while (x < y) { x++; y = Round(sqrt(1.0*r*r-x*x)); SetPixel(hdc,xc+x,yc-y,RGB(255,0,0)); SetPixel(hdc,xc+y,yc-x,RGB(255,0,0)); SetPixel(hdc,xc+y,yc+x,RGB(255,0,0)); SetPixel(hdc,xc+x,yc+y,RGB(255,0,0)); SetPixel(hdc,xc-x,yc+y,RGB(255,0,0)); SetPixel(hdc,xc-y,yc+x,RGB(255,0,0)); SetPixel(hdc,xc-y,yc-x,RGB(255,0,0)); SetPixel(hdc,xc-x,yc-y,RGB(255,0,0)); } ReleaseDC(hWnd,hdc); return; } Câu 3: Xây dựng và cài đặt thuật toán vẽ ellipse có phương trình là 1 2 2 2 2 =+ b y a x ra chính giữa màn hình. Đáp án: Ta có phương trình của ellipse là 1 2 2 2 2 =+ b y a x sát trên đồ thị, ta thấy: Cung I có x tăng nhanh hơn y, nên ta dùng phương trình 22 xa a b y −= , tức là khi lập trình ta cho x chạy rồi tính y. Cung II có y tăng nhanh hơn x, nên ta dùng phương trình 22 yb b a x −= , tức là khi lập trình ta cho y chạy rồi tính x. Để xác định được điểm chuyển tiếp A( ) , AA yx , ta cho đạo hàm cấp một của phương trình 22 xa a b y −= bằng -1. 1' 22 −= − −= xaa bx y 22 2 ba a x A + = Như vậy ta chỉ cần vẽ cung I và II, các cung còn lại lấy đối xứng là được. int Round(double a) { return (int)(a+0.5); } void Ellipse(HWND hWnd) { HDC hdc; RECT rt; int xc, yc; hdc = GetDC(hWnd); int x, y; GetClientRect(hWnd,&rt); xc = rt.right/2; yc = rt.bottom/2; int a = 300, b = 200; int xa = Round(a*a/sqrt(1.0*a*a+b*b)); x=0; y=b; SetPixel(hdc,xc+x,yc-y,RGB(255,0,0)); SetPixel(hdc,xc+x,yc+y,RGB(255,0,0)); SetPixel(hdc,xc-x,yc+y,RGB(255,0,0)); SetPixel(hdc,xc-x,yc-y,RGB(255,0,0)); while (x<xa) { x++; y = Round(1.0*b/a*sqrt(1.0*a*a-x*x)); SetPixel(hdc,xc+x,yc-y,RGB(255,0,0)); SetPixel(hdc,xc+x,yc+y,RGB(255,0,0)); SetPixel(hdc,xc-x,yc+y,RGB(255,0,0)); SetPixel(hdc,xc-x,yc-y,RGB(255,0,0)); } while (y>0) { y ; x = Round(1.0*a/b*sqrt(1.0*b*b-y*y)); SetPixel(hdc,xc+x,yc-y,RGB(255,0,0)); SetPixel(hdc,xc+x,yc+y,RGB(255,0,0)); SetPixel(hdc,xc-x,yc+y,RGB(255,0,0)); SetPixel(hdc,xc-x,yc-y,RGB(255,0,0)); } ReleaseDC(hWnd,hdc); return; } Câu 4: Xây dựng và cài đặt thuật toán vẽ parabola a x y 2 = có a dương ra chính giữa màn hình. Đáp án: Quan sát trên đồ thị, ta thấy Cung I có x tăng nhanh hơn y nên ta dùng phương trình a x y 2 = , tức là khi lập trình ta cho x chạy rồi tính y. Cung II có y tăng nhanh hơn x nên ta dùng phương trình ayx = , tức là khi lập trình ta cho y chạy rồi tính x. Để xác định được điểm chuyển tiếp A( ) , AA yx , ta cho đạo hàm cấp một của phương trình a x y 2 = bằng 1. 1 2 ' == a x y hay 2 a x A = Như vậy ta chỉ cần vẽ cung I và II, nhánh còn lại của parabola lấy đối xứng là được. void Parabola(HWND hWnd) { HDC hdc; RECT rt; int xc, yc; hdc = GetDC(hWnd); int x, y; int a = 100; int xa = Round(1.0*a/2); GetClientRect(hWnd,&rt); xc = rt.right/2; yc = rt.bottom/2; x=0; y=0; SetPixel(hdc,xc+x,yc-y,RGB(0,0,0)); while (x < xa) { x++; y = Round(1.0*x*x/a); SetPixel(hdc,xc+x,yc-y,RGB(0,0,0)); SetPixel(hdc,xc-x,yc-y,RGB(0,0,0)); } while (y < 250) { y++; x = Round(sqrt(1.0*a*y)); SetPixel(hdc,xc+x,yc-y,RGB(0,0,0)); SetPixel(hdc,xc-x,yc-y,RGB(0,0,0)); } ReleaseDC(hWnd,hdc); return; } Câu 5: Xây dựng và cài đặt thuật toán vẽ đường xy sin= trong một chu kỳ ra chính giữa màn hình. Đáp án: Ta phải chuẩn hóa phương trình xy sin= để có thể vẽ ra màn hình, chẳng hạn ta chuẩn hóa như sau: N x Ay π 2 sin= với x = 0 N Quan sát trên đồ thị, ta nhận thấy: Cung I có x tăng hơn y nên ta dùng phương trình N x Ay π 2 sin= , tức là khi lập trình ta cho x chạy rồi tính y. Cung II có y tăng hơn x nên ta dùng phương trình = A yN x arcsin 2 π , tức là khi lập trình ta cho y chạy rồi tính x. Để xác định được điểm chuyển tiếp A( ) , AA yx , ta cho đạo hàm cấp một của phương trình N x Ay π 2 sin= bằng 1. 1 2 cos 2 ' = = N x N A y ππ = A N ar N x A ππ 2 cos 2 Như vậy ta chỉ cần vẽ cung I và II, các cung còn lại lấy đối xứng là được. int Round(double a) { return (int)(a+0.5); } void Sin(HWND hWnd) { HDC hdc; RECT rt; double pi = 4.0*atan(1.0); int xc, yc; int x, y; int A = 200, N = 400; int xa = Round(N/(2*pi)*acos(N/(2*pi*A))); hdc = GetDC(hWnd); GetClientRect(hWnd,&rt); xc = rt.right/2; yc = rt.bottom/2; x = N/4; y = A; SetPixel(hdc,x,yc-y,RGB(0,0,0)); SetPixel(hdc,N/2-x,yc-y,RGB(0,0,0)); SetPixel(hdc,N/2+x,yc+y,RGB(0,0,0)); SetPixel(hdc,N-x,yc+y,RGB(0,0,0)); while (x>xa) { x ; y = Round(A*sin(2*pi*x/N)); SetPixel(hdc,x,yc-y,RGB(0,0,0)); SetPixel(hdc,N/2-x,yc-y,RGB(0,0,0)); SetPixel(hdc,N/2+x,yc+y,RGB(0,0,0)); SetPixel(hdc,N-x,yc+y,RGB(0,0,0)); } while (y>0) { y ; x = Round(N/(2*pi)*asin(1.0*y/A)); SetPixel(hdc,x,yc-y,RGB(0,0,0)); SetPixel(hdc,N/2-x,yc-y,RGB(0,0,0)); SetPixel(hdc,N/2+x,yc+y,RGB(0,0,0)); SetPixel(hdc,N-x,yc+y,RGB(0,0,0)); } ReleaseDC(hWnd,hdc); return; } Câu 5: Xây dựng và cài đặt thuật toán DDA (Digital Differential Analyzer) vẽ đoạn thẳng đi qua hai điểm ),( 11 yx và ),( 22 yx . Giới hạn chỉ xét hệ số góc 10 ≤< m và 21 xx < . Đáp án: Ta có phương trình đường thẳng đi qua 2 điểm ),( 11 yx và ),( 22 yx là 12 1 12 1 yy yy xx xx − − = − − . Do giới hạn hệ số góc 10 ≤< m , tức là x tăng nhanh hơn y nên ta dùng phương trình )(xfy = , hay 11 12 12 )( yxx xx yy y +− − − = , đặt 12 12 xx yy m − − = và 11 ymxb +−= . Vậy ta có phương trình bmxy += . Ở bước k ta có bmxy kk += Ở bước k+1 ta có bmxy kk += ++ 11 Do x tăng nhanh hơn y nên 1 1 += + kk xx Suy ra mbmxbxmy kkk ++=++= + )1( 1 Hay myy kk += +1 So sánh phương trình bmxy kk += với phương trình myy kk += +1 , ta thấy bớt đi một phép nhân. Đại lượng kk kk xx yy − − + + 1 1 được gọi là vi phân số (sai phân), do myy xx yy kk kk kk =−= − − + + + 1 1 1 nên thuật toán có tên là bộ phân tích sai phân. int Round(double a) { return (int)(a+0.5); } void DDALine(HWND hWnd, int x1, int y1, int x2, int y2) { HDC hdc; hdc = GetDC(hWnd); [...]... SetPixel(hdc,xc-y,yc-x,RGB(255,0,0)); SetPixel(hdc,xc-x,yc-y,RGB(255,0,0)); } ReleaseDC(hWnd, hdc); return; } Câu 8: Xây dựng và cài đặt thuật toán vẽ ellipse có phương trình là giữa màn hình bằng thuật toán Bresenham Đáp án: x2 y2 + = 1 ra chính a2 b2 Quan sát trên đồ thị, ta thấy: Cung I có x tăng nhanh hơn y, nên ta dùng phương trình y = b a 2 − x 2 , tức là khi lập a trình ta cho x chạy rồi tính... SetPixel(hdc,xc+x,yc+y,RGB(0,0,0)); SetPixel(hdc,xc-x,yc+y,RGB(0,0,0)); SetPixel(hdc,xc-x,yc-y,RGB(0,0,0)); } } ReleaseDC(hWnd,hdc); return; x2 Câu 9: Xây dựng và cài đặt thuật toán vẽ parabola y = với a nguyên dương ra chính a giữa màn hình dùng thuật toán Bresenham Đáp án: Quan sát trên đồ thị, ta thấy Cung I có x tăng nhanh hơn y nên ta dùng phương trình y = x2 , tức là khi lập trình ta a cho x chạy rồi tính y Cung II có y tăng... SetPixel(hdc,xc-y,yc-x,RGB(255,0,0)); SetPixel(hdc,xc-x,yc-y,RGB(255,0,0)); } } ReleaseDC(hWnd,hdc); return; x2 y2 Câu 15: Xây dựng và cài đặt thuật toán vẽ ellipse có phương trình là 2 + 2 = 1 ra a b chính giữa màn hình bằng thuật toán MidPoint Đáp án: Quan sát trên đồ thị, ta thấy: Cung I có x tăng nhanh hơn y còn cung II có y tăng nhanh hơn x nên để xác định được b a2 − x2 điểm chuyển tiếp A( x A , y... 1 và x1 < x 2 , nên ở: Bước k ta có ( x k , y k ) Bước k + 1 ta có ( x k +1 , y k +1 ) = ( x k + 1, y k +1 ) , trong đó y k +1 = y k hoặc y k +1 = y k + 1 Mục đích của thuật toán Bresenham là dùng toàn số nguyên để tính toán cho nhanh Thuật toán gồm 3 bước: Bước 1: Tính d1 và d 2 d1 = y k +1 − y k d 2 = y k + 1 − y k +1 nên d1 và d 2 dương d = d1 − d 2 Gọi Nhận xét: nếu d < 0 thì y k +1 = y k d ≥ 0... = −1 a a2 − x2 a2 xA = a2 + b2 Như vậy ta chỉ cần vẽ cung I và II, các cung còn lại lấy đối xứng là được Thuật toán Bresenham gồm 3 bước: Xét cung I: Bước k ta có ( x k , y k ) Bước k + 1 ta có ( x k +1 , y k +1 ) = ( x k + 1, y k +1 ) , trong đó y k +1 = y k hoặc y k +1 = y k − 1 Mục đích của thuật toán Bresenham là dùng toàn số nguyên để tính toán cho nhanh Bước 1: Tính d1 và d 2 d1 = y k +1 − (... p = p + 2*dy; else { p = p + 2*dy - 2*dx; y++; } x++; Sleep(20); SetPixel(hdc,x,y,RGB(255,0,0)); } ReleaseDC(hWnd,hdc); return; } Câu 7: Xây dựng và cài đặt thuật toán vẽ đường tròn có phương trình là x 2 + y 2 = r 2 ra chính giữa màn hình bằng thuật toán Bresenham Đáp án: Do tính đối xứng của đường tròn, nên ta chỉ cần vẽ cung 18 , các cung còn lại lấy đối xứng là được Cung cần vẽ có x tăng nhanh... cần vẽ cung I và II, nhánh còn lại của parabola lấy đối xứng là được Mục đích của thuật toán Bresenham là dùng toàn số nguyên để tính toán cho nhanh Xét cung I: Ta có x tăng nhanh hơn y Bước k ta có ( x k , y k ) Bước k + 1 ta có ( x k +1 , y k +1 ) = ( x k + 1, y k +1 ) , trong đó y k +1 = y k hoặc y k +1 = y k + 1 Thuật toán Bresenham gồm 3 bước: Bước 1: Tính d1 và d 2 d1 = y k +1 − y k d 2 = y k... ( x, y ) < 0 thì điểm ( x, y ) nằm phía trên đường thẳng F ( x, y ) ≥ 0 thì điểm ( x, y ) nằm trùng hay nằm phía dưới đường thẳng Thuật toán MidPoint gồm 3 bước: Bước 1: Tính F (M ) với M = ( x k + 1, y k + 1 ) 2 1 F ( M ) = A( x k + 1) + B ( y k + 2 ) + C Mục đích của thuật toán MidPoint là dùng số nguyên để tính cho nhanh Ta thấy F (M ) có đại lượng 1 nên F (M ) là số thực Ta phải chuyển F (M ) thành... y ) < 0 thì điểm ( x, y ) nằm phía dưới đường thẳng nếu F ( x, y ) ≥ 0 thì điểm ( x, y ) nằm trùng hoặc nằm phía trên đường thẳng Thuật toán MidPoint gồm 3 bước: Bước 1: Tính F (M ) với M = ( x k − 1, y k − 1 ) 2 1 F ( M ) = A( x k − 1) + B ( y k − 2 ) + C Mục đích của thuật toán MidPoint là dùng số nguyên để tính cho nhanh Ta thấy F (M ) có đại lượng 1 nên F (M ) là số thực Ta phải chuyển F (M ) thành... F ( x, y ) < 0 thì điểm ( x, y ) nằm bên trái đường thẳng F ( x, y ) ≥ 0 thì điểm ( x, y ) nằm trùng hay nằm bên phải đường thẳng Thuật toán MidPoint gồm 3 bước: Bước 1: Tính F (M ) với M = ( x k + 1 , y k + 1) 2 1 F ( M ) = A( x k + 2 ) + B ( y k + 1) + C Mục đích của thuật toán MidPoint là dùng số nguyên để tính cho nhanh Ta thấy F (M ) có đại lượng 1 nên F (M ) là số thực Ta phải chuyển F (M ) thành . ĐỀ THI CÓ 2 CÂU ĐƯỢC CHỌN TRONG 2 PHẦN MỖI CÂU 5 ĐIỂM SINH VIÊN KHÔNG ĐƯỢC XEM TÀI LIỆU PHẦN I 16 CÂU, CHỌN 1 TRONG 16 CÂU, MỖI CÂU 5 ĐIỂM Câu 1: Xây dựng và cài đặt thuật toán vẽ. hdc); return; } Câu 8: Xây dựng và cài đặt thuật toán vẽ ellipse có phương trình là 1 2 2 2 2 =+ b y a x ra chính giữa màn hình bằng thuật toán Bresenham. Đáp án: Quan sát trên đồ thị, ta thấy: Cung I có x. Round(1.0*a/b*sqrt(1.0*b*b-y*y)); SetPixel(hdc,xc+x,yc-y,RGB(255,0,0)); SetPixel(hdc,xc+x,yc+y,RGB(255,0,0)); SetPixel(hdc,xc-x,yc+y,RGB(255,0,0)); SetPixel(hdc,xc-x,yc-y,RGB(255,0,0)); } ReleaseDC(hWnd,hdc); return; } Câu 4: Xây dựng và cài đặt thuật toán vẽ parabola a x y 2 = có a dương ra chính giữa màn hình. Đáp án: Quan sát trên đồ thị, ta thấy Cung I có x tăng nhanh hơn y nên