清华计算几何大作业(五):CG2017 PA3-2 Which wall are you looking at (你在看哪面墙)

本文围绕清华计算几何大作业CG2017 PA3 - 2展开,介绍Point Location算法用于点定位查询。重点讲解查询点落在梯形上的两种特殊“坑”:上线段非输入线段、上线段非离查询点最近。还给出处理方法,如标记输入线段编号、检查UpperRightNeighbour等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


招募告示:想做一个苏菲2炼金的网站,用于计算最优/次优合成图,涉及算法、Web开发、UI/UX等等,有兴趣请私我哒~

1. 前置知识

计算几何算法:Point Location,详见教材 6.1 点定位及梯形图( 6.1 Point Location and Trapezoidal Maps )

这里给到必要观看的视频课程章节,这些内容对理解和实现 Point Location 算法至关重要,标记有绿色√为必看章节:

在这里插入图片描述

2. 思路分析

问题描述:CG2017 PA3-2 Which wall are you looking at (你在看哪面墙)

这题解题思路就是用Point Location算法建立Trapezoidal Map和Search Structure,然后对每个Robot进行点定位查询,整体的思路没有什么太多难点。但因为Degenerate Case,某些情况下查询结果会有“坑”!本篇文章的重点就是来讲解一下这些“坑”。至于如何拆分和更新梯形结构,和如何处理Degenerate Case,大家可以参考之前的系列文章:

首先,为了避免查询点溢出的情况,我们需要将Bouding Box包含所有的输入线段和查询点。经过这样的处理,那么对于任意一次查询,查询结果只有以下三种:

  • 落在端点上;- Point
  • 落在线段上;- Segment
  • 落在梯形内部或左右边上; - Trapezoid

那这三种查询结果都会有“坑”嘛?答案是No哒,前两种是不会有问题的,因为只有当查询点刚好落在端点或线段上,才会被报告,这些是没有什么特殊情况的。但问题就出现在第三种:当查询点落在梯形上。根据笔者的观察总结,一共有两种特殊情况需要单独处理:

  • 查询结果梯形的上线段( top )不是输入线段,但是构成Bounding Box的边界线段;
  • 查询结果梯形的上线段( top )不是离查询点最近的;

这是什么意思呢?大家可以看看下面两个图例就明白啦:

在这里插入图片描述

左边的情况我们只需要检查梯形上线段是不是输入线段即可,第二种情况稍微复杂一些,造成这种情况的原因是为了处理Degenerate Case,我们进行“假想斜切”。接下来我们就来一个个情况进行处理,找出Robot真正面对的Wall!

对于第一类问题,有个比较直接的方法,我们直接标记输入线段是哪些就行了,但是这样实现起来太麻烦了,因为需要更改Point Location算法的数据结构,不太好,有没有一个不需要修改算法数据结构的方法呢?当然是有的呢,因为我们会在一开始对线段进行编号ID(后面输出也需要用到ID),那么我们只要设法让输入线段的ID从0开始,先对输入线段进行编号,假设有n条线段,我们只要输出 ID < n 的线段,其余线段均非法。

对于第二类问题,我们需要先思考这么一个问题:哪些情况下才会出现这种问题呢?同样根据笔者观察总结,得到了下面的结论:

出现第二类问题,当且仅当查询点刚好落在线段左端点所在的垂直线上,并且查询点必然在该线段的下方。

这是什么意思呢?我们通过下面的图例来进行说明:

在这里插入图片描述

大家可以看到,这种情况下,如果合法线段存在,并且我们假设查询得到的梯形是T,那么这条合法线段一定位于T的UpperRightNeighbor的下线段( Bottom ),所以每当遇到查询结果为梯形的时候,我们就需要检查UpperRightNeighbour是否有满足条件的线段(Wall)。那么是否还有其他情况也会出现这样的问题呢?答案是不会的,上图描绘的是左端点情况,如果查询点不再si的下方,而是上方,那合法线段一定位于si的上方,那么问题就转换到了si上方某个梯形的UpperRightNeighbor是否有满足条件的线段。

那如果查询点位于右端点呢?这种情况也是没有问题的,算法总会正确报告出正确的梯形,以及正确的合法线段:

在这里插入图片描述

最后需要提醒一下,在处理第二类问题的时候,需要特别注意一下垂直输入线段,在判断它是否为合法线段时候,需要特别注意它可能需要特殊处理,具体怎样处理大家可以参考笔者的代码,或者根据自己实现的思路进行相应处理即可,这里就不再赘述。到此,我们就讲解完了 PA3-2 所有需要注意的地方。

3. 伪代码

// 主算法
Algorithm TRAPEZOIDALMAP(S)
算法 TRAPEZOIDALMAP(S)
Input. A set S of n non-crossing line segments.
输入:一组共 n 条互不相交的线段
Output. The trapezoidal map T(S) and a search structure D for T(S) in a bounding box.
输出:梯形图 T(S),以及与之对应的、限制于一个包围框之内的查找结构 D
1. Determine a bounding box R that contains all segments of S, and initialize the trapezoidal map structure T and search structure D for it.
1. 构造一个包围框 R,其大小必须足以容纳 S 中的所有线段根据 R,初始化相应的梯形图结构 T 以及查找结构 D
2. Compute a random permutation s1,s2,...,sn of the elements of S.
2.S 中的所有线段随意打乱,得到一个随机序列:s1, s2,, sn
3. for i <- 1 to n
3. for i <- 1 to n
	4. do Find the set ∆0,1,...,∆k of trapezoids in T properly intersected by si.
	4. do在(当前的)T中,找到与si真相交的所有梯形Δ0, Δ1,, Δk
	5. Remove0,1,...,∆k from T and replace them by the new trapezoids that appear because of the insertion of si.
	5. 将Δ0, Δ1,, Δk从 T 中删去将它们替换为由于 si 的引入而新生出来的若干梯形
	6. Remove the leaves for0,1,...,∆k from D, and create leaves for the new trapezoids. Link the new leaves to the existing inner nodes by adding some new inner nodes, as explained below.
	6. 将与Δ0, Δ1,, Δk对应的叶子从 D 中删去对应于每个新生成的梯形,生成一匹新的叶子将新生出的叶子与已有的内部节点相联接(* 正如下面要介绍的,为此可能需要加入一些新的内部节点 *)
// 寻找待拆分的梯形
Algorithm FOLLOWSEGMENT(T,D,si)
算法 FOLLOWSEGMENT(T, D, si)
Input. A trapezoidal map T, a search structure D for T, and a new segment si.
输入:梯形图 T,与 T 相对应的查找结构 D,以及新近引入的一条线段 si
Output. The sequence ∆0,...,∆k of trapezoids intersected by si.
输出:由所有与 si 真相交的梯形(自左向右)组成的一个序列:Δ0,, Δk
1. Let p and q be the left and right endpoint of si.
1. 分别令 p 和 q 为 si 的左、右端点
2. Search with p in the search structure D to find0.
2. 在查找结构 D 中对 p 进行查找,最终找到梯形Δ0
3. j <- 0;
3. j <- 0;
4. while q lies to the right of rightp(∆j)
4. while (q 位于 rightp(Δj)的右侧)
	5. do if rightp(∆j) lies above si
	5. do if (rightp(Δj)位于 si 的上方)
		6. then Let ∆j+1 be the lower right neighbor of ∆j.
		6. then 令Δj+1为Δj的右下方邻居
		7. else Let ∆j+1 be the upper right neighbor of ∆j.
		7. else 令Δj+1为Δj的右上方邻居
		8. j <- j + 1
		8. j <- j + 1
9. return0,1,...,∆j
9. return (Δ0, Δ1,, Δj)

4. 可视化结果示例

在这里插入图片描述

5. 项目代码

个人作业项目代码:Algorithm

DescriptionEntry method\File
Build trapezoidal Map and search structureBoundingBox trapezoidalMap( List<Line> S, , List<Vector> Q )
Point LocatoinSearchVertex get( Vector p )
Program ( including visualization )CG2017 PA3-2 Which wall are you looking at

6. 拓展(Follow-ups)

  • Point Location结合Voronoi Diagrams(PA2-2

上一节:CG2017 PA3-1 Delaunay Triangulation (Delaunay三角剖分)

下一节:CG2017 PA4-1 Planar Range Query (平面区域查询)

系列汇总:清华计算几何大作业思路分析和代码实现

7. 参考资料

  1. Computational Geometry: Algorithms and Applications
  2. 计算几何 ⎯⎯ 算法与应用, 邓俊辉译,清华大学出版社
  3. 计算几何 | Computational Geometry

8. 免责声明

※ 本文之中如有错误和不准确的地方,欢迎大家指正哒~

※ 此项目仅用于学习交流,请不要用于任何形式的商用用途,谢谢呢;


在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值