1、点在凸多边形内外的判定源程序忘记保存了随便找了个源程序反正老师不会看课 程 设 计 报 告课程名称 计算机图形学 课题名称 点在凸多边形内外的判定 专 业 计算机科学与技术 班 级 1202 学 号 姓 名 指导教师 刘长松 2015年 9 月 21 日湖南工程学院课 程 设 计 任 务 书课程名称 计算机图形学 课 题 点在凸多边形内外的判定 专业班级 计算机1202 学生姓名 学 号 指导老师 刘长松 审 批 任务书下达日期 2015年 9月 5 日任务完成日期 2015 年 9月 21 日一、设计内容与设计要求1设计内容:以图形学基本算法为目标,深入研究。继而策划、设计并实现一个能够判定
2、点在凸多边形内外的算法,并能从某些方面作出评价和改进意见。通过完成一个完整程序,经历策划、设计、开发、测试、总结和验收各阶段。2设计要求:(1)使用鼠标指定一组点来定义凸多边形;(2)使用鼠标指定测试点;(3)根据测试结果输出“在内部”或“在外部”。3.参考文献 1 王汝传.黄海平.计算机图形学教程M. 北京:人民邮电出版社,2009.2 孔令德. 计算机图形学教程M. 北京:清华大学出版社,2008.3 姜灵芝.C语言课程设计案例精编M.北京:清华大学出版社.2008.4 徐文鹏.计算机图形学.北京:机械工业出版社,2009.二、进度安排第 1 周 星期一 8:0012:00 星期三 8:0
3、012:00 星期五 8:0012:00 第 2 周 星期一 8:0012:00 星期三 8:0012:00 星期五 8:0012:00 附:课程设计报告装订顺序:封面、任务书、目录、正文、附件(A4大小的图纸及程序清单)、评分。 正文的格式:一级标题用3号黑体,二级标题用四号宋体加粗,正文用小四号宋体;行距为22。正文的内容:一、课题的主要功能;二、课题的功能模块的划分(要求画出模块图);三、主要功能的实现(至少要有一个主要模块的流程图);四、程序调试;五、总结;六、附件(所有程序的原代码,要求对程序写出必要的注释)。正文总字数要求在5000字以上(不含程序原代码)。目录一、设计需求分析 1
4、二、 总体设计 2三、 详细设计 3四、 调试 9五、心得体会 12参考文献 13附录 14一、设计需求分析该课题主要实现判断点与凸多边形的位置关系。其设计思想是应用图形学中的算法来实现该课题的功能。该课题还要实现通过鼠标画点绘制凸多边形和画点。查询网上资料得知该项目主要判定方法有射线法、面积法、交叉发、改进弧长法、角度矢量法等等,本次实验将会采用射线法来完成本次课题。本设计中主要用到有LineGL(Point pt0, Point pt1);PointGL(Point pt);glutInit(&argc,argv);glutInitDisplayMode(GLUT_RGB|GLUT_SIN
5、GLE);glutInitWindowPosition(a,a);glutInitWindowSize(600,800);glutDisplayFunc(myDisplay);glutReshapeFunc(Reshape);createGLUTMenus();GlutMouseFunc(mouse);glutMainLoop()等等。关于绘点和直线,opengl要求指定顶点的命令必须包含在glBegin函数之后,glEnd函数之前(否则指定的顶点将被忽略),并由glBegin来指明如何使用这些点。如果glBegin函数之后是gl_points生成顶点,是gl_lines则生成直线。创建生成点
6、和直线的方法,生成多边行时通过一个循环,调用生成点和直线的方法显示多边形。同时,多边形的绘制函数DrawPolygon()和判定点在其内的函数PtInPolygon()是实现本次算法的精要所在,通过射线法来判定点与多边形的位置关系,从点出发的射线与多边形的边相交,若交点的个数为奇数,则点在多边形内部;若交点为偶数,则点在多边形的外部。2、总体设计关于点在凸多边形内外判定的设计,首先要设计画点的算法以及直线的画法,从而利用点和直线的算法设计凸多边形的算法。最重要的是设计如何判定点在凸多边形内外。确定一个点与多边形的内部关系一般有两种方法:射线法和累计角度法。这里,我用的是射线法: (在代码中)以
7、point pt为起点,以无穷远为终点作平行于X轴的直线,循环取得多边形每一条边,且判断是否平行X轴,如果平行continue,否则i+; 同时判断点是否在边上,如果是,则返回1(点在多边形上),否则继续下面的判断; 判断边与线是否有交点,如果有则vp+,否则,i+。判断交点的总数,如果为奇数则返回0(点在多边形内),偶数则返回2(点在多边形外)。通过创建鼠标事件的方法,来进行画多边形和判断。其功能模块图如下:图 2.13、详细设计通过鼠标来绘制,绘制图形和点,并将在静态文本控件中绘制图形,所以,需要响应对话框的鼠标消息,并需要在静态文本的重绘函数OnPaint()中绘制图形和点。另外,需要从
8、静态文本控件CStatic类中,派生自己的静态文本控件类DrawMapStatic类。在DrawMapStatic类中,添加变量CArray m_pointArray和CPoint currpoint,分别用来存储凸多边形的顶点和绘制的点。其流程图如下: 图3.1通过点击鼠标左键确定图形绘制点,通过VC+里的工具类向导,将变量DrawMapStatic m_static与静态文本控件绑定。其关键代码如下: void CMyDlg:OnLButtonDown(UINT nFlags, CPoint point) LPRECT lpRect=new CRect(); m_static.GetWin
9、dowRect(lpRect); ScreenToClient(lpRect); if(point.xright & point.xlpRect-left & point.ybottom & point.ylpRect-top) CPoint pt; pt.x=point.x-lpRect-left; pt.y=point.y-lpRect-top; if(m_static.IsDrawMap) m_static.m_pointArray.Add(pt); m_static.currpoint=pt; if(m_static.IsDrawPie) m_static.Drawpoint=pt;
10、m_static.Invalidate();/使静态文本控件重绘 CDialog:OnLButtonDown(nFlags,point); 在静态文本控件中,绘图在OnPaint()函数中,其关键代码如下: void DrawMapStatic:OnPaint() CPaintDC dc(this);/获取绘图设备 int n=m_pointArray.GetSize();/获取当前图形顶点的个数 CPen pen(PS_SOLID,1,RGB(0,0,0);/创建画笔 dc.SelectObject(&pen);/将画笔选入绘图设备中 CBrush *pBrush=new CBrush(RG
11、B(0,0,0);/创建画刷 dc.SelectObject(pBrush);/将画刷选入图形设备中 if(n=4) CPoint pt=m_pointArray.GetAt(0); if(currpoint.xpt.x-5&currpoint.xpt.y-5&currpoint.ypt.y+5) m_pointArray.SetAt(n-1,m_pointArray.GetAt(0);/将图形最后的顶点设置为图形的第一个顶点值 IsDrawMap=FALSE;/设置不能再进行绘图 IsDrawed=TRUE;/设置绘图已经完成 /绘制图形 for(int i=0;in;i+) /绘制顶点,将
12、顶点绘制为以当前点为圆心,半径为3的填充的圆 CPoint point=m_pointArray.GetAt(i); dc.Ellipse(point.x-3,point.y-3,point.x+3,point.y+3); /绘制图形的边 if(i+1n) CPoint p=m_pointArray.GetAt(i+1); dc.MoveTo(point.x,point.y); dc.LineTo(p.x,p.y); /绘制点 if(IsDrawPie&Drawpoint.x!=0&Drawpoint.y!=0) dc.Ellipse(Drawpoint.x-3,Drawpoint.y-3,D
13、rawpoint.x+3,Drawpoint.y+3); 点与凸多边形的位置关系的判断将采用射线法。该算法的基本思想是由被测点向某个方向作射线,计算此射线与多边形所有边交点的个数。若交点个数为奇数,则被测点在多边形内,若交点个数为偶数,则被测点在多边形外部。在此判断算法中,将采用以被测点竖直向下的方向作射线。其算法关键代码如下: for(int j=0;jp1.y) mp=p1; p1=p2; p2=mp; /?被测点?,? if(m_static.Drawpoint.y=p1.y) /被测?端?,?x?端? /?mp?p1?p2?x? if(p1.xp2.x) mp.x=p1.x; mp.y
14、=p2.x; else mp.x=p2.x; mp.y=p1.x; if(m_static.Drawpoint.xmp.x) /若被测点的x值没有在p1.x和p2.x之间,则被测点与该边没有交点,反之,则有 continue; else count+; else CPoint pp1=p1,pp2=p2; /通过二分法将边取半分割,最终将边分割成一点:mp,且该点与被测点的y值相等。 do mp.x=(pp1.x+pp2.x)/2; mp.y=(pp1.y+pp2.y)/2; if(m_static.Drawpoint.ymp.y&m_static.Drawpoint.ypp1.y) pp2=
15、mp; else if(m_static.Drawpoint.ypp2.y) pp1=mp; else if(m_static.Drawpoint.y=mp.y) break; while(true); /假若被测点的x值范围在mp.x与p2.x之间,则被测点与该边有交点 if(m_static.Drawpoint.xmp.x&m_static.Drawpoint.xp2.x) |(m_static.Drawpoint.xp2.x) count+; /通过count的值打印判断结果 if(count%2) edit-SetWindowTextA(?); elseedit-SetWindowTe
16、xtA(?);4、调试4.1运行程序如图所示:图4.14.2 随机画点绘制如图:图4.2.1图4.2.2图4.2.34.3 画点判定图4.3.1图 4.3.2五、心得体会从一开始自己所拿到这个课题开始就一直在想怎么快速简洁的做出来,自己想到一个方案是在凸多边形内找一个点,然后与判定点相连,检测是否与凸多边形是否有交点。这个方案因为一开始判定随机点击所生成的点能否组成凸多边形的判定一直没做出来而放弃了,后来查询网上一些其他人的课程设计报告,发现了解决方法,然而出现了一个问题,别人的报告都是使用射线法,我将自己的方案代入后出现了大量错误,一个个解决后发现图形都无法显示,只好放弃自己的方案,转而运用
17、射线法。参考文献1 严蔚敏.吴伟民数据结构M 高等教育20042 钱能C+程序设计教程(M)(第二版)清华大学出版社20093 陆枫何云峰. 计算机图形学基础(第2 版)M. 电子工业出版社20124 张曦煌杜俊俐. 计算机图形学M.北京邮电大学出版社5 孙家广. 计算机图形学M.清华大学出版社.附录程序源代码如下/Resource.h资源文件#define IDM_ABOUTBOX 0x0010#define IDD_ABOUTBOX 100#define IDS_ABOUTBOX 101#define IDD_MY_DIALOG 102#define IDR_MAINFRAME 128#d
18、efine IDR_MENU 129#define IDC_RESULTEDIT 1006#define IDC_DRAWSTATIC 1012#define IDC_ADJUSTBUTTON 1013#define IDR_MENUMAP 32789#define IDR_MENUPIE 32790#ifdef APSTUDIO_INVOKED#ifndef APSTUDIO_READONLY_SYMBOLS#define _APS_NEXT_RESOURCE_VALUE 134#define _APS_NEXT_COMMAND_VALUE 32791#define _APS_NEXT_CO
19、NTROL_VALUE 1014#define _APS_NEXT_SYMED_VALUE 101#endif#endif/StdAfx.h文件#if !defined(AFX_STDAFX_H_9E57D590_031D_43D3_A71B_89A7753F3D3B_INCLUDED_)#define AFX_STDAFX_H_9E57D590_031D_43D3_A71B_89A7753F3D3B_INCLUDED_#if _MSC_VER 1000#pragma once#endif / _MSC_VER 1000#define VC_EXTRALEAN / Exclude rarely
20、-used stuff from Windows headers#include / MFC core and standard components #include / MFC extensions#include / MFC Automation classes#include / MFC support for Internet Explorer 4 Common Controls#ifndef _AFX_NO_AFXCMN_SUPPORT#include / MFC support for Windows Common Controls #endif / _AFX_NO_AFXCMN
21、_SUPPORT#endif/DrawMapStatic.h文件#if !defined(AFX_DRAWMAPSTATIC_H_B92D73CC_83F8_4755_B45A_7DB0F4512099_INCLUDED_)#define AFX_DRAWMAPSTATIC_H_B92D73CC_83F8_4755_B45A_7DB0F4512099_INCLUDED_#if _MSC_VER 1000#pragma once#endif/ DrawMapStatic.h : header file#include class DrawMapStatic : public CStaticpub
22、lic:DrawMapStatic();CArray m_pointArray;CPoint currpoint;CPoint Drawpoint;BOOL IsDrawMap;BOOL IsDrawPie;BOOL IsDrawed;public:virtual DrawMapStatic();protected:afx_msg void OnPaint();DECLARE_MESSAGE_MAP();#endif/DrawMapStatic.cpp文件#include stdafx.h#include 点在凸多边形内外的判定.h#include DrawMapStatic.h#ifdef
23、_DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE = _FILE_;#endifDrawMapStatic:DrawMapStatic()IsDrawMap=FALSE;IsDrawPie=FALSE;IsDrawed=FALSE;DrawMapStatic:DrawMapStatic()BEGIN_MESSAGE_MAP(DrawMapStatic, CStatic)ON_WM_PAINT()END_MESSAGE_MAP()/在静态文本控件中绘制图形void DrawMapStatic:OnPaint()CPa
24、intDC dc(this);int n=m_pointArray.GetSize();CPen pen(PS_SOLID,1,RGB(0,0,0);dc.SelectObject(&pen);CBrush *pBrush=new CBrush(RGB(0,0,0);dc.SelectObject(pBrush);if(n=4) CPoint pt=m_pointArray.GetAt(0); if(currpoint.xpt.x-10&currpoint.xpt.y-10&currpoint.ypt.y+10) m_pointArray.SetAt(n-1,m_pointArray.GetA
25、t(0); IsDrawMap=FALSE; IsDrawed=TRUE;for(int i=0;in;i+) CPoint point=m_pointArray.GetAt(i); dc.Ellipse(point.x-3,point.y-3,point.x+3,point.y+3); if(i+1 1000#pragma once#endif / _MSC_VER 1000#ifndef _AFXWIN_H_#error include stdafx.h before including this file for PCH#endif#include resource.h / main s
26、ymbols/ CMyApp:/ See 点在凸多边形内外的判定.cpp for the implementation of this class/class CMyApp : public CWinApppublic:CMyApp();/ Overrides/ ClassWizard generated virtual function overrides/AFX_VIRTUAL(CMyApp)public:virtual BOOL InitInstance();/AFX_VIRTUAL/ Implementation/AFX_MSG(CMyApp)/NOTE-theClassWizardwil;/DONOTEDITwhatyouse
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1