课 程 设 计 报 告
计算机图形学
多边形裁剪与填充
计算机科学与技术
课程名称
课题名称
专
班
学
姓
业
级
号
名
指导教师
刘长松 曹 燚
年
月
日
湖南工程学院
课 程 设 计 任 务 书
课程名称
课
计算机图形学
题 多边形裁剪与填充
专业班级
学生姓名
学
号
指导老师
审
批
刘长松 曹 燚
任务书下达日期 年 月 日
任 务 完 成 日 期 年 月 日
一 、 设 计 内 容 与 设 计 要 求
1.设计内容:
交互式地实现多边形的裁剪和填充。。
2.设计要求:
1)窗口功能设计。
2)实现鼠标画多边形与数据存储功能。
3)实现鼠标剪裁窗口选择功能。
4)实现多边形裁剪和填充功能。
3.算法提示:
多边形裁剪算法分析:
基本思想是一次用窗口的一条边裁剪多边形,窗口的一条边以及延长线构成
裁剪线,该线把平面分成两个部分:可见一侧,不可见一侧。用一条裁剪边对
多边形进行裁剪,得到一个顶点序列,作为下一条裁剪边处理过程的输入点。
对于每一条裁剪边,只是判断点在窗口的哪一测以及求线段与裁剪边的交点
算法应随之改变。
多边形填充算法分析:
确定多边形所占有的最大扫描线数,得到多边形顶点的最小和最大 y 值(ymin
和 ymax),从 y=ymin 到 y=ymax, 每次用一条扫描进行填充。对一条扫描线填充的
过程可分为四个步骤: a.求交 b.排序 c.交点配对 d.区间填色。
二、进 度 安 排
第 3 周
第 4 周
星期一 8:00——12:00
星期二 8:00——12:00
星期三 8:00——12:00
星期四 8:00——12:00
星期五 8:00——12:00
星期一 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.
2.
3.
4.
5.
6.
nFlags,
CMyView::OnMouseMove(UINT
void CMyView::OnLButtonDown(UINT nFlags, CPoint point){}对鼠标按下
左键的响应,如果是自定义裁剪的区域操作就捕获鼠标按下的点,画裁剪区
域,如果是自定义点坐标的操作就捕获鼠标的点画多边形。
void
point){} 对
CPoint
鼠标 移动的响应。用捕获的点画出相应的矩形裁剪边框。画边框的时候,先
用白色擦出原先的矩形边框,再用虚线画出新的举行边框
void CMyView::OnRButtonUp(UINT nFlags, CPoint point){}对鼠标放开左
键的相应。如果是自定义点的坐标,就获取新的初始裁减矩形范围。
void CMyView::OnLButtonUp(UINT nFlags, CPoint point){}对鼠标放开左
键的响应
void CMyView::OnInitialUpdate(){}初始化裁剪区域和在窗口中画一个矩
形和一个五角星。
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
be dockable
// TODO: Delete these three lines if you don't want the toolbar to
//
m_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)
{
////对鼠标放开右键的相应