河南理工大学
计算机科学与技术学院
课程设计报告
200 8 — 200 9 学年第 2 学期
课程名称 计算机图形学课程设计
设计题目点在凸多边形内外的判定
学生姓名 刘晶晶
学
号 320809010409
专业班级 计算机科学与技术 08-4 班
指导教师 徐文鹏
2009 年 6 月 20 日
一、设计题目
点在凸多边形内外的判定
二、设计要求
(1)使用鼠标指定一组点来定义凸多边形;
(2)使用鼠标指定测试点;
(3)根据测试结果输出“在内部”或“在外部”;
三、设计目的
掌握点在凸多边形内外判定原理与方法
四、设计方案
关于绘点和直线,opengl 要求指定顶点的命令必须包含在 glBegin 函数之
后,glEnd 函数之前(否则指定的顶点将被忽略),并由 glBegin 来指明如何
使用这些点。如果 glBegin 函数之后是 gl_points 生成顶点,是 gl_lines 则
生成直线。创建生成点和直线的方法,生成多边行时通过一个循环,调用
生成点和直线的方法显示多边形。判断点是否在多边行内,用的是射线法
:(在代码中)以 point
循环取得多边形每一条边,且判断是否平行 X 轴,如果平行 continue,否则 i++;
同时判断点是否在边上,如果是,则返回 1(点在多边形上),否则继续下面的
判断; 判断边与线是否有交点,如果有则 vp++,否则,i++。判断交点的总数,
如果为奇数则返回 0(点在多边形内),偶数则返回 2(点在多边形外)。通过创
建鼠标事件的方法,来进行画多边形和判断。
pt 为起点,以无穷远为终点作平行于 X 轴的直线,
五.软件设计
(1) 程序流程图:
DrawPolygon 函数流程图
PtInPolygon 函数流程图
(2)源程序
#include
#include
#include
#define Draw_Polygon 1
#define Test_Point 2
#define PointI 3
#define VMAX 20
bool pInput=false,pointInput=false,tp=false;
/*Class Point
{
public:
int x,y;
}*/
int vp=0,high=0;
struct Point {
Point p;
int x, y;};
Point vPolygon[VMAX];//存放多边形顶点坐标
void LineGL(Point pt0, Point pt1)
{
glBegin (GL_LINES);
glColor3f (1.0f, 0.0f, 0.0f);
glColor3f (0.0f, 1.0f, 0.0f);
glEnd ();
}
void PointGL(Point pt)
{
glPointSize(2);
glBegin (GL_POINTS);
glColor3f (1.0f, 0.0f, 0.0f);
glEnd ();
}
void DrawPolygon()
{
for(int i=0;i= max(p1.y, p2.y) ) // 交点在 p1p2 延长线上
continue;
// 求交点的 X 坐标
double x = (double)(pt.y - p1.y) * (double)(p2.x - p1.x) / (double)(p2.y
- p1.y) + p1.x;
if ( x > pt.x )
vp++; // 只统计单边交点
}
// 单边交点为偶数,点在多边形之外
return (vp % 2 == 1);
}
void myDisplay()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f (1.0f, 0.0f, 0.0f);
DrawPolygon();
PointGL(p);
glFlush();
}
void Init()
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
}
void Reshape(int w, int h)
{
high=h;
glViewport(0, 0, (GLsizei) w,
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, (GLdouble) w, 0.0, (GLdouble) h);
(GLsizei) h);
}
void mouse(int button, int state, int x, int y)
{
switch (button)
{
case GLUT_LEFT_BUTTON:
if (state == GLUT_DOWN)
{
if (pInput == true)//输入多边形的顶点
{
vPolygon[vp].x = x;
vPolygon[vp].y = high - y;
vp++;
glutPostRedisplay();
}
if(pointInput==true)
{
p.x=x;
p.y=high-y;
glutPostRedisplay();
}
}
break;
default:
break;
}
}
void processMenuEvents(int option) //鼠标事件
{
switch (option) {
case Draw_Polygon:
pInput=true;tp=false;pointInput=false;vp=0;
glutPostRedisplay();
break;
case Test_Point:
tp=true;pointInput=false;pInput=false;
if(vp<3) {
printf("Please draw a polygon!\n");
}
else{
if(PtInPolygon(p))//调用 PtInPolygon()判断点是否在多边形内
printf("点在多边形中\n");
else printf("点不在多边形中\n");}
case PointI:
pointInput = true;tp=false;pInput=false;
break;
}
}
void createGLUTMenus()
{
int menu;
menu = glutCreateMenu(processMenuEvents);
glutAddMenuEntry("Draw Polygon",Draw_Polygon);
glutAddMenuEntry("Point",PointI);
glutAddMenuEntry("Test Point",Test_Point);
glutAttachMenu(GLUT_RIGHT_BUTTON);
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(100, 100);
glutInitWindowSize(640, 480);
glutCreateWindow("Point in polygon");
Init();
glutDisplayFunc(myDisplay);
glutReshapeFunc(Reshape);
createGLUTMenus();
glutMouseFunc(mouse);
glutMainLoop();
return 0;
}
(3)运行结果
六.总结分析
这次课程设计给了我深刻的体会,我的思想有了很大的转变。刚
开始选到这个题目时感到很难,不知道从何下手,没有认真思考,把
东西没学过当做不会做的借口。但随着提交报告时间一天一天逼近,
不能再抱有从网上下载点东西交上去的侥幸心理了,通过仔细分析题
目,和同学商讨发现并没有想象中的那么难,平时做的实验都有类似
的代码。这次课程设计培养了我独立思考和分析问题的能力,让我明
白了不能被困难吓倒,要有一定能做出来的自信心。感谢和我同题目
的同学给我的帮助,感谢徐老师在炎热的天气还跑去机房为我们指导,
没有你们,光凭自己恐怕现在这个程序还没调试出来。这就是这一个星期自己
做课程设计的感受!
参考文献
《计算机图形学》 矿业大学出版社 徐文鹏
《OPENGL 编程指南》 人民邮电出版社 Dave Shreiner