计算几何_多边形

判定凸多边形:顶点凹凸性法

    连续三个顶点p1,p2,p3。计算p1p2,p2p3的叉乘,阶乘大于0,则表示p3点在线段p1和p2的左侧,然后依次计算下一个前后所组成向量的阶乘,如果在计算时,出现负值,则此多边形是凹多边形,如果所有顶点计算完毕,其结果都大于0,则多边形是凸多边形。

判断点在凸多边形内外:

    ①:与判定凸多边形差不多,用判断点与多边形两顶点叉乘,都大于0,点在多边形内,小于0,点在多边形外。
    ②:水平/垂直交叉点数判别法(适用于任意多边形包括凹凸边形)
注意到如果从P作水平向左的射线的话,如果P在多边形内部,那么这条射线与多边形的交点必为奇数,如果P在多边形外部,则交点个数必为偶数(0也在内)。所以,我们可以顺序考虑多边形的每条边,求出交点的总个数。还有一些特殊情况要考虑。

判断线段在任意多边形内:

    (1)首先,要判断一条线段是否在多边形内,先要判断线段的两个端点是否在多边形内。如果两个端点不全在多边形内,那么,线段肯定是不在多边形内的。
    (2)其次,如果线段和多边形的某条边内交(两线段内交是指两线段相交且交点不在两线段的端点),则线段肯定不在多边形内。
    (3)如果多边形的某个顶点和线段相交,则必须判断两相交交点之间的线段是否包含于多边形内。

求多边形重心:

       以第一个顶点为基准,分别连接p[i],p[i+1],1<i<n。将多边形划分为若干个三角形,求出了每个三角形的重心,用叉积求三角形面积,对凸多边形和凹多边形都适用(因为值有正负);作为二维的多边形,把面积作为权值,分别乘以重心坐标的X和Y值;分别将求出的X, Y值的加权平均数除以总面积,即多边形面积的重心坐标。

具体代码实现:

#include <iostream>
#include <stdlib.h>
#include <math.h>
#define MAXN 1000
#define offset 10000
#define eps 1e-8
#define zero(x) (((x)>0?(x):-(x))<eps)
#define _sign(x) ((x)>eps?1:((x)<-eps?2:0))using namespace std ;struct point{double x,y;}p[MAXN];
struct line{point a,b;};double xmult(point p1,point p2,point p0)  //计算向量p1p2,p2p3的叉积
{return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}int is_convex(int n,point* p)  //判定凸多边形,顶点按顺时针或逆时针给出,允许相邻边共线
{int i,s[3]={1,1,1};for (i=0;i<n&&s[1]|s[2];i++)s[_sign(xmult(p[(i+1)%n],p[(i+2)%n],p[i]))]=0;return s[1]|s[2];
}
int is_convex_v2(int n,point* p)  //判定凸多边形,顶点按顺时针或逆时针给出,不允许相邻边共线
{int i,s[3]={1,1,1};for (i=0;i<n&&s[0]&&s[1]|s[2];i++)s[_sign(xmult(p[(i+1)%n],p[(i+2)%n],p[i]))]=0;return s[0]&&s[1]|s[2];
}int inside_convex(point q,int n,point* p)  //判点在凸多边形内或多边形边上,顶点按顺时针或逆时针给出
{int i,s[3]={1,1,1};for (i=0;i<n&&s[1]|s[2];i++)s[_sign(xmult(p[(i+1)%n],q,p[i]))]=0;return s[1]|s[2];
}
int inside_convex_v2(point q,int n,point* p)  //判点在凸多边形内,顶点按顺时针或逆时针给出,在多边形边上返回0
{int i,s[3]={1,1,1};for (i=0;i<n&&s[0]&&s[1]|s[2];i++)s[_sign(xmult(p[(i+1)%n],q,p[i]))]=0;return s[0]&&s[1]|s[2];
}int inside_polygon(point q,int n,point* p,int on_edge=2)  //判点在任意多边形内,顶点按顺时针或逆时针给出,on_edge表示点在多边形边上时的返回值,offset为多边形坐标上限
{point q2;int i=0,count;while (i<n)for (count=i=0,q2.x=rand()+offset,q2.y=rand()+offset;i<n;i++)//随机取一个足够远的点q,以p为起点q为终点做射线L,依次对多边形的每条边进行考察if( zero(xmult(q,p[i],p[(i+1)%n])) && (p[i].x-q.x)*(p[(i+1)%n].x-q.x)<eps && (p[i].y-q.y)*(p[(i+1)%n].y-q.y)<eps )return on_edge;//点p在边上,返回on_edgeelse if (zero(xmult(q,q2,p[i])))break;//点q在射线pq2上,停止本循环,另取q2else if(xmult(q,p[i],q2)*xmult(q,p[(i+1)%n],q2)<-eps&&xmult(p[i],q,p[(i+1)%n])*xmult(p[i],q2,p[(i+1)%n])<-eps)count++;return count&1;
}
inline int opposite_side(point p1,point p2,point l1,point l2)
{return xmult(l1,p1,l2)*xmult(l1,p2,l2)<-eps;
}
inline int dot_online_in(point p,point l1,point l2)
{return zero(xmult(p,l1,l2))&&(l1.x-p.x)*(l2.x-p.x)<eps&&(l1.y-p.y)*(l2.y-p.y)<eps;
}
int inside_polygon(point l1,point l2,int n,point* p)  //判线段在任意多边形内,顶点按顺时针或逆时针给出,与边界相交返回1
{point t[MAXN],tt;int i,j,k=0;if (!inside_polygon(l1,n,p)||!inside_polygon(l2,n,p))return 0;for (i=0;i<n;i++)if (opposite_side(l1,l2,p[i],p[(i+1)%n])&&opposite_side(p[i],p[(i+1)%n],l1,l2))return 0;else if (dot_online_in(l1,p[i],p[(i+1)%n]))t[k++]=l1;else if (dot_online_in(l2,p[i],p[(i+1)%n]))//线段的某个端点在S上t[k++]=l2;else if (dot_online_in(p[i],l1,l2))t[k++]=p[i];for (i=0;i<k;i++)for (j=i+1;j<k;j++){tt.x=(t[i].x+t[j].x)/2;tt.y=(t[i].y+t[j].y)/2;if (!inside_polygon(tt,n,p))return 0;}return 1;
}point intersection(line u,line v)  //求多边形重心
{point ret=u.a;double t=((u.a.x-v.a.x)*(v.a.y-v.b.y)-(u.a.y-v.a.y)*(v.a.x-v.b.x))/((u.a.x-u.b.x)*(v.a.y-v.b.y)-(u.a.y-u.b.y)*(v.a.x-v.b.x));ret.x+=(u.b.x-u.a.x)*t;ret.y+=(u.b.y-u.a.y)*t;return ret;
}
point barycenter(point a,point b,point c)
{line u,v;u.a.x=(a.x+b.x)/2;u.a.y=(a.y+b.y)/2;u.b=c;v.a.x=(a.x+c.x)/2;v.a.y=(a.y+c.y)/2;v.b=b;return intersection(u,v);
}
point barycenter(int n,point* p)
{point ret,t;double t1=0,t2;int i;ret.x=ret.y=0;for (i=1;i<n-1;i++)if (fabs(t2=xmult(p[0],p[i],p[i+1]))>eps){t=barycenter(p[0],p[i],p[i+1]);ret.x+=t.x*t2;ret.y+=t.y*t2;t1+=t2;}if (fabs(t1)>eps)ret.x/=t1,ret.y/=t1;return ret;
}int main()
{
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

转载于:https://www.cnblogs.com/wanglaoda/p/4937174.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/376230.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

wps完成率怎么设置_WPS表格中如何计算完成率?详细操作方法看这里!

平时我们在使用像WPS这样的办公软件时&#xff0c;我们经常会使用到其中的Excel表格软件&#xff0c;来完成日常工作当中所需要完成的各种数据的统计以及录入等工作。而在我们使用WPS表格来录入、修改或者是统计某一些数据时&#xff0c;我们往往会因为表格内容的设定需求&…

[原创]WebScarab工具介绍

[原创]WebScarab工具介绍 一 WebScarab介绍 WebScarab是一个用来分析使用HTTP和HTTPS协议的应用程序框架。其原理很简单&#xff0c;WebScarab可以记录它检测到的会话内容&#xff08;请求和应答&#xff09;&#xff0c;并允许使用者可以通过多种形式来查看记录。WebScarab的设…

段表的作用

表格来自《程序员的自我修养 ——链接、装载与库》 ELF段名作用.text代码段&#xff0c;存放执行语句.data数据段&#xff0c;存放初始化的全局变量和局部静态变量.bss未初始化的全局变量和局部静态变量.rodata只读数据段.comment注释信息段.note.GNU-stack堆栈提示段.debug调…

layoutSubviews总结

ios layout机制相关方法 - (CGSize)sizeThatFits:(CGSize)size- (void)sizeToFit——————- - (void)layoutSubviews- (void)layoutIfNeeded- (void)setNeedsLayout——————– - (void)setNeedsDisplay- (void)drawRectlayoutSubviews在下面情况下会被调用&#xff1a; …

三个彩灯循环点亮程序_近百组彩灯点亮江畔,义渡灯会正式亮灯啦

10月23日晚上&#xff0c;大渡口区义渡古镇华灯初上。夜幕之下&#xff0c;2020第一届义渡灯会亮灯仪式在此举行&#xff0c;来自四川的近百组彩灯将在这里点亮夜空&#xff0c;一直陪伴广大市民游客至明年元宵节后。当晚6点半&#xff0c;义渡灯会亮灯仪式正式开启。本次灯会以…

repeater序列号,换页数字不重新排

<td><%# Container.ItemIndex 1(Convert.ToInt32(this.drpCurrentPageIndex.SelectedValue)-1)*Convert.ToInt32(this.drpCount.SelectedValue)%></td>转载于:https://www.cnblogs.com/liziqiang/p/3457203.html

Altera的几个常用的Synthesis attributes(转载)

各厂商综合工具&#xff0c;对HDL综合时都定义了一些综合属性这些属性可指定a declaration,a module item,a statement, or a port connection 不同的综合方式。 语法为&#xff1a; /* synthesis, <any_company_specific_attribute value_or_optional_value */ 下面就是Al…

QPushButton hover配置

鼠标移动到QPushButton上面时显示下划线 //下面是当鼠标移动到按钮上时&#xff0c;按钮上的文字显示下划线 QPushButton#Button_2:hover{ text-decoration:underline; }//下面是普通显示 QPushButton#Button_2{ color:rgba(52, 144, 255 ,255); border-radius:0px; backgrou…

eclipse没有日志_强化公共DHT以抵抗eclipse攻击,ipfs官方还说了什么?

近日&#xff0c;IPFS官方发布博客&#xff0c;就如何强化公共DHT以抵抗eclipse攻击进行详细介绍&#xff0c;星球君帮大家翻译了一下&#xff0c;让我们来看看官方都说了什么吧&#xff1a;IPFS 2020 年的一个主要焦点是随着网络规模的不断扩大而改进内容路由。虽然我们已经对…

mongoDB简明教程-python(转)

MongoDB是一个介于关系数据库和非关系数据库之间的产品&#xff0c;是非关系数据库当中功能最丰富&#xff0c;最像关系数据库的。他支持的数据结构非常松散&#xff0c;是类似 json的bjson格式&#xff0c;因此可以存储比较复杂的数据类型。官方网站&#xff1a;http://www.mo…

HTTP基础10--web(2)

因输出值转义不完全引发的安全漏洞 实施 Web 应用的安全对策可大致分为以下两部分。 客户端的验证Web 应用端&#xff08;服务器端&#xff09;的验证: 输入值验证 / 输出值转义客户端允许篡改数据或关闭 JavaScript&#xff0c;不适合将 JavaScript 验证作为安全的防范对策。保…

单一课和综合课的划分依据_武夷岩茶产地如何划分?

产地是指某种物品的生产、出产或加工制造的地点&#xff0c;日常含义是指某种物品的主要生产地。本文探讨的武夷岩茶种植产地&#xff0c;也就是当地茶人俗称的“山场”。武夷岩茶“山场”的俗称可能缘起于宋代的茶政。宋代官府设置“榷&#xff08;qu&#xff09;茶场”&#…

windows文件路径大于MAX_PATH

如果文件路径大于MAX_PATH&#xff0c;是无法直接用CreatFile、fopen等方法来打开文件 但是可以通过在路径前面加上“\\?\”来获取文件 比如想要打开下面的文件123.txt&#xff0c;但是文件路径是很长的&#xff08;假设…是200个字符&#xff09;&#xff1a; C:\123...\1…

C# 枚举 字符串 转换

普通方法 这种方法尽管很SB但确实可以解决问题 private void comboBox1_SelectedIndexChanged(object sender, EventArgs e){string SelPath "";switch (comboBox1.SelectedIndex){case 0: SelPath System.Environment.GetFolderPath(System.Environment.SpecialFo…

arduino 机器视觉编程_万物皆可仿真的MATLAB/Simulink神奇在哪?解析如何将其应用于一整套机器人设计开发流程...

MATLAB/Simulink&#xff1a;万物皆可仿真 MATLAB是由美国MathWorks公司出品的一款商业数学软件。它是一个多功能的科学计算平台&#xff0c;将算法开发、数据分析、矩阵计算等诸多强大功能集成在一个易于操作的视窗环境中。MATLAB下的Simulink更是被认为可以“仿真任何系统”。…

排序算法(1) 快速排序 C++实现

快速排序基本特性 时间复杂度&#xff1a;O&#xff08;n*lgn&#xff09;最坏&#xff1a;O&#xff08;n^2&#xff09;空间复杂度&#xff1a;最好情况下&#xff1a;O&#xff08;lgn&#xff09;&#xff0c;最坏情况&#xff1a;O(n)&#xff0c;平均情况&#xff1a;O(l…

boost 变量类型转换

如果vs版本比较低&#xff0c;会不支持一些std类型转换函数&#xff08;vs2008就不支持&#xff09;&#xff0c;比如&#xff1a; std::to_string \\数字转字符串 std::stoll \\字符串转数字而且项目碰巧用boost库&#xff0c;可以考虑用下面的的方法来进行类型转换…

PB增删改

新建一个数据窗口----选择需要更新的表&#xff0c;或者直接写sql也可以如下图已经建立好的数据窗口&#xff0c;根据要求将需要更新的列、unigue key 还有需要更新的表设置好&#xff0c;【将需要更新列的taborder设置大于0 这样维护的时候可以编辑&#xff08;等于0是不能编辑…

(五十六)iOS多线程之NSOperation

NSOpertation是一套OC的API&#xff0c;是对GCD进行的Cocoa抽象。 NSOperation有两种不同类型的队列&#xff0c;主队列和自定义队列。 主队列运行于主线程上&#xff0c;自定义队列在后台运行。 【NSBlockOperation】 通过Block创建任务&#xff0c;下面比较主队列和自定义队列…

android 系统源码调试 局部变量值_如何方便快速的整编Android 9.0系统源码?

点击上方“刘望舒”&#xff0c;选择“星标”多点在看&#xff0c;就是真爱&#xff01;作者 : 刘望舒 | 来源 &#xff1a;刘望舒的博客地址&#xff1a;http://liuwangshu.cn/framework/aosp/3-compiling-aosp.html前言在上一篇文章是时候下载Android 9.0系统源码了中&…