清华计算几何大作业(九):CG2017 PA2-1 Shortest Path in The Room (房间中的最短路径)

1. 前置知识

  1. 计算几何算法:Triangulation,详见教材 3 多边形三角剖分:画廊看守(3 Polygon Triangulation: Guarding an Art Gallery)
  2. DCEL

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

在这里插入图片描述

2. 思路分析

关于这道题的思路分析,笔者在小破站上面发布了系列讲解视频,相关内容视频都有涉及,大家可以观看相关视频,这里就不再赘述:

3. 伪代码

※ 这部分的伪代码是笔者自己翻译的,所以和中文教材上面有些许不同

3.1 单调多边形拆分

// 单调多边形拆分主算法
Algorithm MAKEMONOTONE(P)
算法 MAKEMONOTONE(P)
Input. A simple polygon P stored in a doubly-connected edge list D.
输入:用双向边链表D表示的简单多边形
Output. A partitioning of P into monotone subpolygons, stored in D.
输出:拆分后的多个单调多边形,用D表示
1. Construct a priority queue Q on the vertices of P, using their y-coordinates as priority. If two points have the same y-coordinate, the one with smaller x-coordinate has higher priority.
创建一个优先列队Q,以Y值大的为更高优先级,把所有顶点存储到Q中。如果两个顶点的Y相同,则X越小的优先级越高。
2. Initialize an empty binary search tree T.
初始化一个空的二叉搜索树T3. while Q is not empty
只要Q不为空:
    4. do Remove the vertex vi with the highest priority from Q.Q中移除优先级最高的顶点vi。
        5. Call the appropriate procedure to handle the vertex, depending on its type
        根据顶点的类型,调用相应的处理函数对该顶点进行处理。
// 各个顶点处理算法
// 处理起始顶点(start vertex)
HANDLESTARTVERTEX(vi)
算法 HANDLESTARTVERTEX(vi)
1. Insert ei in T and set helper(ei) to vi.
将边ei插入到T中,并设置ei的helper为vi。

// 处理终止顶点(end vertex)
HANDLEENDVERTEX(vi)
算法 HANDLEENDVERTEX(vi)
1. if helper(ei-1) is a merge vertex
如果边ei-1的helper是merge vertex
    2. then Insert the diagonal connecting vi to helper(ei-1) in D.D插入连接vi和helper(ei-1)的内对角线
3. Delete ei-1 from T.T中删除边ei-1   

// 处理分裂顶点(split vertex)
HANDLESPLITVERTEX(vi)
算法 HANDLESPLITVERTEX(vi)
1. Search in T to find the edge e j directly left of vi.T搜索位于vi左边的第一条边ej
2. Insert the diagonal connecting vi to helper(ej) in D.D插入连接vi和helper(ej)的内对角线
3. helper(ej)<-vi
设置ej的helper为vi
4. Insert ei in T and set helper(ei) to vi.
将边ei插入到T中,并设置ei的helper为vi。

// 处理普通顶点(regular vertex)
HANDLEMERGEVERTEX(vi)
算法 HANDLEMERGEVERTEX(vi)
// similar to HANDLEENDVERTEX()
1. if helper(ei-1) is a merge vertex
如果边ei-1的helper是merge vertex
    2. then Insert the diagonal connecting vi to helper(ei-1) in D.D插入连接vi和helper(ei-1)的内对角线
3. Delete ei-1 from T.T中删除边ei-1
// similar to HANDLESPLITVERTEX()
4. Search in T to find the edge ej directly left of vi.T搜索位于vi左边的第一条边ej
5. if helper(ej) is a merge vertex
如果边ej的helper是merge vertex
    6. then Insert the diagonal connecting vi to helper(e j) in D.D插入连接vi和helper(ej)的内对角线
7. helper(ej)<-vi
设置ej的helper为vi
   
HANDLEREGULARVERTEX(vi)
算法 HANDLEREGULARVERTEX(vi)
// left regular vertex
// similar to HANDLEENDVERTEX()
1. if the interior of P lies to the right of vi
如果多边形的内部落在vi的右侧
    2. then if helper(ei-1) is a merge vertex
   	如果边ei-1的helper是merge vertex
        3. then Insert the diagonal connecting vi to helper(ei-1) in D.D插入连接vi和helper(ei-1)的内对角线
    4. Delete ei-1 from T.T中删除边ei-1
    // similar to HANDLESTARTVERTEX()
    5. Insert ei in T and set helper(ei) to vi.
    将边ei插入到T中,并设置ei的helper为vi。
    // right regular vertex
    // similar to the last part of HANDLEMVERTEX()
    6. else Search in T to find the edge e j directly left of vi.
   反之在T搜索位于vi左边的第一条边ej
        7. if helper(ej) is a merge vertex
	  如果边ej的helper是merge vertex
            8. then Insert the diagonal connecting vi to helper(e-j) in D.D插入连接vi和helper(ej)的内对角线
        9. helper(ej)<-vi
        设置ej的helper为vi

3.2 三角拆分

// 对单调多边形进行三角拆分
Algorithm TRIANGULATEMONOTONEPOLYGON(P)
算法 TRIANGULATEMONOTONEPOLYGON(P)
Input. A strictly y-monotone polygon P stored in a doubly-connected edge ist D.
输入:严格相对Y轴得单调多边形P,用DCEL表示
Output. A triangulation of P stored in the doubly-connected edge list D.
输出:三角拆分后得若干个三角形,用DCEL存储
1. Merge the vertices on the left chain and the vertices on the right chain of P into one sequence, sorted on decreasing y-coordinate. If two vertices have the same y-coordinate, then the leftmost one comes first. Let u1, . . . ,un denote the sorted sequence.
将左链和右链上的顶点存储在一个数组中,并序排序。如果两个顶点的Y值相同,则左边(X值小的靠前)。我们用u_1 ...., u_表示这个排序的顶点数组元素。
2. Initialize an empty stack S, and push u1 and u2 onto it.
初始化一个空stack S,把u_1和u_2入栈。
3. for j←3 to n1
遍历u_到u_n-14. do if uj and the vertex on top of S are on different chains
    如果u_j和栈顶的顶点属于不同的链:
        5. then Pop all vertices from S.
    	弹出S中所有的顶点
            6. Insert into D a diagonal from uj to each popped vertex, except the last one.D中添加连接u_j和每个弹出顶点的内对角线,除了栈底的那个顶点
            7. Push uj−1 and uj onto S.
    		将u_j-1和u_j入栈
        8. else Pop one vertex from S.
    	否则从S中弹出一个顶点
            9. Pop the other vertices from S as long as the diagonals from uj to them are inside P. Insert thesediagonals into D. Push the last vertex that has been popped back onto S.
            持续从S中弹出顶点,直到u_j和弹出顶点的连线不为内对角线则停止弹出。把这些内对角线放入D中,把最后弹出的顶点放回S10. Push uj onto S.
    		将u_j入栈
11. Add diagonals from un to all stack vertices except the first and the last one.
连接u_n和所有S中的顶点,形成内对角线,但不包括栈顶和栈底的顶点。

4. 可视化结果示例

这里展示一个相对复杂的案例,输入多边形为正交多边形( Orthogonal Polygon ),且为迷宫多边形,用这个案例大家可以体会到整个算法项目可以应用到很多领域,比如机器人寻路,自动驾驶寻路,游戏AI寻路等等,当然这里的算法只是基础算法,想要进行落地还是有不少差距的。

首先,我们给到原始输入多边形,和单调多边形拆分:

在这里插入图片描述

其次,进行三角拆分,然后根据拆分得到的三角形进行Dual Graph计算:

在这里插入图片描述

最后,在Dual Graph中运用BFS,找到最短路径需要经过的三角形,最后应用Funnel Algorithm计算得到实际的最短路径:

在这里插入图片描述

5. 项目代码

个人作业项目代码:Algorithm

1.1.4 Triangulation

DescriptionEntry method\File
Partionting monotone polygonsList<Face> makeMonotone( List<Vertex> vertices )
TriangulationList<Face> triangulate( List<Face> monotonePolygons )
BFS in a dual graphvoid BFS( int sizeOfGraph, DualVertex start, DualVertex end )
Funnel algorithmList<Vector> Funnel( DualVertex startTriangle, Vector startPoint, Vector endPoint )
Program ( including visualization )CG2017 PA2-1 Shortest Path in The Room
Pedagogical Aid WebpagePedagogical Aid of Triangulation

6. 拓展(Follow-ups)

  • 复杂多边形的三角拆分,根据教材上面的描述,本题涉及的算法是可以正确处理任意Subdivision的三角拆分,不仅仅对简单多边形有效;
  • 复杂多边形的最短路径问题,既本题允许输入多边形为复杂多边形,同样给到两点,求解两点在多边形内部的最短路径问题;

上一节:CG2017 PA2-2 Find Dancing Partners (寻找舞伴)

下一节:CG2017 PA5-2 FruitNinja(水果忍者)

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

7. 参考资料

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

8. 免责声明

※ 本文之中如有错误和不准确的地方,欢迎大家指正哒~
※ 此项目仅用于学习交流,请不要用于任何形式的商用用途,谢谢呢;


在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值