- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有一个多边形 C,如下所示:
C = 10 0
2 0
2 2
0 2
2 0
0 0
0 10
10 10
其中第一列表示 x 的坐标,第二列对应多边形 C 的 y 坐标。正如你在上图中看到的,这不是一个简单的多边形(这个多边形包含一个由白色指定的孔),所以我想从 C 中获取所有不包含孔的简单子(monad)多边形。在这种情况下,输出应如下所示:
C1 = 0 2
2 0
0 0
C2 = 2 0
2 2
0 2
0 10
10 10
10 0
其中C1和C2分别对应红色小三角和红色大多边形。
问题是如何生成这个子多边形?
任何想法将不胜感激。
最佳答案
首先我们可以假设所有交点都存在吗?很容易想出以有趣的方式与自身相交的多边形。但是使用类似 http://en.wikipedia.org/wiki/Bentley%E2%80%93Ottmann_algorithm 的东西您应该能够找到并添加所有交叉路口。
接下来我将做一个简化的假设,即我们永远不会反向遍历线段。 (您可以通过多种方式处理该病态病例。)
处理完这些细节后,接下来我们需要定位所有可以由这些点定义的最小多边形,无论它们最终是否被算作内部或外部。 (为方便起见,我们将在无穷远处添加一个“点”,并将外部视为多边形。)为此,我们首先获取每个点,并按逆时针顺序列出它直接连接的点。 (平行于 x 轴的方向是 0 度,与 y 轴的方向是 90 度,x 轴的负方向是 180 度,然后当你向下走得更远时我们环绕。)所以对于你的例子,我们会得到一些东西像这样:
( 0, 0): ( 2, 0), ( 0, 2)
( 2, 0): (10, 0), ( 2, 2), ( 0, 2), ( 0, 0)
(10, 0): (10,10), ( 2, 0)
( 0, 2): ( 0, 0), ( 2, 0), ( 2, 2), ( 0,10)
( 2, 2): ( 2, 0), ( 0, 2)
( 0, 10): ( 0, 2), (10,10)
(10, 10): (10, 0), ( 0,10)
现在每个简单的多边形都将击中其中两个点之间的每个点,反之亦然,我们可以取其中一个间隙(包括环绕)并在每个角轻松生成关联的多边形尽可能逆时针转动(即从我们到达的那一点到之后的那一点,可能是环绕)。对于每条线段,多边形将位于右侧。当我们拥有每一个点和差距时,我们知道我们拥有所有这些。因此,在上述情况下,我们将从 ( 0, 0)
和以下点 ( 2, 0)
开始,然后我们查看 ( 2, 0)
发现( 0, 0)
后面跟着(10, 0)
, 转到(10, 0)
并发现 ( 2, 0)
后面是 (10,10)
并以此方式进行追踪:
( 0, 0), ( 2, 0), (10, 0), (10,10), ( 0,10), ( 0, 2), ( 0, 0)
(请注意,由于方向的原因,这跟踪了外部区域。)
现在我们从 ( 0, 0)
和备用起点 ( 0, 2)
开始,做同样的操作得到:
( 0, 0), ( 0, 2), ( 2, 0), ( 0, 0)
(这是小内三角。)
对于( 2, 0)
,我们还没有到达( 2, 2)
。让我们开始吧。
( 2, 0), ( 2, 2), ( 0, 2), ( 0,10), (10,10), (10,0), ( 2, 0)
(这是大的不规则多边形。)
对于 ( 2, 0)
我们还没有到达 ( 0, 2)
所以让我们这样做:
( 2, 0), ( 0, 2), ( 2, 2), ( 2, 0)
(这是白色的小三角形。)
然后枚举我们可能想要经过的所有可能的有向线段,会发现我们已经涵盖了所有这些。所以这些是我们的多边形。现在我们要弄清楚里面是什么,外面是什么。有一个简单的技巧。找到一个 y 值可能最低的点(如果有平局,任何一个都可以)。例如,假设我们选择了 ( 2, 0)
。逆时针排列的连接点是(10, 0), ( 2, 2), ( 0, 2), ( 0, 0)
。它们分别是外部、内部、外部、内部……此外,一旦给定多边形的一条边被标记为外部或内部,其所有有向边都是相同的。因此我们很容易得到:
outside:
- (10, 0), ( 2, 2), ( 0, 2), ( 0, 0)
- ( 2, 0), ( 0, 2), ( 2, 2), ( 2, 0)
inside:
- ( 2, 0), ( 2, 2), ( 0, 2), ( 0,10), (10,10), (10, 0), ( 2, 0)
- ( 0, 0), ( 0, 2), ( 2, 0), ( 0, 0)
你的答案将只是内部多边形。
(小优化,我们根本不需要画外面的多边形。我们可以取第一条我们发现方向的线段,画出一条里面的线段,然后到它的一个角,确定方向接触那个角的线段,并开始绘制其他内部多边形。如果我们正确地跟踪,我们最终会得到它们。)
关于algorithm - 获取简单的多边形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10489829/
我正在努力实现以下目标, 假设我有字符串: ( z ) ( A ( z ) ( A ( z ) ( A ( z ) ( A ( z ) ( A ) ) ) ) ) 我想编写一个正则
给定: 1 2 3 4 5 6
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
大家好,我卡颂。 Svelte问世很久了,一直想写一篇好懂的原理分析文章,拖了这么久终于写了。 本文会围绕一张流程图和两个Demo讲解,正确的食用方式是用电脑打开本文,跟着流程图、Demo一
身份证为15位或者18位,15位的全为数字,18位的前17位为数字,最后一位为数字或者大写字母”X“。 与之匹配的正则表达式: ?
我们先来最简单的,网页的登录窗口; 不过开始之前,大家先下载jquery的插件 本人习惯用了vs2008来做网页了,先添加一个空白页 这是最简单的的做法。。。先在body里面插入 <
1、MySQL自带的压力测试工具 Mysqlslap mysqlslap是mysql自带的基准测试工具,该工具查询数据,语法简单,灵活容易使用.该工具可以模拟多个客户端同时并发的向服务器发出
前言 今天大姚给大家分享一款.NET开源(MIT License)、免费、简单、实用的数据库文档(字典)生成工具,该工具支持CHM、Word、Excel、PDF、Html、XML、Markdown等
Go语言语法类似于C语言,因此熟悉C语言及其派生语言( C++、 C#、Objective-C 等)的人都会迅速熟悉这门语言。 C语言的有些语法会让代码可读性降低甚至发生歧义。Go语言在C语言的
我正在使用快速将 mkv 转换为 mp4 ffmpeg 命令 ffmpeg -i test.mkv -vcodec copy -acodec copy new.mp4 但不适用于任何 mkv 文件,当
我想计算我的工作簿中的工作表数量,然后从总数中减去特定的工作表。我错过了什么?这给了我一个对象错误: wsCount = ThisWorkbook.Sheets.Count - ThisWorkboo
我有一个 perl 文件,用于查看文件夹中是否存在 ini。如果是,它会从中读取,如果不是,它会根据我为它制作的模板创建一个。 我在 ini 部分使用 Config::Simple。 我的问题是,如果
尝试让一个 ViewController 通过标准 Cocoa 通知与另一个 ViewController 进行通信。 编写了一个简单的测试用例。在我最初的 VC 中,我将以下内容添加到 viewDi
我正在绘制高程剖面图,显示沿路径的高程增益/损失,类似于下面的: Sample Elevation Profile with hand-placed labels http://img38.image
嗨,所以我需要做的是最终让 regStart 和 regPage 根据点击事件交替可见性,我不太担心编写 JavaScript 函数,但我根本无法让我的 regPage 首先隐藏。这是我的代码。请简单
我有一个非常简单的程序来测量一个函数花费了多少时间。 #include #include #include struct Foo { void addSample(uint64_t s)
我需要为 JavaScript 制作简单的 C# BitConverter。我做了一个简单的BitConverter class BitConverter{ constructor(){} GetBy
已关闭。这个问题是 not reproducible or was caused by typos 。目前不接受答案。 这个问题是由拼写错误或无法再重现的问题引起的。虽然类似的问题可能是 on-top
我是 Simple.Data 的新手。但我很难找到如何进行“分组依据”。 我想要的是非常基本的。 表格看起来像: +________+ | cards | +________+ | id |
我现在正在开发一个 JS UDF,它看起来遵循编码。 通常情况下,由于循环计数为 2,Alert Msg 会出现两次。我想要的是即使循环计数为 3,Alert Msg 也只会出现一次。任何想法都
我是一名优秀的程序员,十分优秀!