#include <iostream>
#include <ctime>
#include <GL/glut.h>
#include <math.h>
#include <vector> using namespace std; struct Pos
{
int x;
int y;
}; struct Edge
{
int x1, x2;
int y1, y2;
int vx;
int vy;
int a, b, c;
}; struct Poly
{
// 点集
int xx[100];
int yy[100]; // 边集
Edge Edges[100]; int plotNums = 0; //点数量
int edgeNums = 0; //边数量 // 记录凹点
int conv = 0;
}; Poly poly; // 求交点坐标
Pos CrossPos(int p1,int p2){
Pos res;
int A1 = poly.Edges[p1].a;
int B1 = poly.Edges[p1].b;
int A2 = poly.Edges[p2].a;
int B2 = poly.Edges[p2].b;
int C1 = poly.Edges[p1].c;
int C2 = poly.Edges[p2].c; int m = A1 * B2 - A2 * B1;
if (m == 0)
cout <<"第"<<p1<<"边和第"<<p2<<"边"<< "无交点" << endl;
else
{
res.x = (C2*B1 - C1 * B2) / m;
res.y = (C1*A2 - C2 * A1) / m;
}
return res; } // 判断点是否在线段内
bool JudgeInLine(Pos pos,Edge edge)
{
int maxX = edge.x1 >= edge.x2 ? edge.x1 : edge.x2;
int minX = edge.x1 <= edge.x2 ? edge.x1 : edge.x2;
int maxY = edge.y1 >= edge.y2 ? edge.y1 : edge.y2;
int minY = edge.y1 <= edge.y2 ? edge.y1 : edge.y2;
if (pos.x<=maxX && pos.x>=minX && pos.y<=maxY && pos.y>=minY)
{
return true;
}
return false;
} // 求叉积 返回正负值
int CrossProduct(int n)
{
n = n % poly.edgeNums;
int np = (n + 1) % poly.edgeNums;
return (poly.Edges[n].vx*poly.Edges[np].vy - poly.Edges[np].vx*poly.Edges[n].vy) >= 0 ? 1 : -1;
} // 切割凹多边形
void ChangePoly() {
int convP = poly.conv; //凹点的下一个点
Pos interPos; for (int i = 0; i < poly.edgeNums; i++)
{
if (i<convP-1 || i>convP+1)
{
interPos = CrossPos(convP, i);
}
} glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POLYGON);
glColor3f(1.0f, 0.0f, 0.0f);
for (int i = 0; i <= convP; i++)
{
glVertex2f(poly.xx[i], poly.yy[i]);
}
glVertex2f(interPos.x, interPos.y);
glEnd(); glBegin(GL_POLYGON);
glColor3f(0.0f, 1.0f, 1.0f);
glVertex2f(interPos.x, interPos.y);
for (int i=convP+1;i<poly.plotNums;i++)
{
glVertex2f(poly.xx[i], poly.yy[i]);
}
glEnd(); glFlush();
} // 判断是什么多边形
bool Judge()
{
/*输出边信息*/
for (int i = 0; i < poly.edgeNums; i++)
{
cout << "Vx:" << poly.Edges[i].vx << " " << "Vy:" << poly.Edges[i].vy << " " << "A:" << poly.Edges[i].a<< " " << "B:" << poly.Edges[i].b << " " << "C:" << poly.Edges[i].c <<endl;
} /*判断自交*/
Pos interPos;
if (poly.edgeNums > 3)
for (int i = 0; i < poly.edgeNums; i++)
{
interPos = CrossPos(i, (i + 2) % poly.edgeNums);
if (JudgeInLine(interPos, poly.Edges[i]) && JudgeInLine(interPos, poly.Edges[(i + 2) % poly.edgeNums]))
{
cout << "该多边形为自相交多边形" << endl;
return false;
}
} /*判断凹凸*/
// 判断向量叉积 是否为同一正负
int judge;
if (CrossProduct(0) >= 0)
judge = 1;
else
judge = -1;
//判断每一个角,两边向量乘积是否同符号
for (int i = 1; i <= poly.edgeNums; i++)
{
if (judge*CrossProduct(i) < 0)
{
poly.conv = i;
ChangePoly();
cout << "该多边形为凹多边形" << endl;
return false;
}
}
cout << "该多边形为凸多边形" << endl;
return true;
} void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0); glMatrixMode(GL_PROJECTION);//设置投影矩阵
gluOrtho2D(0.0, 400.0, 0.0, 300.0);//二维视景区域 glColor3f(1.0, 0.0, 0.0);
glPointSize(3.0);//点的大小
} void plotpoint(GLint x, GLint y)
{
glBegin(GL_POINTS);
glVertex2i(x, y);
glEnd();
} void displayFcn(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
for (int i = 0; i < poly.plotNums; i++)
{
plotpoint(poly.xx[i], poly.yy[i]);
}
glBegin(GL_POLYGON);
for (int i = 0; i < poly.edgeNums; i++)
{
glVertex2f(poly.xx[i], poly.yy[i]);
}
glEnd(); glFlush();
} void mouse(GLint button, GLint action, GLint x, GLint y)
{
if (button == GLUT_LEFT_BUTTON && action == GLUT_DOWN)
{
poly.xx[poly.plotNums] = x;
poly.yy[poly.plotNums] = 300 - y;
cout << "x:" << x << " " << "y:" << 300 - y << endl;
poly.plotNums++;
glutPostRedisplay();//重绘窗口
}
if (button == GLUT_RIGHT_BUTTON && action == GLUT_DOWN)
{
poly.edgeNums = poly.plotNums;
if (poly.plotNums > 2)
{
for (int i = 1; i <= poly.plotNums; i++)
{
poly.Edges[i - 1].x1 = poly.xx[i - 1];
poly.Edges[i - 1].y1 = poly.yy[i - 1];
poly.Edges[i - 1].x2 = poly.xx[i%poly.plotNums];
poly.Edges[i - 1].y2 = poly.yy[i%poly.plotNums];
poly.Edges[i - 1].vx = poly.Edges[i - 1].x2 - poly.Edges[i - 1].x1;
poly.Edges[i - 1].vy = poly.Edges[i - 1].y2 - poly.Edges[i - 1].y1;
poly.Edges[i - 1].a = poly.Edges[i - 1].vy;
poly.Edges[i - 1].b = -poly.Edges[i - 1].vx;
poly.Edges[i - 1].c = poly.Edges[i - 1].x2 * poly.Edges[i - 1].y1 - poly.Edges[i - 1].x1 * poly.Edges[i - 1].y2;
}
if (Judge())
glutPostRedisplay();//重绘窗口
}
}
} int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(50, 100);
glutInitWindowSize(400, 300);
glutCreateWindow("mouse"); init();
glutDisplayFunc(displayFcn); glutMouseFunc(mouse); glutMainLoop(); }

[OpenGL] 绘制并且判断凹凸多边形、自相交多边形。的更多相关文章

  1. PHP 判断点是否在多边形内

    如何判断一个点是否在一个多边形内,何时会用到这个场景. 我们就模拟一个真是场景.我们公司是快递公司,在本地区域有6个分点.每个分点有3-5个工人负责附近的快递派遣发送,所以根据每个点的服务区域我们就能 ...

  2. java/c# 判断点是否在多边形区域内

    java/c# 判断点是否在多边形区域内 年06月29日 ⁄ 综合 ⁄ 共 1547字 ⁄ 字号 小 中 大 ⁄ 评论关闭 最近帮别人解决了一个问题,如何判断一个坐标点,是否在多边形区域内(二维). ...

  3. 百度地图 判断marker是否在多边形内

    昨天画了圆形,判marker是否存在圆形内.今天来画多边形,判断marker在多边形内. 需要引入一个js      <script type="text/javascript&quo ...

  4. hrbustoj 1429:凸多边形(计算几何,判断点是否在多边形内,二分法)

    凸多边形 Time Limit: 2000 MS    Memory Limit: 65536 K Total Submit: 130(24 users)   Total Accepted: 40(1 ...

  5. C# 判断点是否在多边形内

    /// <summary>/// 判断点是否在多边形内/// </summary>/// <param name="pnt">点</par ...

  6. PHP判断点是否在多边形区域内外

    小谢博客原文地址https://xgs888.top/post/view?id=79 PHP判断点是否在多边形区域内外:根据数学知识的射线法, 射线与几何多边形相交的点的个数为奇数则是在几何内部: 偶 ...

  7. hrbustoj 1306:再遇攻击(计算几何,判断点是否在多边形内,水题)

    再遇攻击 Time Limit: 1000 MS    Memory Limit: 65536 K Total Submit: 253(37 users)   Total Accepted: 56(2 ...

  8. zoj 1081:Points Within(计算几何,判断点是否在多边形内,经典题)

    Points Within Time Limit: 2 Seconds      Memory Limit: 65536 KB Statement of the Problem Several dra ...

  9. [zoj] 1081 Points Within || 判断点是否在多边形内

    原题 多组数据. n为多边形顶点数,m为要判断的点数 按逆时针序给出多边形的点,判断点是否在多边形内,在的话输出"Within",否则输出"Outside" / ...

随机推荐

  1. LFTP 4.6.2 发布,命令行 FTP 工具。这个东东可以用来做插件

    直击现场  这个东东可以用来做插件 LFTP 4.6.2 发布,新增特征如下: * new command "edit" instead of the edit alias.* n ...

  2. Linux 桌面玩家指南:20. 把 Linux 系统装入 U 盘打包带走

    特别说明:要在我的随笔后写评论的小伙伴们请注意了,我的博客开启了 MathJax 数学公式支持,MathJax 使用$标记数学公式的开始和结束.如果某条评论中出现了两个$,MathJax 会将两个$之 ...

  3. Delphi开发 Android 程序启动画面简单完美解决方案

    原文在这里 还是这个方法好用,简单!加上牧马人做的自动生成工具,更是简单. 以下为原文,向波哥敬礼! 前面和音儿一起研究 Android 下启动画面的问题,虽然问题得到了解决,但是,总是感觉太麻烦,主 ...

  4. FMX中实现PostMessage的方法

    首先,做为一个从Windows下转过来的开发人员,许多时候,我们喜欢用PostMessage来触发一些异步执行的代码,但遗憾的是,FMX做为EMB的跨平台库的基础,只提供了SendMessage方法, ...

  5. 京东sdk商家上架接口调用问题总结

    前言: 最近在做商家发布产品,调用京东sdk,发现问题很多,而且还是在我同事的帮助下完成的,摸索中,菜鸟还请高手门多多提携才好,入正题 首先是引用jd的sdk啦,京东sdk中发布商品需要调用一个 36 ...

  6. 《SpringMVC从入门到放肆》十五、SpringMVC之上传文件

    上一篇我们学习了数据分组校验,已经可以灵活的在项目中进行数据校验了,今天来学习SpringMVC的上传文件功能.相对来说SpringMVC的上传功能,还是比较简单的. 一.添加依赖 <depen ...

  7. 系列教程 之 Android开发之旅

    工作室持续推出Android开发系列教程与案例,供广大朋友分享交流技术经验,帮助喜欢Android的朋友们学习进步: 1. Android开发之旅(1) 之 Android 开发环境搭建 代码之间工作 ...

  8. 读书笔记——《谁说菜鸟不会数据分析—Python篇》

    最近刚读完一本新书,关注的公众号作者出的“谁说菜鸟不会数据分析—Python篇”,话说现在很多微信公众号大牛都在出书,这貌似是一个趋势.. 说说这本书吧,我之前看过一些网文,对于数据分析这一块也有过一 ...

  9. Storm —— 单机环境搭建

    1. 安装环境要求 you need to install Storm's dependencies on Nimbus and the worker machines. These are: Jav ...

  10. spring 5.x 系列第9篇 —— 整合mongodb (xml配置方式)

    源码Gitub地址:https://github.com/heibaiying/spring-samples-for-all 一.说明 1.1 项目结构说明 配置文件位于resources下,项目以单 ...