[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" / ...
随机推荐
- IIS6.0 WEB园配置
为应用程序池创建 Web 园请注意以下几点: 一.每一个工作进程都会消耗系统资源和CPU占用率:太多的工作进程会导致系统资源和CPU利用率的急剧消耗: 二.每一个工作进程都具有自己的状态数据,如果We ...
- Windows下OSGEarth的编译过程
目录 1. 依赖 1) OpenSceneGraph 2) GDAL 3) CURL 4) GEOS 5) 其他 2. 编译 1) 设置参数 2) 配置路径 3) 生成编译 3. 参考文献 1. 依赖 ...
- surging 微服务引擎 2.0 会有多少惊喜?
surging 微服务引擎从2017年6月至今已经有两年的时间,这两年时间有多家公司使用surging 服务引擎,并且有公司搭建了CI/CD,并且使用了k8s 集群,这里我可以说下几家公司的服务搭建情 ...
- spark 源码分析之五 -- Spark内置RPC机制剖析之一创建NettyRpcEnv
在前面源码剖析介绍中,spark 源码分析之二 -- SparkContext 的初始化过程 中的SparkEnv和 spark 源码分析之四 -- TaskScheduler的创建和启动过程 中的C ...
- django基础知识之自连接:
自连接 对于地区信息,属于一对多关系,使用一张表,存储所有的信息 类似的表结构还应用于分类信息,可以实现无限级分类 新建模型AreaInfo,生成迁移 class AreaInfo(models.Mo ...
- kuangbin专题 专题二 搜索进阶 哈密顿绕行世界问题 HDU - 2181
题目链接:https://vjudge.net/problem/HDU-2181 题意:一个规则的实心十二面体,它的 20个顶点标出世界著名的20个城市,你从一个城市出发经过每个城市刚好一次后回到出发 ...
- VM虚拟机 VMWare Workstation Pro v15.0.1 中文破解版
虚拟机软件VMware Workstation Pro 15.0 全新版本发布,此次更新了诸多客户机操作系统版本,另外完全兼容Win10创意者更新支持.12.0之后属于大型更新,专门为Win10的安装 ...
- 3. Django每日一码 之 Serializers 源码
2019-7-6 今日源码:rest-framework 序列化Serializers 序列化组件Serializers 源码分析 首先,它需要 data .many . instance,其中 in ...
- linux系统的基础优化
目录 前言 网络优化 在虚拟软件中配置虚拟局域网 接着可以配置自己windows主机的网络连接配置 在虚拟软件中虚拟机添加网卡 虚拟机中的系统基础优化 前言 在自己做linux的相关服务实验时,是没有 ...
- 微信小程序 键盘显示短信验证码
1.场景描述: IOS系统 一些APP或者微信小程序在收到短信验证码的时候会在键盘上自动保存验证码信息,当用户点击的时候,会自动赋值到当前所点击的输入框中 2.案例: 2.实现: TIPS:这个功能是 ...