[OpenGL] 绘制并且判断凹凸多边形、自相交多边形。
#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] 绘制并且判断凹凸多边形、自相交多边形。的更多相关文章
- PHP 判断点是否在多边形内
如何判断一个点是否在一个多边形内,何时会用到这个场景. 我们就模拟一个真是场景.我们公司是快递公司,在本地区域有6个分点.每个分点有3-5个工人负责附近的快递派遣发送,所以根据每个点的服务区域我们就能 ...
- java/c# 判断点是否在多边形区域内
java/c# 判断点是否在多边形区域内 年06月29日 ⁄ 综合 ⁄ 共 1547字 ⁄ 字号 小 中 大 ⁄ 评论关闭 最近帮别人解决了一个问题,如何判断一个坐标点,是否在多边形区域内(二维). ...
- 百度地图 判断marker是否在多边形内
昨天画了圆形,判marker是否存在圆形内.今天来画多边形,判断marker在多边形内. 需要引入一个js <script type="text/javascript&quo ...
- hrbustoj 1429:凸多边形(计算几何,判断点是否在多边形内,二分法)
凸多边形 Time Limit: 2000 MS Memory Limit: 65536 K Total Submit: 130(24 users) Total Accepted: 40(1 ...
- C# 判断点是否在多边形内
/// <summary>/// 判断点是否在多边形内/// </summary>/// <param name="pnt">点</par ...
- PHP判断点是否在多边形区域内外
小谢博客原文地址https://xgs888.top/post/view?id=79 PHP判断点是否在多边形区域内外:根据数学知识的射线法, 射线与几何多边形相交的点的个数为奇数则是在几何内部: 偶 ...
- hrbustoj 1306:再遇攻击(计算几何,判断点是否在多边形内,水题)
再遇攻击 Time Limit: 1000 MS Memory Limit: 65536 K Total Submit: 253(37 users) Total Accepted: 56(2 ...
- zoj 1081:Points Within(计算几何,判断点是否在多边形内,经典题)
Points Within Time Limit: 2 Seconds Memory Limit: 65536 KB Statement of the Problem Several dra ...
- [zoj] 1081 Points Within || 判断点是否在多边形内
原题 多组数据. n为多边形顶点数,m为要判断的点数 按逆时针序给出多边形的点,判断点是否在多边形内,在的话输出"Within",否则输出"Outside" / ...
随机推荐
- CrashRpt_v.1.4.2_vs2008_also_ok
1.windows多线程程序release版崩溃记录工具,便于该如何查找错误. 2.此工具主要用来配置windbug工具,一种排查程序发布版本崩溃这种非常难处理的缺陷的方法,非常棒,amazing! ...
- Memcached在Linux系统下的安装和PHP开启 Memcached的 扩展 超级解决方案
[项目背景]:阿里云ECS服务器,Linux(centos7.2 64位),环境部署使用的是阿里云一键安装包(LAMP)等 [项目需求]:linux安装memcached 和php开启Memcache ...
- 30255Java_5.5 GUI
GUI GUI的各种元素(如:窗口,按钮,文本框等)由Java类来实现 1.AWT 使用AWT所涉及的类一般在java.awt包及其子包中 AWT(Abstract Window Toolkit)包括 ...
- C#最新功能(6.0、7.0)
一直用C#开发程序,.NET的功能越来越多,变化也挺大的,从最初的封闭,到现在的开源,功能不断的增加,一直在进步.作为C#的强烈支持者,C#的变化,我不能不关注,这篇文章主要介绍,C#6.0和C#7. ...
- 如何自学PHP做一个网站 PHP可以做什么项目?网站 小程序 公众号能用PHP开发吗?
很多想从事程序开发的人员,想自学一门语言,不知道从哪里下手学习,如何入门学习?今天我们就以PHP为例子,来讲述一下如何快速的学习一门开发语言,让你快速入门.PHP是一个什么语言?它能开发什么项目呢?下 ...
- 15 BOM的介绍
avaScript基础分为三个部分: ECMAScript:JavaScript的语法标准.包括变量.表达式.运算符.函数.if语句.for语句等. DOM:文档对象模型,操作网页上的元素的API.比 ...
- spring boot 2.x 系列 —— spring boot 整合 servlet 3.0
文章目录 一.说明 1.1 项目结构说明 1.2 项目依赖 二.采用spring 注册方式整合 servlet 2.1 新建过滤器.监听器和servlet 2.2 注册过滤器.监听器和servlet ...
- 【JAVA】POI生成EXCEL图表(柱状图、折线等)
1.使用excel工具自带的图形工具创建一个图: 2.绑定数据区域: 3.数据区域绑定完成,我们要做的就是将数据写入到数据区域中: 4.标记 5.POI 引入包 <!-- https://mvn ...
- JS中闭包的介绍
闭包的概念 闭包就是能够读取其他函数内部变量的函数. 一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascri ...
- spark入门(二)RDD基础操作
1 简述 spark中的RDD是一个分布式的元素集合. 在spark中,对数据的所有操作不外乎创建RDD,转化RDD以及调用RDD操作进行求值,而这些操作,spark会自动将RDD中的数据分发到集群上 ...