logo资料库

计算机图形学 图形剪裁.doc

第1页 / 共7页
第2页 / 共7页
第3页 / 共7页
第4页 / 共7页
第5页 / 共7页
第6页 / 共7页
第7页 / 共7页
资料共7页,全文预览结束
南昌大学实验报告 学生姓名: 陈洁 实验类型:□ 验证 □ 综合 □ 设计 □ 创新 实验日期: 08.12.1 一、实验项目名称:线段裁剪 号: 6103106040 学 专业班级: 计算机 062 实验成绩: 二、实验目的:理解和掌握 Cohen-SutherLand 裁剪的原理和算法。 三、实验基本原理: 对于每条线段 P1P2 分为三种情况处理分为三种情况处理: (1)若 P1P2 完全在窗口内,则显示该线段 P1P2 简称“取”之; (2)若 P1P2 明显在窗口外,则丢弃该线段,简称“弃”之; (3)若线段不满足“取”或 “弃”的条件,则在交点处把线段分为两段。其中一段完全在窗口外,可 弃之。然后对另一段重复上述处理。 将区域码的各位从右到左编号,则坐标区域与各位的关系为: 上 下 右 左 X X 任何位赋值为 1,代表端点落在相应的位置上,否则该位为 0。若端点在剪取矩形内,区域码为 0000。 如果端点落在矩形的左下角,则区域码为 0101。 一旦给定所有的线段端点的区域码,就可以快速判断哪条直线完全在剪取窗口内,哪条直线完全在 窗口外。所以得到一个规律: X X – 若 P1P2 完全在窗口内 code1=0,且 code2=0,则“取” – 若 P1P2 明显在窗口外 code1&code2≠0,则“弃” – 在交点处把线段分为两段。其中一段完全在窗口外,可弃之。然后对另一段重复上述处理。 如何判定应该与窗口的哪条边求交呢? 编码中对应位为 1 的边。 计算线段 P1(x1,y1)P2(x2,y2)与窗口边界的交点。 具体算法见书上 p201。 1001 1000 1010 0001 0000 0010 0101 0100 0110 编码 P1 P3 P4 P2 线段裁剪 四、主要仪器设备及耗材:PC 微机;Windows 操作系统;Visual C++ 程序集成环境。 五、实验步骤: 1、理解和掌握 Cohen-SutherLand 裁剪的原理和算法; 2、根据算法编写(或修改)程序裁剪线段; 3、对程序进行编译,纠正程序中可能出现的语法错误; 4、测试程序运行效果:从键盘输入数据,在屏幕上输出,检查输出结果。 六、实验数据及处理结果 编写程序如下: // 裁剪 Dlg.h:header file // #if !defined(AFX_DLG_H__BE852DB5_A0A9 _4DC6_A10F_6D35796C1BDE__INCLUDED _) #define
AFX_DLG_H__BE852DB5_A0A9_4DC6_A1 0F_6D35796C1BDE__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 // CMyDlg dialog class CMyDlg : public CDialog { // Construction public: CMyDlg(CWnd* pParent = NULL); standard constructor // Dialog Data //{{AFX_DATA(CMyDlg) enum { IDD = IDD_MY_DIALOG }; // // NOTE: the ClassWizard will add data function void // members here //}}AFX_DATA // ClassWizard generated virtual overrides //{{AFX_VIRTUAL(CMyDlg) protected: virtual DoDataExchange(CDataExchange* pDX); DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: int code(int x,int y); HICON m_hIcon; CDC pic;//图片 int top,but;// int lef,rig;//矩形 int lxb,lyb; int lxe,lye;//直线坐标 BOOL ldb;//左键是否按下。 int step;//步骤 // Generated message map functions //{{AFX_MSG(CMyDlg) virtual BOOL OnInitDialog(); afx_msg void OnSysCommand(UINT nID, LPARAM lParam); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); afx_msg void OnButton4(); afx_msg void OnButton1(); afx_msg void OnButton2(); afx_msg void OnLButtonDown(UINT nFlags, CPoint point); afx_msg void OnLButtonUp(UINT nFlags, CPoint point); afx_msg void OnMouseMove(UINT nFlags, CPoint point); afx_msg void OnButton3(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_DLG_H__BE852DB5_A0A9_ 4DC6_A10F_6D35796C1BDE__INCLUDED_ ) // 裁剪 Dlg.cpp : implementation file // #include "stdafx.h" #include "裁剪.h" #include "裁剪 Dlg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif // CAboutDlg dialog used for App About class CAboutDlg : public CDialog { public: CAboutDlg(); // Dialog Data //{{AFX_DATA(CAboutDlg) enum { IDD = IDD_ABOUTBOX }; //}}AFX_DATA // ClassWizard generated virtual overrides //{{AFX_VIRTUAL(CAboutDlg) protected: function
: void pDX); virtual DoDataExchange(CDataExchange* // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: //{{AFX_MSG(CAboutDlg) //}}AFX_MSG DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() CDialog(CAboutDlg::IDD) { //{{AFX_DATA_INIT(CAboutDlg) //}}AFX_DATA_INIT } void CAboutDlg::DoDataExchange(CDataExchange * pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAboutDlg) //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) //{{AFX_MSG_MAP(CAboutDlg) // No message handlers //}}AFX_MSG_MAP END_MESSAGE_MAP() // CMyDlg dialog CMyDlg::CMyDlg(CWnd* /*=NULL*/) : CDialog(CMyDlg::IDD, pParent) { //{{AFX_DATA_INIT(CMyDlg) pParent // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT // Note that LoadIcon does not subsequent DestroyIcon in Win32 = m_hIcon AfxGetApp()->LoadIcon(IDR_MAINFRAME); ldb = FALSE; require a step = 0; top = 20,but = 100,lef = 20,rig = 100; lxb = 0,lyb = 0; lxe = 50,lye = 50; } void CMyDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CMyDlg) // NOTE: the ClassWizard will add DDX and DDV calls here //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CMyDlg, CDialog) //{{AFX_MSG_MAP(CMyDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_BUTTON4, OnButton4) ON_BN_CLICKED(IDC_BUTTON1, OnButton1) ON_BN_CLICKED(IDC_BUTTON2, OnButton2) ON_WM_LBUTTONDOWN() ON_WM_LBUTTONUP() ON_WM_MOUSEMOVE() ON_BN_CLICKED(IDC_BUTTON3, OnButton3) //}}AFX_MSG_MAP END_MESSAGE_MAP() // CMyDlg message handlers BOOL CMyDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu =
GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX) if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR) ; ; pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } // Set // Set small } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); big icon SetIcon(m_hIcon, FALSE); icon // TODO: Add extra initialization here CPaintDC dc(this); pic.CreateCompatibleDC(&dc); CBitmap * bp1,*obp1; bp1 = new CBitmap; bp1->LoadBitmap(IDB_B); obp1 = pic.SelectObject(bp1); obp1->DeleteObject(); return TRUE; the focus to a control } void CMyDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { // return TRUE unless you set CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); to draw the icon. For MFC applications this is automatically done for you by the } } // If you add a minimize button to your dialog, you will need the code below // using the document/view model, // framework. void CMyDlg::OnPaint() { CPaintDC dc(this); painting if (IsIconic()) { SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // device context for // Center icon in client rectangle int cxIcon GetSystemMetrics(SM_CXICON); int cyIcon GetSystemMetrics(SM_CYICON); = = CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } CDC mdc; CBitmap bmp,*bp; bmp.LoadBitmap(IDB_B); mdc.CreateCompatibleDC(GetDC()); bp = mdc.SelectObject(&bmp); pic.BitBlt(0,0,500,320,&mdc,0,0,SRCCOPY); mdc.SelectObject(bp); CDC * dc1; CWnd * wd1; wd1 = this->GetDlgItem(IDC_S); dc1 = wd1->GetDC();
pic.MoveTo(lxb,lyb); pic.LineTo(lxe,lye); pic.MoveTo(lef,top); pic.LineTo(rig,top); pic.LineTo(rig,but); pic.LineTo(lef,but); pic.LineTo(lef,top); dc1->BitBlt(1,1,496,309,&pic,0,0,SRCCOPY); } // The system calls this to obtain the cursor to display while the user drags // the minimized window. HCURSOR CMyDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } void CMyDlg::OnButton4() { // TODO: Add your control notification handler code here OnOK(); } void CMyDlg::OnButton1() { // TODO: Add your control notification handler code here step = 1; } void CMyDlg::OnButton2() { // TODO: Add your control notification handler code here step = 2; } void CMyDlg::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default if(step){ if(point.x>11&&point.x<508&&point.y>11&& point.y<321){ ldb = TRUE; switch(step){ case 1: top = point.y-12; lef = point.x-12; break; case 2: lxb = point.x-12; lyb = point.y-12; break; } } } CDialog::OnLButtonDown(nFlags, point); } void CMyDlg::OnLButtonUp(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default if(ldb){ ldb = FALSE; int ti; switch(step){ case 1: but = point.y-12; rig = point.x-12; if(butrig){ti = lef;lef = rig;rig = ti;} break; ti;} case 2: lxe = point.x-12; lye = point.y-12; break; } Invalidate(FALSE); } CDialog::OnLButtonUp(nFlags, point); } void CMyDlg::OnMouseMove(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default if(ldb){
switch(step){ case 1: but = point.y-12; rig = point.x-12; break; case 2: lxe = point.x-12; lye = point.y-12; break; } Invalidate(FALSE); } CDialog::OnMouseMove(nFlags, point); } #define LEFT 1 #define RIGHT 2 #define BOTTOM 4 #define TOP 8 int CMyDlg::code(int x,int y){//编码函数 int c = 0; if(xrig) c = c|RIGHT; if(y>but) c = c|BOTTOM; else if(y
七、思考讨论题或体会或对改进实验的建议 Cohen-Sutherland 线段裁剪算法小结:  本算法的优点在于简单,易于实现。他可以简单的描述为将直线在窗口左边的部分删去, 按左,右,下,上的顺序依次进行,处理之后,剩余部分就是可见的了。在这个算法中求 交点是很重要的,他决定了算法的速度。另外,本算法对于其他形状的窗口未必同样有效。  特点:用编码方法可快速判断线段的完全可见和显然不可见。 八、参考资料:计算机图形学(第 3 版)及其实验指导书
分享到:
收藏