当前位置:文档之家› 计算机图形学 多边形裁剪与填充 计算机图形学课程设计

计算机图形学 多边形裁剪与填充 计算机图形学课程设计

课程设计报告课程名称计算机图形学课题名称多边形裁剪与填充专业计算机科学与技术班级计算机0902学号姓名指导教师刘长松曹燚2012年10 月9 日湖南工程学院课程设计任务书课程名称计算机图形学课题多边形裁剪与填充专业班级计算机0902学生姓名学号指导老师刘长松曹燚审批任务书下达日期2012年9月15 日任务完成日期2012 年10月9 日一、设计内容与设计要求1.设计内容:交互式地实现多边形的裁剪和填充。

2.设计要求:1)窗口功能设计。

2)实现鼠标画多边形与数据存储功能。

3)实现鼠标剪裁窗口选择功能。

4)实现多边形裁剪和填充功能。

3.算法提示:多边形裁剪算法分析:基本思想是一次用窗口的一条边裁剪多边形,窗口的一条边以及延长线构成裁剪线,该线把平面分成两个部分:可见一侧,不可见一侧。

用一条裁剪边对多边形进行裁剪,得到一个顶点序列,作为下一条裁剪边处理过程的输入点。

对于每一条裁剪边,只是判断点在窗口的哪一测以及求线段与裁剪边的交点算法应随之改变。

多边形填充算法分析:确定多边形所占有的最大扫描线数,得到多边形顶点的最小和最大y值(ymin 和ymax),从y=ymin 到 y=ymax, 每次用一条扫描进行填充。

对一条扫描线填充的过程可分为四个步骤: a.求交b.排序c.交点配对d.区间填色。

二、进度安排第 3 周星期一8:00——12:00星期二8:00——12:00星期三8:00——12:00星期四8:00——12:00星期五8:00——12:00第 4 周星期一8:00——12:00附:课程设计报告装订顺序:封面、任务书、目录、正文、附件(A4大小的图纸及程序清单)、评分。

正文的格式:一级标题用3号黑体,二级标题用四号宋体加粗,正文用小四号宋体;行距为22。

正文的内容:一、课题的主要功能;二、课题的功能模块的划分(要求画出模块图);三、主要功能的实现(至少要有一个主要模块的流程图);四、程序调试;五、总结;六、附件(所有程序的原代码,要求对程序写出必要的注释)。

正文总字数要求在5000字以上(不含程序原代码)。

一、题目内容说明:1、交互式地实现多边形的裁剪和填充。

2、功能要求:1)窗口功能设计。

2)实现鼠标画多边形与数据存储功能。

4)实现鼠标剪裁窗口选择功能。

5)实现多边形裁剪和填充功能。

二、总体设计:本程序使用MFC实现多边形的裁剪和填充绘图程序。

多边形裁剪算法分析:基本思想是一次用窗口的一条边裁剪多边形,窗口的一条边以及延长线构成裁剪线,改线把平面分成两个部分:可见一侧,不可见一侧。

用一条裁剪边多多边形进行裁剪,得到一个顶点序列,作为吓一条裁剪边处理过程的输入点。

对于每一条裁剪边,只是判断点在窗口的哪一测以及求线段与裁剪边的交点算法应随之改变。

仅用一条裁剪边时,逐次多边形裁剪框图:在CGraphics类的CutRectangular(CRect)函数中实现对多边形的裁剪多边形填充算法分析:确定多边形所占有的最大扫描线数,得到多边形顶点的最小和最大y值(ymin和ymax),从y=ymin 到 y=ymax, 每次用一条扫描进行填充。

对一条扫描线填充的过程可分为四个步骤: a.求交b.排序c.交点配对d.区间填色。

在CGraphics类中的FillPlogon函数中实现多边形的填充算法。

三、模块设计:各个程序函数的功能,参数,变量的说明:MFC应用程序框架中类的详细解析:1.MainFrm:创建窗口及窗口里的菜单、工具栏、状态栏等实现交互的按钮。

1)函数int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct){}创建菜单、工具栏、状栏。

2)BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)设置窗口的大小和初始位置。

2.图像裁剪View:视图,负责内存数据与用户的交互,包括数据的显示、菜单的选取,鼠标的响应。

1.void CMyView::OnLButtonDown(UINT nFlags, CPoint point){}对鼠标按下左键的响应,如果是自定义裁剪的区域操作就捕获鼠标按下的点,画裁剪区域,如果是自定义点坐标的操作就捕获鼠标的点画多边形。

2.void CMyView::OnMouseMove(UINT nFlags, CPoint point){}对鼠标移动的响应。

用捕获的点画出相应的矩形裁剪边框。

画边框的时候,先用白色擦出原先的矩形边框,再用虚线画出新的举行边框3.void CMyView::OnRButtonUp(UINT nFlags, CPoint point){}对鼠标放开左键的相应。

如果是自定义点的坐标,就获取新的初始裁减矩形范围。

4.void CMyView::OnLButtonUp(UINT nFlags, CPoint point){}对鼠标放开左键的响应5.void CMyView::OnInitialUpdate(){}初始化裁剪区域和在窗口中画一个矩形和一个五角星。

6.void CMyView::OnDraw(CDC* pDC){}重画窗口,用voidCMyView::OnInitialUpdate{}来启动它,通过消息映射表处理菜单、工具条、快捷键和其他用户消息。

定义裁剪矩形区域,并赋值。

当自定义多边形坐标时,在各个点坐标处画一个小圆,以显示点的位置。

画出多边形。

3.图像裁剪DOC:文档,负责内存数据与磁盘的交互。

1、void CMyDoc::OnFillployon(){}2、void CMyDoc::OnUpdateFillployon(CCmdUI* pCmdUI){}3、void CMyDoc::OnCutRect(){}4、void CMyDoc::OnUpdateCutRect(CCmdUI* pCmdUI){}4.CGraphics:实现多边形的填充和裁剪。

1、构造函数CGraphics():PointCount(10),Point(NULL){}初始化五角星的顶点坐标。

2、析构函数~CGraphics(){}删除动态生成的Point指针。

3、bool DrawPloyon(CDC*);在指定设备中画多边形。

4、bool FillPloyon(CDC*);填充多边形。

5、bool InterCross(CPoint,CPoint,CPoint,CPoint,CPoint&);判断两条线段是否相交。

6、bool CutRect(CRect);对多边形进行裁剪。

7、bool IsInSquareRgn(CRect,CPoint,int);对多边形裁剪时,判断线段断点是否在可视一侧。

8、bool SortArray(int*,int);冒泡排序。

四、详细设计:1、创建窗口、菜单、工具栏、状栏的函数。

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct){if (CFrameWnd::OnCreate(lpCreateStruct) == -1)return -1;if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||!m_wndToolBar.LoadToolBar(IDR_MAINFRAME)){TRACE0("Failed to create toolbar\n");return -1; // fail to create}if (!m_wndStatusBar.Create(this) ||!m_wndStatusBar.SetIndicators(indicators,sizeof(indicators)/sizeof(UINT))){TRACE0("Failed to create status bar\n");return -1; // fail to create}// TODO: Delete these three lines if you don't want the toolbar to// be dockablem_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);EnableDocking(CBRS_ALIGN_ANY);DockControlBar(&m_wndToolBar);return 0;}2、鼠标按下左键的响应函数void CMyView::OnLButtonDown(UINT nFlags, CPoint point){//对鼠标按下左键的相应CScrollView::OnLButtonDown(nFlags, point);if(m_bDefineRect){//如果是自定义裁减的区域的操作SetCapture();//捕获鼠标m_bCaptured = TRUE;CDC *dc=GetDC();CRect rect(TopLeft,BottomRight);dc->SelectStockObject(WHITE_PEN);dc->Rectangle(rect);InvalidateRect(rect,false);TopLeft = point;::SetCursor(::LoadCursor(NULL, IDC_CROSS));//设置鼠标样子为十字形的}if(m_bDefinePointV){//如果是自定义点坐标的操作PointArray.Add(point);CRect ellipseRect;ellipseRect.top = point.y - 5;ellipseRect.bottom = point.y + 5;ellipseRect.left = point.x - 5;ellipseRect.right = point.x + 5;InvalidateRect(ellipseRect,true);}}3、鼠标移动时的响应函数void CMyView::OnMouseMove(UINT nFlags, CPoint point){CScrollView::OnMouseMove(nFlags, point);//对鼠标移动时的相应if (m_bCaptured){//画出相应的矩形裁减边框CDC *dc=GetDC();CRect rect(TopLeft,BottomRight);dc->SelectStockObject(WHITE_PEN);dc->Rectangle(rect);//用白色擦除原先的矩形边框InvalidateRect(rect,false);BottomRight=point;CRect newrect(TopLeft,BottomRight);CPen pen;pen.CreatePen(PS_DOT,1,RGB(0,0,0));dc->SelectObject(pen);dc->Rectangle(newrect);//用虚线画出新的矩形边框 }}void CMyView::OnLButtonUp(UINT nFlags, CPoint point) {CScrollView::OnLButtonUp(nFlags, point);//对鼠标放开左键的响应if (m_bCaptured){::ReleaseCapture();m_bCaptured = false;m_bDefineRect = false;}}void CMyView::OnViewDefineRect(){//设置是否自定义裁减区域m_bDefineRect = true;}void CMyView::OnEditDefinePoint(){//设置是否自定义点的坐标m_bDefinePointV = true;}4、放开鼠标右键的响应void CMyView::OnRButtonUp(UINT nFlags, CPoint point) {////对鼠标放开右键的相应CScrollView::OnRButtonUp(nFlags, point);if(m_bDefinePointV){CMyDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);pDoc->m_grahics.PointCount=PointArray.GetSize();if(pDoc->m_grahics.Point)delete pDoc->m_grahics.Point;pDoc->m_grahics.Point = new CPoint[pDoc->m_grahics.PointCount];for(int i=0;i<pDoc->m_grahics.PointCount;i++)pDoc->m_grahics.Point[i]=PointArray.GetAt(i);//对Point点坐标重新赋值PointArray.RemoveAll();m_bDefinePointV=false;CRect rect;this->GetClientRect(rect);InvalidateRect(rect);//获取新的初始裁减矩形范围int minX = pDoc->m_grahics.Point[0].x , minY = pDoc->m_grahics.Point[0].y;int maxX = pDoc->m_grahics.Point[0].x , maxY = pDoc->m_grahics.Point[0].y;for(i=1;i<pDoc->m_grahics.PointCount;i++){if(minX > pDoc->m_grahics.Point[i].x)minX = pDoc->m_grahics.Point[i].x;if(minY > pDoc->m_grahics.Point[i].y)minY = pDoc->m_grahics.Point[i].y;if(maxX < pDoc->m_grahics.Point[i].x)maxX = pDoc->m_grahics.Point[i].x;if(maxY < pDoc->m_grahics.Point[i].y)maxY = pDoc->m_grahics.Point[i].y;}TopLeft = CPoint(minX,minY);BottomRight = CPoint(maxX,maxY);}}5、初始化函数void CMyView::OnInitialUpdate(){CScrollView::OnInitialUpdate();CSize sizeTotal;sizeTotal.cx = sizeTotal.cy = 100;SetScrollSizes(MM_TEXT, sizeTotal);CMyDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);//设置初始的裁减区域int minX = pDoc->m_grahics.Point[0].x , minY = pDoc->m_grahics.Point[0].y;int maxX = pDoc->m_grahics.Point[0].x , maxY = pDoc->m_grahics.Point[0].y;for(int i=1;i<pDoc->m_grahics.PointCount;i++){if(minX > pDoc->m_grahics.Point[i].x)minX = pDoc->m_grahics.Point[i].x;if(minY > pDoc->m_grahics.Point[i].y)minY = pDoc->m_grahics.Point[i].y;if(maxX < pDoc->m_grahics.Point[i].x)maxX = pDoc->m_grahics.Point[i].x;if(maxY < pDoc->m_grahics.Point[i].y)maxY = pDoc->m_grahics.Point[i].y;}TopLeft = CPoint(minX,minY);BottomRight = CPoint(maxX,maxY);}6、重画窗口的函数,是MFC自动生成的,我们可以在里面添加自己的代码,用来实现消息映射表处理菜单、工具条、快捷键和其他用户消息。

相关主题