点在凸多边形内外的判定源程序忘记保存了随便找了个源程序反正老师不会看.docx
《点在凸多边形内外的判定源程序忘记保存了随便找了个源程序反正老师不会看.docx》由会员分享,可在线阅读,更多相关《点在凸多边形内外的判定源程序忘记保存了随便找了个源程序反正老师不会看.docx(38页珍藏版)》请在冰豆网上搜索。
点在凸多边形内外的判定源程序忘记保存了随便找了个源程序反正老师不会看
课程设计报告
课程名称计算机图形学
课题名称点在凸多边形内外的判定
专业计算机科学与技术
班级1202
学号
姓名
指导教师刘长松
2015年9月21日
湖南工程学院
课程设计任务书
课程名称计算机图形学
课题点在凸多边形内外的判定
专业班级计算机1202
学生姓名
学号
指导老师刘长松
审批
任务书下达日期2015年9月5日
任务完成日期2015年9月21日
一、设计内容与设计要求
1.设计内容:
以图形学基本算法为目标,深入研究。
继而策划、设计并实现一个能够判定点在凸多边形内外的算法,并能从某些方面作出评价和改进意见。
通过完成一个完整程序,经历策划、设计、开发、测试、总结和验收各阶段。
2.设计要求:
(1)使用鼠标指定一组点来定义凸多边形;
(2)使用鼠标指定测试点;
(3)根据测试结果输出“在内部”或“在外部”。
3.参考文献
[1]王汝传.黄海平.计算机图形学教程[M].北京:
人民邮电出版社,2009.
[2]孔令德.计算机图形学教程[M].北京:
清华大学出版社,2008..
[3]姜灵芝.C语言课程设计案例精编[M].北京:
清华大学出版社.2008.
[4]徐文鹏.计算机图形学.北京:
机械工业出版社,2009.
二、进度安排
第1周星期一8:
00——12:
00
星期三8:
00——12:
00
星期五8:
00——12:
00
第2周星期一8:
00——12:
00
星期三8:
00——12:
00
星期五8:
00——12:
00
附:
课程设计报告装订顺序:
封面、任务书、目录、正文、附件(A4大小的图纸及程序清单)、评分。
正文的格式:
一级标题用3号黑体,二级标题用四号宋体加粗,正文用小四号宋体;行距为22。
正文的内容:
一、课题的主要功能;二、课题的功能模块的划分(要求画出模块图);三、主要功能的实现(至少要有一个主要模块的流程图);四、程序调试;五、总结;六、附件(所有程序的原代码,要求对程序写出必要的注释)。
正文总字数要求在5000字以上(不含程序原代码)。
目录
一、设计需求分析1
二、总体设计2
三、详细设计3
四、调试9
五、心得体会12
参考文献13
附录14
一、设计需求分析
该课题主要实现判断点与凸多边形的位置关系。
其设计思想是应用图形学中的算法来实现该课题的功能。
该课题还要实现通过鼠标画点绘制凸多边形和画点。
查询网上资料得知该项目主要判定方法有射线法、面积法、交叉发、改进弧长法、角度矢量法等等,本次实验将会采用射线法来完成本次课题。
本设计中主要用到有LineGL(Pointpt0,Pointpt1);PointGL(Pointpt);glutInit(&argc,argv);glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE);glutInitWindowPosition(a,a);glutInitWindowSize(600,800);glutDisplayFunc(myDisplay);glutReshapeFunc(Reshape);createGLUTMenus();GlutMouseFunc(mouse);glutMainLoop()等等。
关于绘点和直线,opengl要求指定顶点的命令必须包含在glBegin函数之后,glEnd函数之前(否则指定的顶点将被忽略),并由glBegin来指明如何使用这些点。
如果glBegin函数之后是gl_points生成顶点,是gl_lines则生成直线。
创建生成点和直线的方法,生成多边行时通过一个循环,调用生成点和直线的方法显示多边形。
同时,多边形的绘制函数DrawPolygon()和判定点在其内的函数PtInPolygon()是实现本次算法的精要所在,通过射线法来判定点与多边形的位置关系,从点出发的射线与多边形的边相交,若交点的个数为奇数,则点在多边形内部;若交点为偶数,则点在多边形的外部。
2、总体设计
关于点在凸多边形内外判定的设计,首先要设计画点的算法以及直线的画法,从而利用点和直线的算法设计凸多边形的算法。
最重要的是设计如何判定点在凸多边形内外。
确定一个点与多边形的内部关系一般有两种方法:
射线法和累计角度法。
这里,我用的是射线法:
(在代码中)以pointpt为起点,以无穷远为终点作平行于X轴的直线,循环取得多边形每一条边,且判断是否平行X轴,如果平行continue,否则i++;同时判断点是否在边上,如果是,则返回1(点在多边形上),否则继续下面的判断;判断边与线是否有交点,如果有则vp++,否则,i++。
判断交点的总数,如果为奇数则返回0(点在多边形内),偶数则返回2(点在多边形外)。
通过创建鼠标事件的方法,来进行画多边形和判断。
其功能模块图如下:
图2.1
3、详细设计
通过鼠标来绘制,绘制图形和点,并将在静态文本控件中绘制图形,所以,需要响应对话框的鼠标消息,并需要在静态文本的重绘函数OnPaint()中绘制图形和点。
另外,需要从静态文本控件CStatic类中,派生自己的静态文本控件类DrawMapStatic类。
在DrawMapStatic类中,添加变量CArraym_pointArray和CPointcurrpoint,分别用来存储凸多边形的顶点和绘制的点。
其流程图如下:
图3.1
通过点击鼠标左键确定图形绘制点,通过VC++里的工具类向导,将变量DrawMapStaticm_static与静态文本控件绑定。
其关键代码如下:
voidCMyDlg:
:
OnLButtonDown(UINTnFlags,CPointpoint)
{
LPRECTlpRect=newCRect();
m_static.GetWindowRect(lpRect);
ScreenToClient(lpRect);
if(point.xright&&point.x>lpRect->left&&
point.ybottom&&point.y>lpRect->top)
{
CPointpt;
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;
}
}
m_static.Invalidate();//使静态文本控件重绘
CDialog:
:
OnLButtonDown(nFlags,point);
}
在静态文本控件中,绘图在OnPaint()函数中,其关键代码如下:
voidDrawMapStatic:
:
OnPaint()
{
CPaintDCdc(this);//获取绘图设备
intn=m_pointArray.GetSize();//获取当前图形顶点的个数
CPenpen(PS_SOLID,1,RGB(0,0,0));//创建画笔
dc.SelectObject(&pen);//将画笔选入绘图设备中
CBrush*pBrush=newCBrush(RGB(0,0,0));//创建画刷
dc.SelectObject(pBrush);//将画刷选入图形设备中
if(n>=4)
{
CPointpt=m_pointArray.GetAt(0);
if(currpoint.x>pt.x-5&&currpoint.xcurrpoint.y>pt.y-5&&currpoint.y{
m_pointArray.SetAt(n-1,m_pointArray.GetAt(0));//将图形最后的顶点设置为图形的第一个顶点值
IsDrawMap=FALSE;//设置不能再进行绘图
IsDrawed=TRUE;//设置绘图已经完成
}
}
//绘制图形
for(inti=0;i{
//绘制顶点,将顶点绘制为以当前点为圆心,半径为3的填充的圆
CPointpoint=m_pointArray.GetAt(i);
dc.Ellipse(point.x-3,point.y-3,point.x+3,point.y+3);
//绘制图形的边
if(i+1{
CPointp=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,Drawpoint.x+3,Drawpoint.y+3);
}
点与凸多边形的位置关系的判断将采用射线法。
该算法的基本思想是由被测点向某个方向作射线,计算此射线与多边形所有边交点的个数。
若交点个数为奇数,则被测点在多边形内,若交点个数为偶数,则被测点在多边形外部。
在此判断算法中,将采用以被测点竖直向下的方向作射线。
其算法关键代码如下:
for(intj=0;j{
//获取当前边的两个端点
p1=m_static.m_pointArray.GetAt(j);
p2=m_static.m_pointArray.GetAt(j+1);
if(p2.y>p1.y)
{
mp=p1;
p1=p2;
p2=mp;
}
//?
?
被测点?
?
?
?
?
,?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
if(m_static.Drawpoint.y<=p2.y)
continue;
elseif(m_static.Drawpoint.y>=p1.y)
{//被测?
?
?
?
?
端?
?
?
?
?
?
?
?
?
x?
?
?
?
?
?
?
端?
?
?
//?
mp?
?
p1?
p2?
x?
?
if(p1.x>p2.x)
{
mp.x=p1.x;
mp.y=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
{
CPointpp1=p1,pp2=p2;
//通过二分法将边取半分割,最终将边分割成一点:
mp,且该点与被测点的y值相等。
do
{
mp.x=(pp1.x+pp2.x)/2;
mp.y=(pp1.y+pp2.y)/2;
if(m_static.Drawpoint.y>mp.y&&m_static.Drawpoint.y{
pp2=mp;
}
elseif(m_static.Drawpoint.ypp2.y)
{
pp1=mp;
}
elseif(m_static.Drawpoint.y==mp.y)
break;
}while(true);
//假若被测点的x值范围在mp.x与p2.x之间,则被测点与该边有交点
if((m_static.Drawpoint.x>mp.x&&m_static.Drawpoint.x||(m_static.Drawpoint.xp2.x))
count++;
}
}
//通过count的值打印判断结果
if(count%2)
edit->SetWindowTextA("?
?
?
?
?
?
?
?
");
else
edit->SetWindowTextA("?
?
?
?
?
?
?
?
");
4、调试
4.1运行程序如图所示:
图4.1
4.2随机画点绘制如图:
图4.2.1
图4.2.2
图4.2.3
4.3画点判定
图4.3.1
图4.3.2
五、心得体会
从一开始自己所拿到这个课题开始就一直在想怎么快速简洁的做出来,自己想到一个方案是在凸多边形内找一个点,然后与判定点相连,检测是否与凸多边形是否有交点。
这个方案因为一开始判定随机点击所生成的点能否组成凸多边形的判定一直没做出来而放弃了,后来查询网上一些其他人的课程设计报告,发现了解决方法,然而出现了一个问题,别人的报告都是使用射线法,我将自己的方案代入后出现了大量错误,一个个解决后发现图形都无法显示,只好放弃自己的方案,转而运用射线法。
参考文献
[1]严蔚敏.吴伟民数据结构[M]高等教育2004
[2]钱能C++程序设计教程(M)(第二版)清华大学出版社2009
[3]陆枫何云峰.计算机图形学基础(第2版)[M].电子工业出版社2012
[4]张曦煌杜俊俐.计算机图形学[M].北京邮电大学出版社
[5]孙家广.计算机图形学[M].清华大学出版社.
附录
程序源代码如下
//Resource.h资源文件
#defineIDM_ABOUTBOX0x0010
#defineIDD_ABOUTBOX100
#defineIDS_ABOUTBOX101
#defineIDD_MY_DIALOG102
#defineIDR_MAINFRAME128
#defineIDR_MENU129
#defineIDC_RESULTEDIT1006
#defineIDC_DRAWSTATIC1012
#defineIDC_ADJUSTBUTTON1013
#defineIDR_MENUMAP32789
#defineIDR_MENUPIE32790
#ifdefAPSTUDIO_INVOKED
#ifndefAPSTUDIO_READONLY_SYMBOLS
#define_APS_NEXT_RESOURCE_VALUE134
#define_APS_NEXT_COMMAND_VALUE32791
#define_APS_NEXT_CONTROL_VALUE1014
#define_APS_NEXT_SYMED_VALUE101
#endif
#endif
//StdAfx.h文件
#if!
defined(AFX_STDAFX_H__9E57D590_031D_43D3_A71B_89A7753F3D3B
__INCLUDED_)
#defineAFX_STDAFX_H__9E57D590_031D_43D3_A71B_89A7753F3D3B__INCLUDED_
#if_MSC_VER>1000
#pragmaonce
#endif//_MSC_VER>1000
#defineVC_EXTRALEAN//Excluderarely-usedstufffromWindowsheaders
#include//MFCcoreandstandardcomponents#include//MFCextensions
#include//MFCAutomationclasses
#include//MFCsupportforInternetExplorer4CommonControls
#ifndef_AFX_NO_AFXCMN_SUPPORT
#include//MFCsupportforWindowsCommonControls#endif//_AFX_NO_AFXCMN_SUPPORT
#endif
//DrawMapStatic.h文件
#if!
defined(AFX_DRAWMAPSTATIC_H__B92D73CC_83F8_4755_B45A_7DB0F4512099__INCLUDED_)
#defineAFX_DRAWMAPSTATIC_H__B92D73CC_83F8_4755_B45A_7DB0F4512099__INCLUDED_
#if_MSC_VER>1000
#pragmaonce
#endif
//DrawMapStatic.h:
headerfile
#include
classDrawMapStatic:
publicCStatic
{
public:
DrawMapStatic();
CArraym_pointArray;
CPointcurrpoint;
CPointDrawpoint;
BOOLIsDrawMap;
BOOLIsDrawPie;
BOOLIsDrawed;
public:
virtual~DrawMapStatic();
protected:
afx_msgvoidOnPaint();
DECLARE_MESSAGE_MAP()
};
#endif
//DrawMapStatic.cpp文件
#include"stdafx.h"
#include"点在凸多边形内外的判定¨.h"
#include"DrawMapStatic.h"
#ifdef_DEBUG
#definenewDEBUG_NEW
#undefTHIS_FILE
staticcharTHIS_FILE[]=__FILE__;
#endif
DrawMapStatic:
:
DrawMapStatic()
{
IsDrawMap=FALSE;
IsDrawPie=FALSE;
IsDrawed=FALSE;
}
DrawMapStatic:
:
~DrawMapStatic()
{
}
BEGIN_MESSAGE_MAP(DrawMapStatic,CStatic)
ON_WM_PAINT()
END_MESSAGE_MAP()
//在静态文本控件中绘制图形
voidDrawMapStatic:
:
OnPaint()
{
CPaintDCdc(this);
intn=m_pointArray.GetSize();
CPenpen(PS_SOLID,1,RGB(0,0,0));
dc.SelectObject(&pen);
CBrush*pBrush=newCBrush(RGB(0,0,0));
dc.SelectObject(pBrush);
if(n>=4)
{
CPointpt=m_pointArray.GetAt(0);
if(currpoint.x>pt.x-10&&currpoint.xpt.y-10&&currpoint.y{
m_pointArray.SetAt(n-1,m_pointArray.GetAt(0));
IsDrawMap=FALSE;
IsDrawed=TRUE;
}
}
for(inti=0;i{
CPointpoint=m_pointArray.GetAt(i);
dc.Ellipse(point.x-3,point.y-3,point.x+3,point.y+3);
if(i+1{
CPointp=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,Drawpoint.x+3,Drawpoint.y+3);}
//点在凸多边形内外的判定.h文件
#if!
defined(AFX__H__A8D120D2_3EA8_4F60_86A8_7D3D5C486AD7__INCLUDED_)
#defineAFX__H__A8D120D2_3EA8_4F60_86A8_7D3D5C486AD7__INCLUDED_
#if_MSC_VER>1000
#pragmaonce
#endif//_MSC_VER>1000
#ifndef__AFXWIN_H__
#errorinclude'stdafx.h'beforeincludingthisfileforPCH
#endif
#include"resource.h"//mainsymbols
//CMyApp:
//See点在凸多边形内外的判定.cppfortheimplementationofthisclass
//
classCMyApp:
publicCWinApp
{
public:
CMyApp();
//Overrides
//ClassWizardgeneratedvirtualfunctionoverrides
//{{AFX_VIRTUAL(CMyApp)
public:
virtualBOOLInitInstance();
//}}AFX_VIRTUAL
//Implementation
//{{AFX_MSG(CMyApp)
//NOTE-theClassWizardwil;//DONOTEDITwhatyouse