Bài hướng dẫn thực hành số 1 môn Đồ họa máy tính

pdf 10 trang phuongnguyen 4680
Bạn đang xem tài liệu "Bài hướng dẫn thực hành số 1 môn Đồ họa máy tính", để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên

Tài liệu đính kèm:

  • pdfbai_huong_dan_thuc_hanh_so_1_mon_do_hoa_may_tinh.pdf

Nội dung text: Bài hướng dẫn thực hành số 1 môn Đồ họa máy tính

  1. Bài hướng dẫn thực hành số 1 Đồ Họa Máy Tính TH00/01 BÀI HƯỚNG DẪN THỰC HÀNH SỐ 1 MÔN ĐỒ HỌA MÁY TÍNH 1 Bài tập thực hành số 1 Viết chương trình (SDI) bằng Visual C++ thực hiện các chức năng sau: 1. Vẽ các đối tượng đoạn thẳng, đường tròn, ellipse. 2. Cho phép thay đổi thuộc tính của các đối tượng này 2 Ví dụ 1 Nội dung: Viết chương trình (SDI) bằng Visual C++ cho phép vẽ các đoạn thẳng bằng mouse: 1. Nhấn nút trái mouse để bắt đầu vẽ một đoạn thẳng mới 2. Giữ nút trái mouse và di chuyển mouse đến vị trí mới 3. Nhả nút trái mouse 2.1 Hướng dẫn 2.1.1 Tạo project mới ™ Trong menu File, chọn chức năng New. ™ Trong tab “Projects” của dialog “New”, chọn mục MFC AppWizard (exe). ™ Nhập tên của Project (ví dụ là “VD1”) vào ô Project name. Sau đó nhấn nút OK ™ Trong dialog MFC AppWizard - Step 1, có 3 mục chọn lựa: Single document (SDI), Multiple documents (MDI) và Dialog based. Trong ví dụ này, chọn mục Single document. Nhấn nút Next để chuyển sang dialog kế tiếp trong wizard. 1
  2. Bài hướng dẫn thực hành số 1 Đồ Họa Máy Tính TH00/01 ™ Trong mỗi dialog tiếp theo của Wizard, chấp nhận các option mặc định. Nhấn nút Next để chuyển sang dialog kế tiếp. Trong dialog cuối cùng, nhấn nút Finish. 2.1.2 Cửa số Workspace Cửa sổ Workspace bao gồm 3 phần chính: ƒ ClassView: thể hiện thông tin các lớp đối tượng chính trong project. ƒ ResourceView: thể hiện thông tin các tài nguyên (resource) trong project, bao gồm accelerator, bitmap, cursor, dialog, html, icon, menu, string table, toolbar, version ƒ FileView: thể hiện danh sách các tập tin trong project: • Source Files chứa các file *.cpp, *.c. • Header Files chứa các file header (*.h) • Resource Files chứa các file resource • 2.1.3 Lớp đối tượng CLine Lớp đối tượng CLine thể hiện đối tượng đoạn thẳng. Mỗi đoạn thẳng được xác định bằng một cặp điểm: điểm đầu (m_P1) và điểm cuối (m_P2) ¾ Tạo lớp đối tượng mới bằng 1 trong 2 cách sau đây: ƒ Chọn chức năng New Class trong menu &Insert ƒ Nhấn nút phải của mouse vào mục đầu tiên trong ClassView để hiển thị popup menu. Chọn chức năng New Class ¾ Trong dialog New Class, thực hiện: ƒ Chọn Class type là Generic Class ƒ Nhập tên lớp đối tượng vào ô Name, ví dụ như CLine. (Tên một lớp đối tượng nên bắt đầu bằng ký tự C hoa. Ví dụ: nếu tên lớp đối tượng là CNewClass thì 2
  3. Bài hướng dẫn thực hành số 1 Đồ Họa Máy Tính TH00/01 Visual C++ sẽ tự động phát sinh ra 2 file tương ứng với lớp đối tượng này là NewClass.h và NewClass.cpp) ƒ Nếu lớp đối tượng sẽ được tạo ra kế thừa từ lớp đối tượng nào thì gõ tên của lớp đối tượng cha vào cột bên trái của bảng Base class(es). Nếu không có sự kế thừa thì bỏ qua bước này. ƒ Nhấn nút OK. ¾ Bổ sung các thuộc tính và các hàm của lớp đối tượng CLine: ƒ Trong file Line.h, khai báo các thuộc tính và các hàm trong lớp CLine • Bổ sung vào lớp đối tượng CLine 2 thuộc tính (protected) sau: CPoint m_P1; // điểm đầu đoạn thẳng CPoint m_P2; // điểm cuối đoạn thẳng • Bổ sung vào lớp đối tượng CLine 3 hàm (public) sau: void SetPoint1(CPoint p); // cập nhật điểm đầu m_P1 void SetPoint2(CPoint p); // cập nhật điểm cuối m_P2 void Draw(CDC* pDC); // Hiển thị đối tượng ƒ Trong file Line.cpp, bổ sung phần cài đặt của các hàm vừa khai báo trong Line.h void CLine::SetPoint1(CPoint p) { m_P1=p; } void CLine::SetPoint2(CPoint p) { m_P2=p; } void CLine::Draw(CDC *pDC) { pDC->MoveTo(m_P1); pDC->LineTo(m_P2); } 2.1.4 Các xử lý trong View 2.1.4.1 Lưu trữ các đối tượng Cần lưu ý thêm dòng sau đây vào đầu file VD1View.cpp #include “Line.h” Để có thể dễ dàng thao tác trên các loại đối tượng khác nhau (đoạn thẳng, đường tròn, ellipse ), chúng ta nên sử dụng mảng 1 chiều chứa con trỏ để lưu trữ các đối tượng này. Khai báo thuộc tính sau trong lớp đối tượng CVD1View: CPtrArray m_Objects; CPtrArray là lớp đối tượng mảng động do Visual C++ cung cấp, mỗi phần tử trong mảng là 1 con trỏ. m_Objects.GetSize() Ù hàm trả về số lượng phần tử trong mảng m_Objects m_Objects[i] Ù phần tử thứ i của mảng m_Objects. Nếu i>= m_Objects.GetSize() thì chương trình sẽ bị lỗi. Xem thêm các chi tiết về lớp đối tượng CPtrArray trong MSDN. 3
  4. Bài hướng dẫn thực hành số 1 Đồ Họa Máy Tính TH00/01 2.1.4.2 Message Message (thông điệp) là cách thức mà Windows thông báo đến ứng dụng. Ví dụ: • WM_PAINT được gửi đến ứng dụng để yêu cầu ứng dụng vẽ lại màn hình của mình. • WM_LBUTTONDOWN hay WM_LBUTTONUP được gửi đến ứng dụng khi người sử dụng nhấn hay thả nút trái mouse trong ứng dụng. • 2.1.4.3 Xử lý message WM_LBUTTONDOWN và WM_LBUTTONUP ¾ Hiển thị màn hình ClassWizard bằng cách nhấn Ctrl-W (hay chọn chức năng ClassWizard trong menu View) ¾ Trong danh sách Class name, chọn lớp đối tượng . (muốn tạo ra các hàm xử lý các message trong lớp đối tượng nào thì chọn lớp đối tượng này trong danh sách Class name). ¾ Trong danh sách Messages, nhấn đúp mouse vào message WM_LBUTTONDOWN để tạo ra hàm OnLButtonDown trong lớp . (khi nhấn đúp mouse vào một message, Visual C++ sẽ tự phát sinh hàm xử lý tương ứng với message này trong lớp đối tượng được chọn trong danh sách Class name). Nhấn nút Edit Code để bắt đầu soạn thảo hàm này. ¾ Một cách tương tự, ta có thể thểm hàm OnLButtonUp trong lớp để xử lý sự kiện nhả nút trái mouse (WM_LBUTTONUP). Nội dung của hàm OnLButtonDown và OnLButtonUp: void CVD1View::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default CLine *pLine = new CLine; // Tạo ra 1 đoạn thẳng mới pLine->SetPoint1(point); // Cập nhật điểm đầu của đoạn thẳng m_Objects.Add(pLine); // Thêm đoạn thẳng mới vào cuối mảng chứa con // trỏ các đối tượng CView::OnLButtonDown(nFlags, point); } void CVD1View::OnLButtonUp(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default if (m_Objects.GetSize()>0) { CLine* pLine = (CLine*)m_Objects[m_Objects.GetSize()-1]; // Thao tác trên đối tượng đoạn thẳng cuối cùng trong mảng pLine->SetPoint2(point); // Cập nhật điểm cuối đoạn thẳng Invalidate(); // Yêu cầu vẽ lại màn hình } CView::OnLButtonUp(nFlags, point); } 2.1.4.4 Hiển thị các đoạn thẳng Hàm OnDraw của lớp CVD1View thực hiện việc vẽ màn hình trong ứng dụng VD1 void CVD1View::OnDraw(CDC* pDC) 4
  5. Bài hướng dẫn thực hành số 1 Đồ Họa Máy Tính TH00/01 { CVD1Doc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here int i, n = m_Objects.GetSize() if (n) for (i=0; i Draw(pDC); } 2.1.4.5 Hủy các đoạn thẳng CVD1View::~ CVD1View() { m_Objects.RemoveAll(); } Hàm RemoveAll của lớp CVD1View sẽ hủy toàn bộ các phần tử trong mảng 2.1.5 Thực hiện chương trình Một số chức năng: Nút Chức năng Nút Chức năng F7 Build Project Ctrl+F7 Build 1 file cpp Ctrl+F5 Execute F5 Start Debug Ctrl+F10 Run to cursor F11 Step Into F10 Step Over Shift+F11 Step Out Shift+F5 Step Debug 5
  6. Bài hướng dẫn thực hành số 1 Đồ Họa Máy Tính TH00/01 3 Mở rộng 3.1 Mở rộng 1 3.1.1 Nội dung ™ VD1a: Viết chương trình (SDI) bằng Visual C++ cho phép vẽ các đường tròn. ™ VD1b: Viết chương trình (SDI) bằng Visual C++ cho phép vẽ các ellipse. 3.1.2 Hướng dẫn m_P1 m_P2 R m_P1 m_P2 • Xây dựng lớp CCircle hay CEllipse để thể hiện đối tượng đường tròn hay ellipse. • Cách xác định đường tròn bằng mouse: o Nhấn và giữ nút trái mouse, di chuyển mouse đến vị trí khác và nhả nút trái mouse. o Vị trí đầu chính (m_P1) là tâm đường tròn. Khoảng cách giữa vị trí đầu (m_P1) và vị trí cuối (m_P2) chính là bán kính đường tròn. • Cách xác định ellipse bằng mouse: o Nhấn và giữ nút trái mouse, di chuyển mouse đến vị trí khác và nhả nút trái mouse. o Vị trí đầu (m_P1) và vị trí cuối (m_P2) xác định hình chữ nhật ngoại tiếp ellipse cần vẽ. 3.2 Mở rộng 2 3.2.1 Nội dung Mỗi chương trình trong VD1, VD1a, VD1b chỉ cần cho phép người sử dụng vẽ một loại đối tượng nhất định (đoạn thẳng, đường tròn hay ellipse). Trong phần mở rộng 2, chương trình cần cho phép người sử dụng vẽ cả 3 loại đối tượng này: Viết chương trình (SDI) bằng Visual C++ cho phép vẽ các đoạn thẳng, đường tròn, ellipse. 3.2.2 Hướng dẫn 3.2.2.1 Các đối tượng được vẽ ¾ Xây dựng lớp đối tượng CShape thể hiện các đối tượng được vẽ. ¾ Các lớp đối tượng CLine, CCircle, CEllipse sẽ kế thừa lớp đối tượng CShape. ¾ Trong lớp CShape có các hàm ảo (virtual) thực hiện thao tác vẽ, cập nhật, truy xuất thông tin. Trong mỗi lớp đối tượng kế thừa từ CShape sẽ cụ thể hóa các hàm này. 6
  7. Bài hướng dẫn thực hành số 1 Đồ Họa Máy Tính TH00/01 CShape CLine CCircle CEllipse ¾ Trong lớp C View vẫn sử dụng mảng CPtrArray m_Objects. Tuy nhiên, trong chương trình này, mỗi phần tử trong mảng m_Objects không phải là con trỏ trỏ đến 1 đối tượng đoạn thẳng (CLine) như trong VD1 mà là con trỏ trỏ đến 1 đối tượng thuộc lớp CShape. Đối tượng này có thể thuộc lớp CLine, CCircle hay CEllipse ¾ Khi tạo ra 1 đối tượng mới, cần xét xem loại đối tượng mà người sử dụng muốn vẽ để tạo ra đối tượng thuộc lớp CLine, CCircle hay CEllipse. CShape* pShape; switch (loại đối tượng muốn vẽ) { case LINE: pShape = new CLine; break; case CIRCLE: pShape = new CCircle; break; case ELLIPSE: pShape = new CEllipse; break; } Cập nhật thông tin của pShape thông qua các hàm ảo của CShape Đưa pShape vào mảng m_Objects ¾ Khi thao tác trên các phần tử trong mảng m_Objects, chỉ cần ép kiểu là (CShape*). Ví dụ: int i, n = m_Objects.GetSize() if (n) for (i=0; i Draw(pDC); 3.2.2.2 Chọn loại đối tượng được vẽ ¾ Bổ sung vào menu hay toolbar của chương trình chức năng chọn loại đối tượng sẽ được vẽ. ¾ Mỗi mục trong menu hay toolbar có 2 sự kiện chính: ƒ UPDATE_COMMAND_UI: Message này phát sinh khi cần cập nhật trạng thái của mục chọn này. ƒ COMMAND: Message này phát sinh khi người sử dụng chọn mục chọn này. 7
  8. Bài hướng dẫn thực hành số 1 Đồ Họa Máy Tính TH00/01 ¾ Việc thêm hàm xử lý các message này hoàn toàn tương tự cách thêm hàm xử lý message WM_LBUTTONDOWN và WM_LBUTTONUP ¾ Để enable hay đặt dấu check vào 1 mục trong menu hay toolbar, sử dụng message UPDATE_COMMAND_UI. Ví dụ: hàm OnUpdateShapeLine dưới đây tương ứng với message UPDATE_COMMAND_UI của mục Line trong menu Shape void CBT1View::OnUpdateShapeLine(CCmdUI* pCmdUI) { // TODO: Add your command update UI handler code here pCmdUI->Enable(TRUE); // TRUE Ù Enable mục Line trong menu Shape // FALSE Ù Disable mục Line trong menu Shape pCmdUI->SetCheck(TRUE); // TRUE Ù Đặt dấu check (9) // FALSE Ù Bỏ dấu check (9) } 3.3 Mở rộng 3 3.3.1 Nội dung Trong các ví dụ trên, đối tượng cần vẽ chỉ được hiển thị sau khi đã vẽ xong (tức sau khi nhả nút trái mouse). Trong phần mở rộng 3, yêu cầu đặt ra là phải hiển thị được đối tượng ngay trong quá trình vẽ. Viết chương trình (SDI) bằng Visual C++ cho phép vẽ các đoạn thẳng, đường tròn, ellipse. Chương trình cần cho phép người sử dụng thấy được đối tượng mình đang vẽ ngay trong quá trình vẽ. 8
  9. Bài hướng dẫn thực hành số 1 Đồ Họa Máy Tính TH00/01 3.3.2 Hướng dẫn ¾ Thuật toán: BOOL bDraw = FALSE; Khi nhấn nút trái mouse thì bDraw = TRUE; Tạo đối tượng mới tại vị trí nhấn nút trái mouse Hiển thị đối tượng vừa mới tạo ra Khi di chuyển mouse thì Nếu bDraw==TRUE Xóa đối tượng đang được vẽ. Cập nhật lại vị trí đối tượng đang được vẽ Hiển thị đối tượng đang được vẽ Khi nhả nút trai mouse thì Nếu bDraw==TRUE Cập nhật lại thông tin đối tượng đang vẽ Hiển thị đối tượng đang được vẽ bDraw=FALSE; ¾ Sử dụng hàm SetROP2 với tham số R2_NOTXORPEN để vẽ các đối tượng với option NOTXORPEN. NORXORPEN Ù Màu pixel sau khi vẽ=NOT(Màu pixel trước khi vẽ XOR Màu bút vẽ) ¾ Khi đó, nếu vẽ cùng 1 đối tượng 2 lần sẽ tương đương với việc xóa đối tượng này. Ví dụ: void CLine::Draw(CDC* pDC) { int OldMode; OldMode = pDC->SetROP2(R2_NOTXORPEN); pDC->MoveTo(m_P1); pDC->LineTo(m_P2); pDC->SetROP2(OldMode); } 3.4 Mở rộng 4 3.4.1 Nội dung Viết chương trình (SDI) bằng Visual C++ thực hiện các chức năng sau: • Cho phép vẽ các đoạn thẳng, đường tròn, ellipse. Cần hiển thị các đối tương ngay trong quá trình vẽ. • Cho phép người sử dụng thay đổi các thuộc tính (màu vẽ, màu tô, mẫu tô, nét vẽ, độ dày nét vẽ ) của các đối tượng này. 3.4.2 Hướng dẫn Các hàm vẽ được cung cấp trong lớp CDC. Ví dụ: MoveTo, LineTo, Rectangle, Ellipse, Khi sử dụng các đối tượng GDI như CPen, CBrush, CFont, CBitmap , cần lưu ý hủy các đối tượng này sau khi dùng xong (bằng hàm DeleteObject) để tránh lãng phí tài nguyên. Khi sử dụng hàm SelectObject của CDC để chọn 1 đối tượng GDI mới, nên lưu lại giá trị trả về của hàm này vì đây là đối tượng GDI đang được CDC sử dụng. Sau khi dùng xong đối 9
  10. Bài hướng dẫn thực hành số 1 Đồ Họa Máy Tính TH00/01 tượng GDI mới, cần trả lại đối tượng GDI mặc định trước đó của CDC (cũng bằng hàm SelectObject). Ví dụ: CPen NewPen; CPen * OldPen; NewPen.CreatePen(PS_SOLID, 1, RGB(255,0,0)); OldPen = pDC->SelectObject(&NewPen); // Sử dụng bút vẽ NewPen // Sau khi sử dụng bút vẽ NewPen pDC->SelectObject(OldPen); NewPen.DeleteObject(); 10