本节主要讲解了如何将二维多边形划分为多个不相交的三角形。
考虑如下场景,在一个尺寸为多边形的画廊中放置摄像头(哨兵),需要放几个才能完全覆盖该场景?可以看到下图至少需要两个哨兵。

如下图,若多边形是凸多边形或星形多边形,那么只须在中间的核位置放一个即可,此情况为该问题的最小解(下界):

若多边形不规则,那么最多n个点,即n多边形的每个顶点都设置一个哨兵,就可以将整个多边形覆盖,因此问题的最大解(上界)为n。

实际上,对于n个顶点的不规则多边形而言,最多只须n/3个点即可覆盖,如下图红点所示:

因为场景不同导致的情况不同,在数学上有证明指出画廊问题是NP-Hard问题,就是非确定性多项式困难问题

回到正题,多边形P的最大的连续对角线的集合称为P的三角剖分。Fisk指出,对任意一条边和内对角线连接的两个点着色,他们的颜色都是互异的,故进行三角剖分后的多边形,只需3种颜色即可对它完成着色。

证明: 首先构造三角剖分图的对偶图。
对第一个点所在的那个三角形使用三种颜色进行着色,然后从这个点移至下一个点时,我们知道这两个三角形是存在一条公共边,必有第三个顶点之间是不相连的,因此它们可以是同一种颜色。遍历这棵树,即可完成着色。
因为每个三角形的点颜色不一,对于一种颜色的点而言,它可以覆盖它所在的三角形,而多边形又是被剖分成一个个三角形,因此只要在同一种颜色的点上设置监控即可覆盖整个多边形,因此至多需要n/3个监控就可以覆盖整个多边形。

对于这n/3还可以有进一步的优化:
由鸽巢原理知,对于三种颜色的点总共有n个,那么必存在一种颜色的点数是小于等于n/3的。我们只需要选取其中最小规模的那个颜色集合即可。
这里只考虑简单多边形(即相邻的边才有交点的多边形)以及中间带洞的简单多边形的三角剖分。


step1:首先根据Lowest-then-Leftmost原则找到第一个凸点,然后找到与它相邻的两个点I,K并把I,K连接起来
step2:如果△IJK是一个耳朵,那么IK是一条内对角线,可以切分出一个三角形,调整未被切分的点,继续运行
step3:如果IK不是内对角线(如下图),意味着多边形中间有空洞。假设M是离线IK最远的那个点,沿JM切分,回到第一步,可以看到无论是下面的哪种情况,都能使三角剖分继续下去

利用数学归纳法能证明“简单多边形总能进行三角剖分”:
- 递归基:最终变成一个三角形(无洞)
- 递归假设:每次都将多边形分割成更小的简单多边形


钟乳石点StalacTite和石笋StalagMite:多边形中分别向下和向上凸起的形状,一个多边形之所以不是单调的,是因为存在这两种点。那么剖分的话就是将这些点消除掉。



这里利用栈存储未处理的点
step1:首先初始化,顶点从高到低排序(假定了方向是纵向),因为已经是分成了两条有序链,那么只需要归并即可
step2:把第一个点压入栈中
step3:若扫描点c与栈内所有点处于同侧,且它与t点和s点形成的角是凹角,把c点压入栈中,继续往下扫描

step4:若点c与栈中所有点同侧,但是c与t和s形成的角是凸角。此时把c和次栈顶s相连,可以切除一个三角形。然后弹出栈顶t,持续判断此时的栈顶和次栈顶相连的角的情况,直到c与栈顶和次栈顶相连的角是凹角或者栈内的点数小于2。这个操作完成后将c点push进栈,继续向下扫描

step5:若点c与栈中所有点异侧,此时点c可以与每个栈中的点有一条内对角线,都可以切三角形。这时就将c与栈顶次栈顶的点构成的三角形切除同时将栈顶的点pop出来,持续这个过程直到栈中只剩下一个元素。然后将栈底pop出来,并把之前碰到的第一个栈顶元素t入栈,最后将点c入栈,继续向下扫描

这里是Ruby新手。完成一些练习后碰壁了。练习:计算一系列成绩的字母等级创建一个方法get_grade来接受测试分数数组。数组中的每个分数应介于0和100之间,其中100是最大分数。计算平均分并将字母等级作为字符串返回,即“A”、“B”、“C”、“D”、“E”或“F”。我一直返回错误:avg.rb:1:syntaxerror,unexpectedtLBRACK,expecting')'defget_grade([100,90,80])^avg.rb:1:syntaxerror,unexpected')',expecting$end这是我目前所拥有的。我想坚持使用下面的方法或.join,
点向量坐标矩阵的几何意义介绍旋转矩阵的几何含义之前,先介绍一下点向量坐标矩阵的几何含义点:在一维空间下就是一个标量,如同一条直线上,以任意某一个位置为0点,以一定的尺度间隔为1,2,3...,相反方向为-1,-2,-3...;如此就形成了一维坐标系,这时候任何一个点都可以用一个数值表示,如点p1=5,即即从原点出发沿着x轴正方向移动5个尺度;点p2=-3,负方向移动3个尺度; 在一维坐标系上过原点做垂直于一维坐标系的直线,则形成了二维坐标系,此时描述一个点需要两个数值来表示点p3=(3,2),即从原点出发沿着x轴正方向移动3个尺度,在此基础上沿着y轴正方向移动两个尺度的位置就是点p3。
项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
给定一个nxmbool数组:[[true,true,false],[false,true,true],[false,true,true]]有什么简单的方法可以返回“该列中有多少个true?”结果应该是[1,3,2] 最佳答案 使用转置得到一个数组,其中每个子数组代表一列,然后将每一列映射到其中的true数:arr.transpose.map{|subarr|subarr.count(true)}这是一个带有inject的版本,应该在1.8.6上运行,没有任何依赖:arr.transpose.map{|subarr|subarr.in
给定两个大小相等的数组,如何找到不考虑位置的匹配元素的数量?例如:[0,0,5]和[0,5,5]将返回2的匹配项,因为有一个0和一个5共同;[1,0,0,3]和[0,0,1,4]将返回3的匹配项,因为0有两场,1有一场;[1,2,2,3]和[1,2,3,4]将返回3的匹配项。我尝试了很多想法,但它们都变得相当粗糙和令人费解。我猜想有一些不错的Ruby习惯用法,或者可能是一个正则表达式,可以很好地回答这个解决方案。 最佳答案 您可以使用count完成它:a.count{|e|index=b.index(e)andb.delete_at
Ruby中如何“一般地”计算以下格式(有根、无根)的JSON对象的数量?一般来说,我的意思是元素可能不同(例如“标题”被称为其他东西)。没有根:{[{"title":"Post1","body":"Hello!"},{"title":"Post2","body":"Goodbye!"}]}根包裹:{"posts":[{"title":"Post1","body":"Hello!"},{"title":"Post2","body":"Goodbye!"}]} 最佳答案 首先,withoutroot代码不是有效的json格式。它将没有包
目标我正在尝试计算自给定日期以来周的距离,而无需跳过任何步骤。我更喜欢用普通的Ruby来做,但ActiveSupport无疑是一个可以接受的选择。我的代码我写了以下内容,这似乎可行,但对我来说似乎还有很长的路要走。require'date'DAYS_IN_WEEK=7.0defweeks_sincedate_stringdate=Date.parsedate_stringdays=Date.today-dateweeks=days/DAYS_IN_WEEKweeks.round2endweeks_since'2015-06-15'#=>32.57ActiveSupport的#weeks
技术选型1,前端小程序原生MINA框架cssJavaScriptWxml2,管理后台云开发Cms内容管理系统web网页3,数据后台小程序云开发云函数云开发数据库(基于MongoDB)云存储4,人脸识别算法基于百度智能云实现人脸识别一,用户端效果图预览老规矩我们先来看效果图,如果效果图符合你的需求,就继续往下看,如果不符合你的需求,可以跳过。1-1,登录注册页可以看到登录页有注册入口,注册页如下我们的注册,需要管理员审核,审核通过后才可以正常登录使用小程序1-2,个人中心页登录成功以后,我们会进入个人中心页我们在个人中心页可以注册人脸,因为我们做人脸识别签到,需要先注册人脸才可以进行人脸比对,进
如何计算两个字符串之间的字符交集?例如(假设我们有一个名为String.intersection的方法):"abc".intersection("ab")=2"hello".intersection("hallo")=4好的,男孩女孩们,感谢你们的大量反馈。更多示例:"aaa".intersection("a")=1"foo".intersection("bar")=0"abc".intersection("bc")=2"abc".intersection("ac")=2"abba".intersection("aa")=2一些补充说明:维基百科定义intersection如下:Int