#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. CrashRpt_v.1.4.2_vs2008_also_ok

    1.windows多线程程序release版崩溃记录工具,便于该如何查找错误. 2.此工具主要用来配置windbug工具,一种排查程序发布版本崩溃这种非常难处理的缺陷的方法,非常棒,amazing! ...

  2. Memcached在Linux系统下的安装和PHP开启 Memcached的 扩展 超级解决方案

    [项目背景]:阿里云ECS服务器,Linux(centos7.2 64位),环境部署使用的是阿里云一键安装包(LAMP)等 [项目需求]:linux安装memcached 和php开启Memcache ...

  3. 30255Java_5.5 GUI

    GUI GUI的各种元素(如:窗口,按钮,文本框等)由Java类来实现 1.AWT 使用AWT所涉及的类一般在java.awt包及其子包中 AWT(Abstract Window Toolkit)包括 ...

  4. C#最新功能(6.0、7.0)

    一直用C#开发程序,.NET的功能越来越多,变化也挺大的,从最初的封闭,到现在的开源,功能不断的增加,一直在进步.作为C#的强烈支持者,C#的变化,我不能不关注,这篇文章主要介绍,C#6.0和C#7. ...

  5. 如何自学PHP做一个网站 PHP可以做什么项目?网站 小程序 公众号能用PHP开发吗?

    很多想从事程序开发的人员,想自学一门语言,不知道从哪里下手学习,如何入门学习?今天我们就以PHP为例子,来讲述一下如何快速的学习一门开发语言,让你快速入门.PHP是一个什么语言?它能开发什么项目呢?下 ...

  6. 15 BOM的介绍

    avaScript基础分为三个部分: ECMAScript:JavaScript的语法标准.包括变量.表达式.运算符.函数.if语句.for语句等. DOM:文档对象模型,操作网页上的元素的API.比 ...

  7. spring boot 2.x 系列 —— spring boot 整合 servlet 3.0

    文章目录 一.说明 1.1 项目结构说明 1.2 项目依赖 二.采用spring 注册方式整合 servlet 2.1 新建过滤器.监听器和servlet 2.2 注册过滤器.监听器和servlet ...

  8. 【JAVA】POI生成EXCEL图表(柱状图、折线等)

    1.使用excel工具自带的图形工具创建一个图: 2.绑定数据区域: 3.数据区域绑定完成,我们要做的就是将数据写入到数据区域中: 4.标记 5.POI 引入包 <!-- https://mvn ...

  9. JS中闭包的介绍

    闭包的概念 闭包就是能够读取其他函数内部变量的函数. 一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascri ...

  10. spark入门(二)RDD基础操作

    1 简述 spark中的RDD是一个分布式的元素集合. 在spark中,对数据的所有操作不外乎创建RDD,转化RDD以及调用RDD操作进行求值,而这些操作,spark会自动将RDD中的数据分发到集群上 ...