NAV导航网格寻路 一些必要的计算几何知识

转载:http://blog.csdn.net/ynnmnm/article/details/44833007

NAV导航网格寻路 -- 一些必要的计算几何知识

在继续下面的nav网格生成算法之前,先介绍一下涉及到的计算几何知识。这里只罗列出结论,要详细了解参考相关书籍。

  • 矢量加减法:
     设二维矢量P = ( x1, y1 ),Q = ( x2 , y2 ),则矢量加法定义为: P + Q = ( x1 + x2 , y1 + y2 ),同样的,矢量减法定义为: P - Q = ( x1 - x2 , y1 - y2 )。显然有性质 P + Q = Q + P,P - Q = - ( Q - P )。
  • 矢量叉积
    设矢量P = ( x1, y1 ),Q = ( x2, y2 ),则矢量叉积定义为由(0,0)、p1、p2和p1+p2所组成的平行四边形的带符号的面积,即:P × Q = x1*y2 - x2*y1,其结果是一个标量。显然有性质 P × Q = - ( Q × P ) 和 P × ( - Q ) = - ( P × Q )。
  • 折线段的拐向判断:
      折线段的拐向判断方法可以直接由矢量叉积的性质推出。对于有公共端点的线段p0p1和p1p2,通过计算(p2 - p0) × (p1 - p0)的符号便可以确定折线段的拐向:
      若(p2 - p0) × (p1 - p0) > 0,则p0p1在p1点拐向右侧后得到p1p2。
      若(p2 - p0) × (p1 - p0) < 0,则p0p1在p1点拐向左侧后得到p1p2。
      若(p2 - p0) × (p1 - p0) = 0,则p0、p1、p2三点共线。
  • 判断两线段是否相交:
      我们分两步确定两条线段是否相交:
      (1)快速排斥试验
        设以线段 P1P2 为对角线的矩形为R, 设以线段 Q1Q2 为对角线的矩形为T,如果R和T不相交,显然两线段不会相交。
      (2)跨立试验
        如果两线段相交,则两线段必然相互跨立对方。若P1P2跨立Q1Q2 ,则矢量 ( P1 - Q1 ) 和( P2 - Q1 )位于矢量( Q2 - Q1 ) 的两侧,即( P1 - Q1 ) × ( Q2 - Q1 ) * ( P2 - Q1 ) × ( Q2 - Q1 ) < 0。上式可改写成( P1 - Q1 ) × ( Q2 - Q1 ) * ( Q2 - Q1 ) × ( P2 - Q1 ) > 0。当 ( P1 - Q1 ) × ( Q2 - Q1 ) = 0 时,说明 ( P1 - Q1 ) 和 ( Q2 - Q1 )共线,但是因为已经通过快速排斥试验,所以 P1 一定在线段 Q1Q2上;同理,( Q2 - Q1 ) ×(P2 - Q1 ) = 0 说明 P2 一定在线段 Q1Q2上。所以判断P1P2跨立Q1Q2的依据是:( P1 - Q1 ) × ( Q2 - Q1 ) * ( Q2 - Q1 ) × ( P2 - Q1 ) >= 0。同理判断Q1Q2跨立P1P2的依据是:( Q1 - P1 ) × ( P2 - P1 ) * ( P2 - P1 ) × ( Q2 - P1 ) >= 0。
  • 凸多边形
    假设我们在一个多边形上(包括多边形的边界及边界围封的范围)任意取两点并以一条线段连结该两点,如果线段上的每一点均在该多边形上,那么我们便说这个多边形是凸的。
  • 凸包
    给定平面上的一个(有限)点集(即一组点),这个点集的凸包就是包含点集中所有点的最小面积的凸多边形。
  • 点在凸多边形中的判断
    假设多边形是凸的,而且顶点p0,p1,...,pn按顺时针方向排列,则点在多边形任意一边 pi-1, pi 的右面。
  • Voronoi图及对偶图
  • Delaunay三角剖分(Voronoi对偶图)

    在实际中运用的最多的三角剖分是Delaunay三角剖分,它是一种特殊的三角剖分。先从Delaunay边说起:
        【定义】Delaunay边:假设E中的一条边e(两个端点为a,b),e若满足下列条件,则称之为Delaunay边:存在一个圆经过a,b两点,圆内(注意是圆内,圆上最多三点共圆)不含点集V中任何其他的点,这一特性又称空圆特性。
        【定义】Delaunay三角剖分:如果点集V的一个三角剖分T只包含Delaunay边,那么该三角剖分称为Delaunay三角剖分。
    以下是Delaunay剖分所具备的优异特性:
        1.最接近:以最近临的三点形成三角形,且各线段(三角形的边)皆不相交。
        2.唯一性:不论从区域何处开始构建,最终都将得到一致的结果。
        3.最优性:任意两个相邻三角形形成的凸四边形的对角线如果可以互换的话,那么两个三角形六个内角中最小的角度不会变大。
        4.最规则:如果将三角网中的每个三角形的最小角进行升序排列,则Delaunay三角网的排列得到的数值最大。
        5.区域性:新增、删除、移动某一个顶点时只会影响临近的三角形。
        6.具有凸多边形的外壳:三角网最外层的边界形成一个凸多边形的外壳。
  • 多边形裁剪

    Weiler-Athenton算法

–主多边形:被裁剪多边形,记为A

–裁剪多边形:裁剪窗口,记为B

多边形顶点的排列顺序(使多边形区域位于有向边的左侧 )外环:逆时针 ;内环:顺时针

主多边形和裁剪多边形把二维平面分成两部分。

内裁剪:A∩B

外裁剪:A-B

裁剪结果区域的边界由A的部分边界和B的部分边界两部分构成,并且在交点处边界发生交替,即由A的边界转至B的边界,或由B的边界转至A的边界。

如果主多边形与裁剪多边形有交点,则交点成对出现,它们被分为如下两类:

进点:主多边形边界由此进入裁剪多边形内  如,I1,I3, I5, I7, I9, I11

出点:主多边形边界由此离开裁剪多边形区域. 如, I0,I2, I4, I6, I8, I10 

算法步骤

(1)建立空的裁剪结果多边形的顶点表.

(2)选取任一没有被跟踪过的交点为始点,将其输出到结果多边形顶点表中.

(3)如果该交点为进点,跟踪主多边形边边界;否则跟踪裁剪多边形边界.

(4) 跟踪多边形边界,每遇到多边形顶点,将其输出到结果多边形顶点表中,直至遇到新的交点.

(5)将该交点输出到结果多边形顶点表中,并通过连接该交点的双向指针改变跟踪方向(如果上一步跟踪的是主多边形边界,现在改为跟踪裁剪多边形边界;如果上一步跟踪裁剪多边形边界,现在改为跟踪主多边形边界).

(6)重复(4)、(5)直至回到起点

时间: 2024-07-30 10:19:41

NAV导航网格寻路 一些必要的计算几何知识的相关文章

NAV导航网格寻路(3) -- 一些必要的计算几何知识

这篇是转的文章,原文http://blianchen.blog.163.com/blog/static/13105629920103614613291/ 在继续下面的nav网格生成算法之前,先介绍一下涉及到的计算几何知识.这里只罗列出结论,要详细了解参考相关书籍. 矢量加减法: 设二维矢量P = ( x1, y1 ),Q = ( x2 , y2 ),则矢量加法定义为: P + Q = ( x1 + x2 , y1 + y2 ),同样的,矢量减法定义为: P - Q = ( x1 - x2 , y

NAV导航网格寻路(2) -- 寻路方法

这篇是转的文章,原文http://blianchen.blog.163.com/blog/static/1310562992010324046930/ nav寻路一般包含两部分,首先是使用工具根据地图信息生成寻路用的nav mesh,接下来就是在游戏中根据生成的nav mesh来自动寻路. 一般人首先关心的就是寻路方法,所以这里把顺序颠倒下,先说寻路. 一.  使用A*寻找所经过网格路径 下图为一个已经生成nav网格的地图,深红色区域为不可行走区域,浅红色区域为可以行走的区域. 如下图,现在如果

NAV导航网格寻路(7) -- 代码和一些优化

这篇是转的文章,原文http://blianchen.blog.163.com/blog/static/131056299201031293039882/ 这里发不了源码,本系列完整源码可以到http://bbs.9ria.com/thread-49841-1-1.html下. 看下图,最优路径应该是从上面绕过中间阻挡区,而实际寻路产生的路径确是下面.这是由于,在网格面积过大或有某边长度过长时,由于a*中的花费是计算网格的两边中点距离而不实际的路径长度,所以产生的路径偏差较大.所以在一般的网格生

NAV导航网格寻路(4) -- 生成nav网格

这篇是转的文章,原文http://blianchen.blog.163.com/blog/static/131056299201037102315211/ 假设上图是一个游戏地图,红色的区域是不可行走的区域,浅灰色区域是可行走区域,要想在游戏中实现nav寻路,必须将可行走区域转化为nav网格并保存为一种固定形式的数据,如下图浅红色的三角形. nav网格必须是凸多边形,这里使用三角型,当然也可以使用4边形.下面介绍一种任意多边形的三角化算法.算法来自论文<平面多边形域的快速约束 三角化>作者:曾

NAV导航网格寻路(5) -- 生成网格的一些补充

这篇是转的文章,原文http://blianchen.blog.163.com/blog/static/13105629920103811451196/ 如果你也实现了上一章提到的代码,不难发现对下图的两种情况会出现问题 左面的是两个区域有相交的情况,右面的是多边形本身有自交,在这两种情况下,前面给出的代码均会产生错误的结果. 对于两个多边形相交,可以在生成网格之前先合并多边形,合并后如图 合并算法在前面多边形剪裁处已给出一个,这里只贴上代码: /** * 合并两个多边形(Weiler-Athe

NAV导航网格寻路(6) -- 寻路实现

这篇是转的文章,原文http://blianchen.blog.163.com/blog/static/13105629920103911258517/ 前面已经介绍了寻路的方法,现在给出我的一个实现. A*寻找网格路径 A*算法就不说了,网上很多,这里只说下三角形网格如何使用A*算法,如下图,绿色直线代表最终路径和方向,路径线进入三角形的边称为穿入边,路径线出去的边称为穿出边.每个三角形的花费(g值)采用穿入边和穿出边的中点的距离(图中红线),至于估价函数(h值)使用该三角形的中心点(3个顶点

NAV导航网格寻路(1)-- 介绍

这篇是转的文章,原文 http://blianchen.blog.163.com/blog/static/13105629920103211052958/ WayPoint寻路 下图是一个典型的路点寻路 另一种方法是使用多边形来记录路径信息,它可以提供更多的信息给ai角色使用.下图就是一个navigation mesh. 以下列出几个WayPoint的不足之处: 一些复杂的游戏地图需要的WayPoint数量过于庞大 有时会使角色走“Z”型路径 如下图A点和B点之间的路径 NAV寻路如下图 下图是

Unity之导航网格寻路相关参数

1.Object(物体)参数面板 Navigation Static:选中该复选框,则表示该游戏对象将参与导航网格的烘焙. Generate OffMeshLinks:选中该复选框,可以自动根据Drop Height(下落高度)和Jump Distance(跳跃距离)的参数设置用关系线来连接分离的网格(模型). NavigationArea:导航区域设置.在默认情况下分为Walkable(行走区域).Not Walkable(不可行走层)和Jump(跳跃层). 2.Bake(烘焙)参数面板 Ag

【Unity】12.2 导航网格寻路简单示例

开发环境:Win10.Unity5.3.4.C#.VS2015 创建日期:2016-05-09 一.简介 本节通过一个简单例子,演示如何利用静态对象实现导航网格,并让某个动态物体利用导航网格自动寻路,最终找到目标. 二.设计步骤 1.添加3个Cube 启动Unity应用程序打开ch1201_Navmesh_Sample工程,新建一个名为Demo1-1.unity的场景,然后在场景中创建3个Cube,如下图所示: 2.生成导航网格 (1)将3个Cube全变为Static 分别选中游戏场景中的3个C