精华内容
下载资源
问答
  • 测向器 一个重要的谷歌地图功能的简单表示——使用谷歌地图 Javascript API v3 查找两个地方之间的行车路线。
  • 在《绘制二维障碍栅格地图的一种方法1(局部地图的绘制)》 http://blog.csdn.net/zhubaohua_bupt/article/details/72923373 这篇博客里, 我们讲述了如何利用深度相机去绘制单帧图像看到的局部地图。但是只有局部...


    全局地图的绘制 


     在《绘制二维障碍栅格地图的一种方法1(局部地图的绘制)http://blog.csdn.net/zhubaohua_bupt/article/details/72923373 


    这篇博客里,我们讲述了如何利用深度相机去绘制单帧图像看到的局部图。


    但是只有局部地图是不够用的,在一般的地面机器人的路径规划中,往往需要整个场景的栅格地图,


    这样,就可以为机器人,在场景里所有可达的目标位置,提供路径规划数据。本篇博客是接上述那篇博客讲述的。


    本篇博客内容为:


    在已知局部栅格地图后,怎么通过相机在不同时刻的位姿,把多帧局部地图绘制成全局栅格地图。

    比如,这是一个局部地图:


    不断融合后,形成的全局地图:



    关键技术点


       1坐标转换,局部栅格地图根据相机位姿,把二维栅格点转换到不断融合的全局地图     


       2 地图融合:不断融合的全局栅格地图,和新的一帧局部栅格地图的融合


    坐标转换


    坐标转换是把t时刻的局部地图点,经过相机t时刻的位姿,投射到全局地图中。


    栅格地图的应用对象是地面机器人,它的运动一般是二维的,所以,在坐标转换过程中,我们只需要考虑


    相机当前坐标系与初始坐标系(一般用它来作为全局参考系)的偏航角Yaw与t时刻相机中心在全局中心的位置


    以下默认坐标系(Z轴:相机前方向,Y轴:相机下方向,X轴:相机左方向)

     

    偏航角的计算:

           如果我们知道了t时刻相机相对于全局参考坐标系的位姿T(R,t)之后,只需要姿态R,就可以转换得到

    偏航角Yaw(不明白就搜旋转矩阵转RPY角)


    公式如下:



    其中, R为t时刻相机相对于参考系的旋转矩阵,R31为旋转矩阵第三行第一列的元素,其他类推。


    t时刻相机中心在全局中心的位置 :



    地图融合

            

            这一部分讲述的是,把局部地图投影到全局地图后,怎么和已有的全局地图进行融合,


    形成一个新的全局地图。我们知道,栅格地图至少有三种状态(可通行(无障碍占据)、有障碍占据、未知),


    融合是解决这样一个具体问题在全局栅格地图中,某一个栅格(称为g)肯定是这些状态中的一种,


    当局部地图上的点伴随着它自己的状态,投影到栅格g上时,怎么解决栅格g状态更新的问题。


          常用的融合策略是概率融合(搜概率栅格图)。在《局部地图》这篇博客中,我们画的局部地图其实就是概率栅


    图,初始时,用像素值128表示当前栅格不确定(所用像素值的范围0-255),然后,如果当前栅格是障碍,


    我们把它置0,否则就是255。

           

     

    融合方法1:比较暴力但可行的融合策略。

      

    现在,我们用一种粗暴但有效的方法来解决融合问题:


    全局栅格地图上栅格的值,我们不让它是3值的(3状态),而是让它们分布在0-255,


    栅格对应的值小于128时,越小是障碍的概率越大,栅格对应的值大于128时,越大是障碍的概率越小。


    如此,我们就可利用如下思想融合地图:


    如此,我们就可这样融合地图:

    IF  plocalGrid==obstacle and plocalGrid -value1>=0

    Then pglobleGrid-=value1;

    ELSE IF plocalGrid== PassableandpglobleGrid +value2<=255

    Then pglobleGrid +=value2;

    Endif


    value1和value2是一个经验值,比如可以都取5。


    注:pglobleGrid为局部栅格plocalGrid投影到全局栅格上后,在全局栅格上的位置。 栅格地图的像素值在0~255之间。


    这个方法虽然比较暴力,但也是基于统计的,效果可行。


    融合方法2:贝叶斯滤波


    更普通的方法是利用贝叶斯滤波对栅格地图融合。先给出公式


    这个公式乍一看有点复杂,但稍微经过解释,非常容易理解。下面我们来看看,这个公式表述了一个怎样的融合方法。

    首先解释一下公式中的符号含义:


    z : 2值观测值(每一次的观测值来源于局部地图,只有两种状态:占据、空闲)


    融合t+1时刻的观测值后,栅格i被障碍占据的概率。

            融合t时刻的观测值后,栅格i被障碍占据的概率。


    单纯的从t+1时刻的观测值,判断的栅格i被障碍占据的概率


    一般取常数,比如,


    注意:这里不是一个完备事件,

    也就是说两者之和不一定为1。


    说到这里,讲的可能还不是特别清楚,我们举个融合的例子来帮助理解。



    通过这两个例子,也就是新观测不同的时候,全局地图融合的过程,你是否能理解这个公式呢?


    地图融合注意事项:


             在融合地图时,我们只融合当前局部地图能看到的范围,我们不能往全局地图里融合未知的范围,否则就会出错。

             举个例子,比如你的全局地图刚才看到了一面墙后面的场景,当前局部地图看到的是相机至这面墙之间的空间,墙后面的看不到(对于局部地图是未知区域),这个时候,如果把未知融合到全局地图里,肯定不是我们想要的。

             最后,地图构建的效果见顶端。


    转载请说明出处:http://blog.csdn.net/zhubaohua_bupt/article/details/77093334


    展开全文
  • 然而,A*可用于任意图形,不仅仅是网格,有很多种地图表示都可以使用A*算法。地图表示可能对性能和路径的质量产生很大影响。寻路算法不是线性的,而是越来越差。如果需要行进的距离翻倍了,那么会消...

    转自:https://www.gameres.com/489480.html

     

    在本系列文档大部分内容中,我都假设A*用于某种网格上,其中的“节点”是一个个网格的位置,“边”是从某个网格位置出发的各个方向。然而,A*可用于任意图形,不仅仅是网格,有很多种地图表示都可以使用A*算法。

    地图表示可能对性能和路径的质量产生很大影响。

    寻路算法不是线性的,而是越来越差。如果需要行进的距离翻倍了,那么会消耗超过两倍的时间来找路径。你可以想象寻路算法是在搜索一个类似圆的区域,当圆的直径加倍时,区域变成原来的四倍。一般来说,在地图表示中,节点越少,A*算法越快。而且节点越匹配角色单元将要移向的位置,路径质量越好。

    游戏中,用于寻路的地图表示不需要和用于其他用途的地图表示一样。但是采用相同的表示是一个不错的起点,直到你发现需要更好的路径或更高的性能。

    网格(Grid)

    网格图将世界(world)均匀分割为小的规则图形,这些图形有时被称为“图块(tile)”。常用的网格有正方形、三角形和六边形。网格很简单,也很容易了解,很多游戏都采用它来表示世界,因此本文中我重点关注网格。


    在《BlobCity》游戏中我采用网格表示,因为在每个网格位置,移动成本都不同。如果在一大片空间内,移动成本都是均匀的(正如前文我举过的例子),那么用网格可能就相当浪费。因为此时,A*无需一次走一步,它可以跳过一大片区域走到另一端。在网格上寻路,得到的也是网格上的路径,可以通过后期处理,消除锯齿状移动。但是如果你的角色单元没有限制必须在网格上移动,或者你的世界甚至不采用网格,那么在网格上寻路可能不是最好的选择。

    图块移动(Tile movement)


    即使在网格中,也可以选择沿图块、边或顶点移动。图块是默认选项,尤其是角色单元只能移动到图块中心的那些游戏。在上图中,在A处的单元可以移到所有标B的位置。你也许还允许对角线移动,代价相同或者更高。

    如果你采用网格寻路,但角色单元不限制仅沿网格移动,并且移动成本是均匀的的,那么你可能想要拉直路径,即如果某两个节点之间没有障碍,可以从一个节点沿直线移动到另一个远处的节点。

    边移动(Edge movement)


    如果角色单元可以移动到一个网格内的任何一点,或者图块很大,就应该考虑,你的应用是否选择边寻路或顶点寻路更好。

    一个单元通常从一个边(一般是边的中点)进入图块,并从另一个边离开那个图块。图块寻路中,单元移到图块中心,但边寻路中,单元直接从一个边移到另一个边。我写了一个java applet,演示绘制边之间的道路,可能帮助说明边是如何使用的。

    顶点移动(Vertex movement)


    网格图中的障碍通常在顶点处有拐角。在障碍物周围,最短的路径就是要绕过这些拐角。顶点寻路中,角色单元从一个拐角移到另一个拐角。这是一种最节省开销的移动,但是要依据角色单元的大小调整路径。

    多边形地图(Polygonal maps)

    除了网格,最常用的是多边形表示。如果一大片区域的移动成本是均匀的,并且角色单元可以沿直线移动,而不是沿网格移动,你可能想采用一种非网格的表示。在你的游戏中,即使其他东西采用网格,寻路也可以使用非网格的图形表示。这里有个简单的例子,是一种多边形的地图表示。这个例子中,角色单元需要绕过两个障碍。


    想象在这个地图中角色单元如何移动。最短路将在这些障碍的拐角点之间,因此我们选择这些拐角点(红色圆点)作为A*算法的关键“导航点”;每次地图改变,就计算一次这些点。如果障碍和网格对齐,那么导航点和网格顶点对齐。此外,寻路的起点和终点应当标示在图中;每次调用A*,都需要将这两个点加到图上。

    除了导航点,A*需要知道哪些点是连通的。一个简单的算法是构建可视图:互相可见的点对。这个简单算法可能满足你的需求,尤其是当游戏中地图不常改变时。但是如果这个算法太慢,你可能需要一个更复杂的算法。另外,在图上添加起点和终点后,对任意两个顶点(包括起点和终点),如果两点可见,添加一条这两点连接而成的边。

    A*需要的第三条信息是点之间的行进时间。如果在网格上移动,时间就是曼哈顿距离(manhattan distance)或对角网格距离(diagonal grid distance)。如果可以在导航点之间直接移动,时间就是直线距离。

    接下来,A*考虑从导航点到导航点的路径,图中粉色线就是其中一条路径。如果导航点很少,而网格位置很多,这种方法要比从网格点到网格点的寻路快得多。如果路上没有障碍,A*性能非常好——起点和终点将由边连接,无需扩展任何导航点,A*可以立即找到路径。即使有障碍,A*也将从一个拐角点跳到另一个拐角点,直到找到最优路径,这将仍然比在网格位置间寻路要快得多。

    维基百科中有更多关于机器人文学中的可视图。

    复杂性管理(Managing complexity)

    上边的例子非常简单,图也很合理。然而在一些有很多开放区域或长廊的地图中,可视图的一个弊端就显现出来了。连接每对障碍拐角点的一个主要缺点是,如果有N个拐角点(顶点),则至多有N2条边。下图展示了这个问题:


    这些额外的边主要影响内存使用。相比网格,这些边提供一种捷径,大大加快了寻路。虽然有算法可以删除冗余的边,以简化图形,但删除之后仍然有很多边。

    可视图的另一个缺陷是,每次调用A*,都要添加起点和终点,以及以它们为顶点的新边,然后在找到路径之后,删除这些添加的东西。节点很好加,但增加边需要考虑从这些新节点到所有已有节点的可见情况,如果地图很大,这可能会很慢。一种优化方案是只看附近的节点,或者也可以用简化可视图,删除和两个顶点都不相切的边(这种边永远不会出现在最短路中)。

    导航网(Navigation Meshes)

    不用多边形表示障碍,而是将可行区域用不重叠的多边形表示,这也被称为导航网。这些可行区域还可以附有一些信息(如“要求游泳”或“移动成本为2”)。这种表示法不需要存储障碍。

    前面的例子就变成了下图这样:


    我们可以像处理网格一样处理这个,同样的,可以选择多边形中心点、边或顶点作为导航点。

    多边形移动(Polygon movement)

    同网格一样,每个多边形的中心提供了一个合理的寻路节点集。此外,还要添加起点和终点,以及这两个点与所在区域中心点所连成的边。下图中,黄色路径是沿多边形中心点寻路所得的路径,粉色路径是理想路径。


    可视图表示可以产生那条粉色理想路径。采用导航网使地图易于管理了,但是路径的质量受到影响。我们可以消除路径,使其看起来更好一些。

    多边形边移动(Polygon edge movement)

    移到多边形的中心通常是不必要的。相反,我们可以穿过相邻多边形的边而移动。下面这个例子中,我选择每条边的中点。黄色路径是沿边中点寻路所得的路径,相比理想的粉红色路径,是一条不错的路径。


    你也可以增加成本,在边上选更多的点,来产生更好的路径,

    多边形顶点移动(Polygon vertex movement)

    绕过障碍的最短路径是绕过其拐角,这也是为什么我们在可视图表示中采用拐角点,在这里即是导航网的顶点:


    上图中,路上只有一个障碍。当要绕过障碍时,黄色路径会穿过一个顶点,粉色路径(理想路径)也一样。然而,可视图方法将直接连线起点和障碍拐角点,导航图则要更多步。这些步骤不应该沿顶点走,因此路径看起来不自然,有“抱墙”行为。

    混合式移动(Hybrid movement)

    对于多边形的哪个部分可以用作寻路导航点,我们并没有任何约束。你可以在一条边上多加一些点,顶点也不错,多边形的中心点则基本没用。下图是采用了边中点和顶点的一种混合方案:


    注意要绕过障碍,需要穿过一个顶点,但在其他地方,则可以穿过边中点。

    路径消除(Path smoothing)

    只要移动成本是固定的,路径消除相当容易。算法很简单:如果点i到点i+2可见,删除点i+1,循环直到邻节点之间都不可见。剩下的只有绕过障碍物拐角点的导航点。这些点都是导航网的顶点。因此如果使用路径消除,就不需要采用边中点或多边形中心点作为导航点,只要顶点就可以了

    上面的例子中,路径消除可以将黄色路径变成粉红色路径。然而,寻路算法并不知道这些更短的路径,因此它的决策不会优化。导航网是一种近似地图表示,而可视图是一种精确地图表示。缩短在导航网中找到的路,结果并不总能像通过可视图找到的路一样好。

    分层(Hierarchical)

    平面地图只有一层。而游戏很少只有一层——往往有一个“图块”层,然后有一个“子图块”层,物体可以在图块中移动。然而我们通常只在高层寻路。你也可以添加更高的层,如“房间”。

    在地图表示中,节点越少,寻路越快。还有一种加快寻路速度的方法是多层次搜索。例如,要从你家到另一个城市的某个位置,你会找到一条路,从你的椅子到你的车,从车到街道,从街道到高速公路,从高速公路到城市边缘,再从那儿到另一个城市,然后到一个街道,到一个停车场,最终到达目的地门前。此时,有下述几层搜索:

    街道层,你从一个位置走到附近的某个位置,但不会走出这条街。

    城市层,你从一条街道走到另一条,直到找到高速公路。你无需担心进入建筑物或停车场,也不用担心在高速公路上行驶。

    州层,在高速公路上,你从一个城市到另一个城市。在到达目的城市之前,你无需担心城市内的街道。

    将问题分层,可以忽略很多选项。例如当从一个城市到另一个城市时,考虑路上每个城市的每条街道是很乏味的。相反,你可以忽略它们,只考虑高速公路,问题就变得很小且易于管理,解决也变得很快。

    分层地图在表示上有很多层。异构层次结构(heterogenous hierarchy)通常有固定层数,各有不同特点。例如,《Ultima 5》有一个“世界”地图,上边有城市和地牢。你可以进入一个城市或地牢,这就进入地图的第二层。另外,世界之上还有世界,从而是一个三层结构。这些层可以是不同的类型(图块网格、可视图、导航网、路标)。而同质层次结构(homogeneous hierarchy)层数任意,每层都有相同的特性。四叉树和八叉树就是同质层次结构的。

    分层地图中,寻路可能发生在几个层次。例如,假设一个 1024×1024 的世界被划分为 64×64 个“区域”,则可以这样找到一条路径,从玩家位置到区域边缘,然后从一个区域到另一个区域,直到到达目的区域,然后从那个区域的边缘到达目的位置。粗级别上,更容易找到长路径,因为寻路算法没有考虑所有的细节。当玩家穿过每个区域时,可以再次调用寻路算法,找一个短路径。保证问题规模很小,寻路算法就可以运行得更快。

    你可以结合使用分层和图搜索算法,如A*,但是不需要每一层都采用一样的算法。对一些小的层级,你可以预算所有节点间的最短路(用Floyd-Warshall或其他算法)。在分层地图中,通常找不到最优路径,但一般都接近最优。

    还有个类似的方法是改变分辨率。首先,绘制低分辨率路径。当接近一个点时,用高分辨率精化路径。这个方法可以结合路径拼接使用,以避免移动障碍。

    一些文章:《“龙腾世纪:起源”中的寻路算法》解释某商业游戏中使用的几种分层方法,《采用线性预处理的超快最短路查询》在道路图中使用“运输节点”[PDF],《游戏网格地图的运输节点》、《分层A*:有效搜索抽象层》、《道路网路线规划》(Dominic Schulte的博士论文),逐层注解A*(第一部分,第二部分,源代码)。

    环绕式地图(Wraparound maps)

    如果你的世界是球形或环形的,物体可以从地图的一端绕到另一端。最短路可能在任一方向,因此必须探索所有的方向。如果用网格,环绕时可以用启发式方法。此时,我们不用abs(x1 – x2),而采用min(abs(x1 – x2), (x1+mapsize) – x2, (x2+mapsize) – x1),即考虑三种情况的最小值:待在地图上不绕行,x1在左边时绕行,或x2在左边时绕行。绕行每个轴时都这样做。本质上来说,你计算启发值时,假设地图与其副本邻接。

    连通组件(Connected Components)

    有些游戏地图中,起点和终点之间根本就无路可通。如果用A*找路,它会探索图的很大一个子集,才能确定根本没路。如果可以预先分析地图,用不同的标记标识出所有的连通子图,那么在找路之前,首先检查起点和终点是否都在同一个子图中。如果不在,那么这两者之间无路可通。另外分层寻路在这也可以用,特别是子图之间有单向边时。

    道路图(Road maps)

    如果你的角色单元只能在道路上走,你可能需要提供A*道路和交叉口的信息。每个交叉口是图上的一个节点,每条路是图上一条边。A*找从交叉口到交叉口的路,这比用网格表示要快得多。

    有时,角色单元的起点和终点可能不在交叉口。此时,每次运行A*时,都要修改点/边图(和可视图和导航图采用的技术一样),将起点和终点作为新节点加到图中,然后在这两个点和最近的交叉点之间连线。寻路结束后,再删除这些额外的节点和边,这样图在下次调用A*时还可以使用。


    上图中,交叉口是寻路图中的节点,节点之间的道路是边,且每条边都应给定道路行驶距离。在这个框架中,你可以把单向道路作为图上的单向边。

    如果你想给转向分配成本,你可以稍稍扩展这个框架:将原来单一的位置节点,变为<位置,方向>节点(静态空间的一个点),其中方向指你到达那个位置后所面向的方向;将原来从X到Y的边,换成从<X,方向>到<Y,方向>的边(代表直行),和从<X,方向1>到<Y,方向2>的边(代表转向)。每条边都或者代表直行,或者代表转向,不可能两者都是。然后你可以给代表转向的边分配成本。

    如果你还要考虑转向限制,如“只能右转”,你可以改变上述框架,即结合使用那两种边,每个转向边之后都是直行。例如,在这个框架中,你想表示一个限制“只能右转”:添加一个直行边<X,北>到<Y,北>,一个转向边<X,北>到<Z,东>,转向之后是直行。不要添加<X,北>到任何向西的边,因为这意味着左转,也不要添加任何向南的边,因为这意味着掉头。

    利用上述框架,可以对一个大型市中心建模,其中有单向道路,特定路口转向限制(通常禁止掉头,有时禁止左转),以及转向成本(建模在右转之前减速和等待行人)。相比网格图,道路图中A*找路相当快,因为每个节点处的选择很少,而且图上的节点也相对较少。

    跳跃链(Skip links)

    基于网格创建的寻路图,一般给每个位置分配一个顶点,给相邻位置之间的每个可能的移动分配一条边。然而边不一定必须是相邻顶点之间的,“跳跃链”或“快捷链”就是非相邻点之间的边,它可以加快寻路进程。

    跳跃链的移动成本怎么算呢?有两种方法:

    使成本匹配最优路径的移动成本。这保留了A*的优良特性,如寻找最优路径。为了将A*推向正确的方向,要打破跳跃链和常规链之间的关联,即将跳跃链的成本减少1%左右。

    使成本匹配启发成本。这对性能有很大影响,但是放弃了最优路径。

    添加跳跃链类似于分层地图,花费更少的精力,但往往能给你一样的性能。

    对于有地下室和走廊的网格图,矩形对称性缩减和跳跃点搜索提供两种方法建立跳跃链。矩形对称性缩减(Rectangular Symmetry Reduction)静态建立附加边(他们称为宏边),然后调用标准的图搜索算法。跳跃点搜索(Jump Point Search)动态建立长边,是图搜索算法的一部分。对于道路图和其他类型的图,抽象分层值得一看。

    路标(Waypoints)

    路标是路径上的一个点。路标可以具体到每条路,或者是游戏地图的一部分。路标可以手动输入或自动计算。很多实时策略游戏中,玩家点击就可以手动添加特定路径的路标。当自动计算时,路标可以简化路径表示。地图设计者可以在地图上人工添加路标(或“信标灯”),以标识好路径的位置,或者也可以用算法自动标识。

    使用跳跃链是为了加快寻路,因此跳跃链应当放在设计者设置的路标之间,这可以使其利益最大化。

    如果路标不是很多,可以预算每对路标之间的最短路(用全对最短路算法,不用A*)。常见的情况就是,一个角色单元先按照自己的路径到达一个路标,然后按照预算的路标间的最短路走,最后离开路标这个高速路,走自己的路到达目标。

    如果路标或跳跃链的成本错误,可能导致找到次优路径。有时我们可以通过后期处理或在移动中,消除一个糟糕的路径。

    图形格式建议(Graph Format Recommendations)

    一开始你在已使用的游戏世界表示中寻路,如果你不满意,考虑将游戏世界转换为方便寻路的另一种表示形式。

    很多网格游戏中,地图的很多大块区域移动成本都是均匀的,但是A*不知道这些,并且浪费时间来探索它们。创建一个简单图(导航网,可视图,或者网格图的分层表示)可以帮助A*。

    移动成本固定时,可视图产生的是最优路径,且A*运行很快,但是边存储耗费大量内存。网格允许移动成本有细微改变(地形,斜坡,惩罚用的危险区域等),边存储耗费内存少,但点存储耗费很多内存,而且A*可能很慢。导航网居于两者之间。在大块区域移动成本均匀时,它效果很好,而且允许移动成本的些微改变,还能产生合理的路径。这些路径并不总如可视图产生的一样短,但是通常都是合理的。分层地图采用多层表示来处理长距离内的大致路径,以及短距离内的详细路径。

    你可以读读这篇很形象的文章,了解更多关于导航网的知识。注意这篇文章比较了:(a)仅保持可行多边形和仅保持导航点,(b)沿顶点走和沿多边形中心点走。这些大多是正交的。保持可行多边形有利于后期动态调整路径,但是并非所有的游戏都需要。使用顶点更有利于避免障碍,并且如果你采用了路径消除,还不会影响路径质量。如果没有路径消除,边的效果可能更好,所以考虑边或是边+顶点。

    除了给网格地图构建一个独立的非网格表示,你也可以改变A*,使其更好得理解成本均匀分布的网格地图。可以参照跳点搜索在方格上加速A*的方法,以及Theta*在网格上生成非网格移动的方法。

    相关阅读:游戏中常用的寻路算法(5)预先计算好的路径的所用空间

    展开全文
  • 地图是人类文化的杰作,它融科学、艺术于一体,作为描述、研究人类生存环境的一信息载体是人类生产与生活中不可缺少的一工具。”这是陈述彭院士为《中国地图学年鉴》作序的开场语。Taylor也曾指出“当涉及应用...

    “地图是人类文化的杰作,它融科学、艺术于一体,作为描述、研究人类生存环境的一种信息载体是人类生产与生活中不可缺少的一种工具。”这是陈述彭院士为《中国地图学年鉴》作序的开场语。Taylor也曾指出“当涉及应用人脑来识别空间联系中的模式与相互关系时,地图学的认知方法是唯一的过程”。地图存在于我们生活的方方面面,应用广泛且己经产生了巨大的社会效应和经济效益,其重要性不言而喻。地图是地图可视化的结果,地图可视化作为现代地图学的核心一直是三维GIS(http://www.ztmapinfo.com/)的研究热点。地图可视化将电子设备的视觉传输能力和人类的视觉思维能力协同起来,将复杂多样的空间信息转化为图形图像并进行交互处理,为人们直观地观察地理现象及分析和探索地理规律提供了有力的工具。随着计算机技术和图形硬件的发展,利用计算机技术来辅助制作电子地图逐渐成为主流趋势。上世纪80年代科学计算可视化己被提出并迅速发展,其理论和方法对空间信息的表达和分析产生了重要影响。国际地图制图协会于1995年成立了一个地图可视化委员会,并与计算机图形学会开始了“Carto-Project”,研究项目,该项目使图形学技术有效地应用在地理学及地图学领域,为空间信息可视化提供了良好的技术支撑。
    随着云计算、物联网、基于位置的服务等技术的飞速发展,使得数据的种类和存储规模以前所未有的速度增长。数据的规模化效应给地图可视化带来了极大的挑战,传统地图可视化方式上的变革正在酝酿和发生。21世纪以来随着社会经济文化的进步,大众对于地图的需求也日益提高,人们不再满足于二维地图的抽象表达。随着虚拟现实、增强现实等计算机图形学技术的飞速发展,数字地球、虚拟地理环境、虚拟地理场景相继被提出,可视化逐步由二维图形的抽象表达发展至三维空间的逼真展示。在解决大规模空间数据实时绘制的问题上,国内外学者进行了广泛而深入的研究,主要集中在空间索引优化、LOD、可见域裁剪和渲染方法优化等多个方面。其中,LOD方法改变了“图形质量越精细越好”的片面观点,在保证绘制效果的基础上有效地控制复杂场景的数据简化,在实时图形绘制、交互式可视化和虚拟现实等领域有着广泛的应用。在GIS领域,采用LOD进行大规模地理场景的实时渲染己经成为最普遍的解决方案。然而,现有的多数矢量地图动态LOD绘制方法在原始数据结构上进行简化,再剖分为图形API支持的基础图元类型,海量且实时的剖分计算和速率敏感的显存IO过程导致了其渲染效率低下;矢量地图静态LOD绘制方法则受限于有限的存储空间和极长的预处理时间。而且,现有的矢量地图LOD绘制方法多是针对二维场景下矢量地图的渲染,没有考虑到投影方式对地图简化的影响,不适用于二三维一体化渲染。
    传统的软件地图渲染方法依靠中央处理器的性能进行可视化渲染,其有限的计算能力导致地图渲染效率低下,难以满足大数据时代下海量空间信息快速呈现的要求。自NVIDIA公司创造性地推出GPU以来,其高效的浮点运算能力和数倍于CPU的显存带宽使得以往由CPU负责处理的几何变换、光照计算、图形及纹理计算等复杂计算全部转移至GPU上进行。随着图形处理器性能的大幅度提高和可编程特性的发展,计算机处理图形的速度和质量得到了极大提升,图形流水线的某些处理阶段和算法从CPU向GPU转移以加速图形的渲染,充分开发GPU资源,已成为近年来计算机图形学领域的研究热点。同样,在GIS领域利用GPU加速地图渲染己经成为地图可视化的发展趋势,GPU性能的提升和可编程特性的发展为提高地图的渲染效率和渲染质量提供了新的技术手段。充分利用GPU的性能,结合LOD技术进行大规模数据的实时渲染已经成为矢量地图优化渲染的重要方向。
    矢量地图渲染方法的优化是现代地图学一个重要的研究方向。人们对于矢量数据渲染需求是源源不断的,空间数据的海量性和地理场景的复杂性使得单纯依靠图形硬件的计算能力远远不能满足数据实时性渲染的需求,所以研究矢量地图的加速渲染技术是十分必要的。本文的研究意义主要体现在以下两个方面:
    (1)提高矢量地图LOD绘制方法绘制效率
    针对现有透视投影下矢量地图动态LOD渲染方法存在的问题,设计一种视投影下矢量地图动态LOD渲染方法用以提高矢量地图LOD绘制方法的绘制效率,同时为三维场景下的矢量地图的渲染提供一种新的解决方案。
    (2)为非瓦片式的地图服务提供新的技术途径
    现有栅格瓦片技术无法更改地图的样式,矢量瓦片可以更改样式但绘制效率相对栅格瓦片效率降低。瓦片式地图受限于计算机存储空间的大小和极长的切片时间,层级之间具有跳跃感且没有考虑投影方式的影响。本文方法考虑到投影方式的影响并对矢量几何要素进行实时简化,为非瓦片式地图服务提供了新的技术途径,为大规模数据可视化提供了新的思路。
    在地图学与GIS领域,点符号、线符号、面符号是矢量地图的三种基础表达方式。因点几何要素不存在自身简化,因此本文主要研究线,面几何要素的动态LOD绘制方法。矢量地图LOD绘制涉及三个主要的可视化操作:简化,剖分与渲染。其中,针对LOD绘制中简化的操作,国内外学者已经进行了广泛而深入的研究。模型简化的实质是一个信息压缩的问题,即从组成模型的有序集合里选择一个子集,在规定的精度范围内,此子集从内容上可以尽可能的反映原集合,而在数据量上尽可能的减少。常见的简化机制包括顶点聚类、增量式删除、采样和自适应细分等方法,基本的简化算法都是通过这四种机制的结合或者变形进行实现的。针对本文的研究,以下将从线几何要素的LOD绘制方法和面几何要素的LOD绘制方法两方面进行介绍。
    1.线几何要素LOD绘制方法
    线几何要素的LOD绘制一般通过简化算法或LOD模型获取简化结果,再对简化结果进行渲染。线几何要素的简化算法一般采用增量式删除法或采样法。这些算法从几何特征的角度出发进行简化,它们都能较好的保留几何要素的图形特征和空间分布特征。针对线几何要素的简化,国内外学者展开了不同的研究。以下,本文从Douglas-Peucker算法, Li-Openshaw算法、渐进式算法及这些算法的改进和线LOD模型分别进行介绍。
    (1) Douglas-Peucker算法及其改进
    Douglas-Peucker算法是一种增量式删除的折线简化算法,算法的基本思路是将曲线的首尾点相连,计算其余点至首尾点连线的垂直距离的最大值,若最大距离小于设定阈值即误差度量则舍去两端点之间的所有节点;若最大距离不小于设定阈值则保留此节点,以首尾点与此节点相连生成两个新的线段,对其重复上述的操作,直至线段上只有两个节点为止。Douglas-Peucker算法采用从整体到局部的思维方式,是最具代表性的空间图形综合方法,可以有效地对折线进行简化并保留其几何特征,但此算法简化过程中要素的拓扑关系发生变化可能会导致要素产生自相交。之后,Peucker和Douglas通过检测凹坑、峰值、脊、沟壑和断裂将Douglas-Peucker算法用效的应用在地形的简化上。针对简化的效率问题,Hershberger和Snoeyink提出了一种基于路径凸包的方法加速了Douglas-Peucker算法的效率,并分析了其最坏时候的运行情况。针对如何避免自相交的问题,Guibas证明了Douglas-Peucker算法中如何避免自相交是一个非确定多项式问题,针对NP-hard问题的求解一般采用穷举法或采用确定性算法,采用穷举法可以很容易得到结果但耗时极长,但确定性算法极难被找到。Saalfelds设计了一种检测拓扑一致性的简单规则,通过添加简单测试进行自相交判断解决了简化的折线自身及与相邻要素潜在的拓扑冲突问题,但检测效率不高。基于逐点前进法提出了一种改进的DP算法,极大地提高了算法的效率。不同于Saalfelds采用的凸包测试,Wu详细分析自相交与折线星形区域的关系,通过分解折线为化星形子集并进行判断来避免要素的自相交,提高了自相交判断的效率。针对三维要素简化的问题,基于二维Douglas-Peucker算法提出了三维Douglas-Peueker算法,良好的解决了三维离散点的综合问题。
    (2) Li-Openshaw算法及其改进
    Li-Openshaw算法是一种采样式的折线简化算法,Li-Openshaw算法基于自然现实实现,算法的基本思想是通过圆在原始曲线上滑动对曲线进行重采样,控制圆的大小获取不同尺度下的简化效果,可以有效的进行线要素的多尺度的简化,但没有考虑曲线上局部极大值点或圆与曲线的多个节点相交导致的异常情况。基于重心算法对Li-Openshaw算法进行改进,这种方法在实现和简捷性方面都取得了较好的效果,曲线光滑程度较为理想。改进Li-Openshaw算法,通过局部极大值点识别弯曲并对弯曲进行细分用以简化,同时依据构造曲线节点顺序判断相交的多个节点中初次出现的节点从而避免异常,解决了Li-Openshaw算法中失真和异常。在Li-Openshaw算法的基础上,使用Nyquist-shannon采样理论采用六边形的剖分对线要素进行采样以简化操作,此方法保持了要素更多的形态特征,适用于制图线的简化但预处理时间较长。结合Douglas-Peucker算法和Li-Openshaw算法提出一种顾及空间关系的线简化方法,通过对建立的全局简化方法的使用有效地降低了曲线的复杂度,且顾及了线要素整体的空间关系。
    (3)渐进式简化算法
    渐进式简化算法是一种增量式删除的简化方法,从局部到整体进行简化,如可以通过使用距离控制、角度控制或者面积控制依次对几何要素的顶点、边进行简化操作,最终完成整个要素的简化。Visvalingam。和Whyatt使用面积作为度量因子对节点剔除,提出了一种线要素的点剔除简化方法,可以有效地保留线要素的几何形态特征并进行简化。通过线结构中的极值点、拐点、凸点和单调区间建立线要素的分层结构,提出了一种从局部到整体的渐进方法可以有效进行线要素的简化,同时考虑了空间拓扑关系避免了要素的自相交。通过剥皮算法,将线要素以二叉树进行组织依据弯曲程度实现对线要素的高效简化。通过节点偏移量,以单调链求交的方式对线要素进行简化实现了线要素的有效简化。
    (4)线要素LOD模型
    针对线要素的LOD模型研究,国内外学者己经提出了多种LOD数据结构如:Strip-Tree、Multi-Scale Line Tree、Arc-Tree和Binary Line Generalisation Tree(BLG-Tree)等。Strip-Tree和Arc-Tree解决了任意曲线存储的问题却不适用于简单多段线的存储。针对多段线的有效存储问题,提出了Multi-ScaleLine Tree,它是一个多向树并引入了离散数量的细节层次,树中的节点可以有任意数量的子项,实现了多段线的静态LOD存储。基于Douglas和Peucker)的线性推广算法的BLG-Tree是一个可变比例的线数据结构,BLG-Tree可以依据阈值动态的获取简化后的线数据,解决了可变比例尺的存储与动态检索问题。但Strip-Tree, Arc-Tree, Multi-Scale Line Tree和B LG-Tree都是针对单个要素的存储,不能用于多个对象的空间组织(索引,聚类),因此只能解决简化和存储的部分问题。为避免数据存储冗余而设计的第一批多尺度矢量数据结构之一是反应性(BinarySpace Partitioning, BSP)树,它支持空间组织和多层次细节展示但它一个静态的LOD结构。Van Oosterom提出的反应树是第一个支持地图对象的空间组织以及多个尺度存储的动态矢量数据结构。反应树(The Reactive-Tree)是R树扩展,反应树可以有效的表达对象的重要性级别,重要性程度高的对象在树结构中相应存储得更高,这使得重要性高的对象更易于访问,而且反应树且支持对象的插入与删除。
    分析可知,现有线要素LOD绘制方法着重于对几何要素数据的简化而没有虑绘制操作。几何要素的简化主要采用增量式删除或重采样的方式进行,增量式删除在原始数据结构进行简化,重采样则会产生新的顶点数据。针对矢量地图中线几何要素渲染的需求,线几何要素必须被剖分成图形API支持的基础图元,再赋以颜色或者纹理完成线几何要素的绘制。依据现有的方法,绘制过程中大量的剖分计算导致现有方法在促进矢量地图的LOD绘制上显得有心无力。
    2.面几何要素LOD绘制方法
    面几何要素(多边形)的LOD绘制实现的直接解决方案是将多边形边界划分为多个段,然后使用线的简化算法对多边形进行简化,最终进行绘制操作。针对多边形几何模型LOD绘制过程中的简化操作,国内外学者己经进行了诸多研究,主要有增量式删除法和采样法。以下,本文分别进行对上述方法进行详细的介绍与分析。
    (1)增量式删除
    增量式删除方法即每次根据用户指定的简化准则在原始模型上选择一个点进行删除,对相关区域进行重新组织。这个简化准则可能仅判断顶点能否删除也可能对模型质量的影响给出一个量化的值(误差度量),通过误差度量完成对节点剔除、边折叠或半边折叠。
    针对节点剔除的处理,一般使用上文中描述的线简化算法如DP算法或渐进式简化算法。提出了一种经典网格简化算法,首先通过将顶点的分类确定顶点是否可以进行删除,再依据阈值对顶点进行删除最终重新三角化,但算法的简化质量不高。Cohen提出了简化信封算法,通过建立信封表面来控制模型顶点的删除,简化质量较好但空间开销巨大,需要对简化的表面进行重新三角化。针对非平面数据,采用顶点删除的方法一般难以保证物体表面的光滑,简化后的结果表面较为粗糙。
    边折叠方法则是通过边的移除操作和相关顶点的合并操作完成,会产生新的顶点,其中以渐进网格方法作为代表。渐进网格方法通过引入边折叠策略使渐进格网能够高效地为任意的三角形网格动态创建连续分辨率数据状态,极大地提高了渲染效率。Qlism算法则采用二次误差度量(Quadric Error Metrics, QEM)表示顶点到平面几何的距离平方和进行度量误差,算法在渲染速度与简化质量之间达到了极大的平衡,可以实现空洞的闭合和物体的合并。
    半边折叠方法不同于边折叠方法,半边折叠方法通过顶点位置移动和边移除完成,不产生新的顶点,存储和运算相对边折叠方法较低。详细分析了顶点移除方法、边折叠方法和半边折叠方法的区别,验证了半边折叠方法的优越性。基于半边折叠方法提出了一种网格简化的通用框架,用以支持研究人员定义不同的简化准则进行简化操作,在简化质量和简化效率上都取得了较好的效果。提出一种实时的渐进网格生成算法,使用堆排序算法将边折叠的计算成本排序成二叉树并定义了只考虑局部信息的简化操作,算法速度得到了很大提升。依据顶点在邻域的尖锐程度判断原始节点的重要性提出一种保持特征的格网简化算法,算法实现简单且简化效率较高。
    分析可知,节点剔除方法需要对简化后的模型进行三角化操作,效率较低;边折叠和半边折叠方法则着重于高度详细的几何模型,适用于如地形数据等特定的GIS数据结构却没有考虑到矢量数据的简化,导致这些方法在促进矢量地图LOD绘制的能力上显得不足。
    (2)采样法
    采样法即通过抽取点或生成新的顶点模拟初始模型,试图通过拟合模型来近似表达原始模型,采样法主要研究如何将采样点合理的分布在表面上以保留原始模型的更多特征。使用规则格网划分模型,判断格网内顶点的重要程度,通过选取重要程度较高的点代表栅格中的顶点从而完成模型的简化,但其简化质量不高。通过聚类的方式对将顶点的集合采用聚类后的顶点进行代替,该算法运算速度快,简化效率有所提高。提出基于混合矢量的光栅的方法同时考虑了制图简化和渲染。该方法采用GPU缓存来有效地创建Voronoi图,以通过像素颜色检查来辅助多边形边界的简化。由于Voronoi图和像素颜色检查可以通过硬件进行加速,这种方法对于简化多边形边界非常有效,但此方法没有考虑多边形填充不适用于矢量地图的渲染且没有处理自相交的问题。使用帧缓存技术改进了混合矢量的光栅方法,实现了大规模矢量数据的快速简化,同时使用模板缓存剔除了Voronoi图因自相交而重叠的区域,解决了原有方法存在的自相交问题。
    (3)面要素LOD模型
    面要素的LOD模型国内外学者己经进行了诸多研究。基于DP算法提出了一种称为二叉线性综合树((BLG-Tree)的数据结构,它递归地将线划分为多段线并将多段线组织成二叉树用于拓扑保持,可以高效地获取多个尺度的面要素简化结果。基于R树结构提出反应树的存储结构,实现动态LOD区域划分。GAP-Tree GAP-Tree是一种广义区域划分方法,它通过分层组织区域的手段对面要素进行划分完成了多尺度下面要素的构建。此外,针对数据存储的冗余和碎片化,国内外学者提出了若干对GAP-Tree的改进如tGap-Tree和流畅tGap-Tree,流畅tGap-Tree可以用以支持三维数据的快速浏览。另外,由于图形简化过程中可能发生拓扑错误和变形,国内外学者提出了诸多拓扑和形状保持的方法。如使用Delaunay三角网检测拓扑错误或者使用分层拓扑数据结构来维持LOD结果之间的拓扑一致性。利用三角形的连接关系提出了一种利用Deaunay三角网的简化算法,实现了要素简化过程中的拓扑关系保持。
    (4)梯形格网方法
    然而为了满足矢量地图多样式渲染的需求,依据当前用于矢量地图LOD绘制的流程,面要素必须组织成可绘制的图元,例如三角形或梯形用以渲染。在这个过程中,对于矢量图形的剖分和显存IO消耗了大量的时间,时间与其数据量呈正比。应用LOD模型或节点剔除法可以有效的简化多边形,但仍需要进行剖分操作,大量的剖分计算导致绘制效率低下;边折叠和半边折叠方法则不适用于矢量地图的渲染。
    针对现有LOD绘制方法存在的问题,考虑到梯形上下底边存在平行关系、顶点位置明确、易于判断空间关系、支持图元的关系运算和关系传递、且可以拆分成三角形进行高效渲染等特性,借鉴半边折叠算法提出了一种支持矢量面几何要素渲染的梯形格网渲染方法设计了一种既支持简化又可直接用于渲染的梯形格网结构(下图(a))并提出了一种针对2D地图面几何要素的梯形格网简化算法(下图(b))将面几何要素简化与剖分的过程统一。梯形格网方法部分解决了传统矢量地图LOD渲染方法中因重复剖分而导致的效率低下问题,极大的提高了面状几何要素矢量渲染效率。但此方法仅适用CPU环境下二维地图面几何要素的渲染,没有考虑到投影方式对简化影响,其节点权重采用DP算法在初始化时确定,节点容差不会发生变更。梯形格网的简化算法依照梯形的上下左右关系进行判断,然而三维场景下由于旋转、俯仰等操作梯形的位置和方向发生了变更,使得其简化算法不再适用。而且此方法不支持线要素的渲染、没有GPU环境下的实现,不适用于三维场景下矢量地图LOD的渲染。
    在这里插入图片描述
    3.研究现状总结与分析
    纵观矢量地图渲染的研究现状,近年来国内外对LOD的渲染方法的研究己经取得了较大的进展,随着制图需求的日益增长已然形成了多种LOD绘制方法。分析当前矢量地图渲染方法的研究现状总结为以下几点:
    (1)现有简化方法可以有效地简化矢量几何要素,但没有考虑绘制操作。顶点剔除法在原始数据结构上进行简化,但需要进行剖分操作才可用于渲染,然而相邻层级之间的简化结果具有相似性,现有方法忽略相邻层级的相似性,冗余的剖分计算导致其绘制效率低下。边折叠和半边折叠方法不需要进行重复剖分,却不适用于矢量地图的渲染。
    (2)梯形格网渲染方法解决了重复剖分的问题且支持矢量面要素的渲染,然而没有考虑投影方式对制图简化的影响,不支持线要素的渲染且没有针对GPU环境下的实现。
    (3)梯形格网渲染方法主要是针对二维场景的实现,暂不适用于三维场景,针对透视投影下矢量地图的LOD绘制方法的研究较少。
    4. 研究目标与研究内容
    4.1 研究目标
    总结以上问题,针对现有矢量地图LOD绘制方法存在的不足,研究基于梯形格网的矢量地图动态LOD绘制方法,目的提高地图的渲染效率并用以支持三维场景下的矢量地图的渲染。本文的研究目标如下:
    (1)设计一种透视投影下的梯形格网简化算法。简化算法包含线、面梯形格网的简化算法,该算法不仅能够保证渐进格网简化方法与传统简化方法结果的一致性,还可以避免要素自身的自相交,以实现LOD绘制过程中剖分与简化的统一。
    (2)设计一种高效的地图动态LOD绘制方法。该方法依据视点相关的原则对矢量地图进行动态LOD绘制,可以支持三维场景下矢量地图的渲染。
    4.2 研究内容
    为实现以上研究目标,设计研究内容如下:
    (1)矢量地图可视化探讨与分析
    从地图学的角度研究地图渲染,以现有的地图可视化模型为基础,由动态LOD绘制流程为切入点,深入分析传统动态LOD流程中存在的问题。分析平行投影与透视投影的异同,详细探讨投影方式对地图简化的影响,研究透视投影下节点的权重计算方式。
    (2)梯形格网的构建与分析
    使用平行线推移算法和梯形剖分算法对矢量几何要素进行剖分,基于剖分结果使用梯形格网结构构建线、面梯形格网,分析梯形格网中梯形节点、梯形链与简化还原的关系,用以支持梯形格网的简化还原操作。
    (3)顾及拓扑保持的梯形格网简化算法研究
    在透视投影下,基于拓扑保持和简化结果一致性的原则,使用梯形格网结构设计顾及拓扑保持的梯形格网简化算法。
    (4)基于GPU的矢量地图LOD渲染方法研究
    基于可视化流水管线的渲染流程,为避免矢量地图动态LOD绘制流程中存在的图形重复剖分和顶点数据重传至GPU的问题,设计GPU环境下的基于梯形格网的矢量地图LOD绘制方法,充分利用GPU与可编程流水管线的特性,提高地图的渲染效率。
    5. 研究方法与技术路线
    5.1 研究方法
    (1)文献分析法
    搜集并整理国内外相关领域研究者在矢量地图LOD绘制方法取得的研究成果,总结前人的方法和方法适用范围,针对这些方法的优势和存在的不足进行分析并借鉴其优点,为本文的研究方法提供思路。
    (2)对比分析法
    进行本文方法与Mapbox矢量瓦片渲染方法在基础地图操作如:平移、缩放、俯仰、飞行的效率对比,验证本文方法的高效性。
    (3)实验验证法
    选取OSM(OpenStreetMap)线、面数据,使用提出的动态LOD绘制方法,对渲染结果和渲染效率进行实验,验证算法的高效性。
    5.2 技术路线
    根据本文的研究目标和研究内容,设计的技术路线如下图所示,包括5个阶段:
    1)准备阶段。收集并整理文献,总结分析现有LOD绘制方法的优缺点和适用性,对现有研究取得的成果进行总结归纳,从而找出本文的研究目标和研究思路。
    2)梯形格网构建阶段。从可视化的角度出发,对线,面要素进行剖分处理,针对线,面要素剖分后的图元,构建梯形格网并分析梯形格网中梯形节点、梯形链对梯形格网简化还原的影响。
    3)梯形格网简化算法设计阶段,依据前文所述梯形格网,基于拓扑保持和一致性原则设计透视投影下的梯形格网简化算法,给出详细的算法实现步骤。
    4)动态LOD绘制方法设计。在梯形格网简化算法的基础上,设计梯形格网LOD策略,同时分析地图操作对简化的影响,依据GPU可编程流水管线的原理,设计基于梯形格网的矢量地图动态LOD绘制方法。
    5)实验及评价阶段。选取OSM线,面数据,对比Mapbox矢量瓦片绘制方法,验证算法的有效性,讨论算法的适用性。
    在这里插入图片描述
    6.结语
    综上所述,本文阐述了基于三维GIS技术的矢量地图动态LOD渲染方法的研究背景和研究意义。分别从线,面要素的LOD绘制方法的研究现状进行分析,结合当前计算机硬件发展的趋势和空间信息可视化新水器的要求,依次介绍了研究目标、研究内容、研究方法以及技术路线。

    原文来自:http://www.ztmapinfo.com/blog/index.php/article/39.html

    展开全文
  • unity小地图制作和方向导航

    千次阅读 2016-08-25 17:24:59
    一:unity方向导航制作: 设计要求是方向导航随着鼠标旋转转换方向,效果图如下: 具体的实现方法主要有两个步骤,分别为UI设计和脚本编写。我的设计思路是这个控件分为两层,第一层为东西南北指示层,第二层...

    一:unity方向导航制作:
    设计要求是方向导航随着鼠标旋转转换方向,效果图如下:
    这里写图片描述这里写图片描述
    具体的实现方法主要有两个步骤,分别为UI设计和脚本编写。我的设计思路是这个控件分为两层,第一层为东西南北指示层,第二层为图标指示层,这里我的图标采用圆形图标,方向指示这里采用控制图标旋转的方式实现,层级关系如下:
    这里写图片描述
    首先创建父节点1,然后在父节点下创建子节点2,3;最后调整好位置。
    第二步脚本编写,脚本如下:

    using UnityEngine;
    using System.Collections;
    using UnityEngine.UI;
    
    public class shijiao : MonoBehaviour
    {
        public GameObject Gcanvas;
        public GameObject UIzhinanpicture;
        public GameObject Terren;
        public GameObject SMAP;
        //public GameObject bnt=GameObject.Find("Button");
        //方向灵敏度  
        public float sensitivityX = 10F;   
        public float sensitivityY = 10F;   
    
       //上下最大视角(Y视角)  
        public float minimumY = -60F;  
        public float maximumY = 60F;
        float rotationY = 0F;  
        static public bool ifcanvas;
        void Update()
        {
                    if(Input.GetMouseButton (0)){
                    //按住鼠标左键才能调节角度,根据鼠标移动的快慢(增量), 获得相机左右旋转的角度(处理X)  
                    float rotationX = transform.localEulerAngles.y + Input.GetAxis ("Mouse X") * sensitivityX;  
    
                    //根据鼠标移动的快慢(增量), 获得相机上下旋转的角度(处理Y)  
                    rotationY += Input.GetAxis ("Mouse Y") * sensitivityY;  
                    //角度限制. rotationY小于min,返回min. 大于max,返回max. 否则返回value   
                    rotationY = Mathf.Clamp (rotationY, minimumY, maximumY);  
    
                    //总体设置一下相机角度  
                    transform.localEulerAngles = new Vector3 (-rotationY, rotationX, 0);
                        UIzhinanpicture.transform.localEulerAngles = new Vector3(0,0,- rotationX);
                    }
        }
    }
    

    二:unity小地图的制作
    关于小地图的制作,网上各种帖子铺天盖地,然而仔细看却发现大部分都一样,互相抄袭,很多都是没用的。各种帖子大都采用是正交相机的方式显示小地图,然而这个地图是真实场景的俯视,我们需要的往往是像英雄联盟那样的小地图,这里我采用一种简单的方式实现小地图。废话不说先上效果图:
    这里写图片描述
    这里写图片描述
    这里的地图只是一张图片,这增加了地图的灵活性,这里的小地图创建跟上面方向导航类似,所不同的是脚本的编写方式。
    具体的实现也是分为两个步骤,分别为UI的设计和代码的编写。
    第一步:地图UI的设计
    层级关系如图:
    这里写图片描述
    父节点1为背景地图,子节点2为蓝色箭头,蓝色箭头表示目标目前所在的位置。这两个节点仅仅是图片控件。
    第二步:脚本的编写
    脚本如下:

    using UnityEngine;
    using System.Collections;
    using UnityEngine.UI;
    using System;
    using UnityEngine.EventSystems;
    
    public class shijiao : MonoBehaviour
    {
        public GameObject Gcanvas;//画布
        public GameObject UIzhinanpicture;
        public GameObject Terren;//大地
        public GameObject SMAP;//小地图指针
        public GameObject SMAPBK;//小地图背景
        GameObject Cm;
    
        //方向灵敏度  
        public float sensitivityX = 10F;   
        public float sensitivityY = 10F;   
    
       //上下最大视角(Y视角)  
        public float minimumY = -60F;  
        public float maximumY = 60F;
    
        //山地的大小
        float Twidth;
        float Tlongth;
        //地图大小
        float mapwidth;
        float maplongth;
        //比例大小
        static public float widthScale;
        static public float longthscal;
        //图片缩放比例
        //比例大小
        //static public float PwidthScale;
        //static public float Plongthscal;
    
        float rotationY = 0F;  
        static public bool ifcanvas;
        private float movespeed = 20;
        CharacterController ctrlor;
        void Start ()
        {
            RenderSettings.fog = false;
            ifcanvas =true; 
          Gcanvas.SetActive (ifcanvas);
          Cm = GameObject.Find("Mcam");
          ctrlor = GetComponent<CharacterController>();
          Twidth=Terren.GetComponent<Collider>().bounds.size.x;
          Tlongth =Terren.GetComponent<Collider>().bounds.size.z;
          mapwidth = SMAPBK.GetComponent<RectTransform>().rect.width;
          maplongth = SMAPBK.GetComponent<RectTransform>().rect.height;
            widthScale =(mapwidth) /Twidth;
            longthscal =(maplongth) /Tlongth;
            SMAP.transform.localPosition= new Vector3(Cm.transform.position.x* widthScale- 50, Cm.transform.position.z* longthscal-50,0);
        }
        void Update()
        {
            if (Input.GetMouseButton (1)) {
    
                ifcanvas = true;
                Gcanvas.SetActive (ifcanvas);
                }
                else{
                if (Input.GetKey(KeyCode.Escape))
                {               
                    ifcanvas = false;
                    Gcanvas.SetActive (ifcanvas);
                }
                if (!EventSystem.current.IsPointerOverGameObject())
                {
                    //W键前进
                    if (Input.GetKey (KeyCode.W)) {
                        Vector3 forward = transform.TransformDirection(Vector3.forward);
                        ctrlor.Move(forward*movespeed*Time.deltaTime);
    
                    }
                    //S键后退
                    if (Input.GetKey(KeyCode.S))
                    {
                        Vector3 back = transform.TransformDirection(Vector3.back);
                        ctrlor.Move(back * movespeed * Time.deltaTime);
    
                    }
                    //A键移动
                    if (Input.GetKey(KeyCode.A))
                    {
                        Vector3 left = transform.TransformDirection(Vector3.left);
                        ctrlor.Move(left* movespeed * Time.deltaTime);
                    }
                    //D键后退
                    if (Input.GetKey(KeyCode.D) && gameObject.transform.position.y > 0)
                    {
                        Vector3 right = transform.TransformDirection(Vector3.right);
                        ctrlor.Move(right * movespeed * Time.deltaTime);
                    }
                    //E键升高
                    if (Input.GetKey (KeyCode.E)) {
                        Vector3 upward = transform.TransformDirection(Vector3.up);
                        ctrlor.Move(upward * movespeed * Time.deltaTime);
                    }
                    SMAP.transform.localPosition = new Vector3(Cm.transform.position.x * widthScale - 50, Cm.transform.position.z * longthscal - 50, 0);
                    if (Input.GetMouseButton (0)){
                    //根据鼠标移动的快慢(增量), 获得相机左右旋转的角度(处理X)  
                    float rotationX = transform.localEulerAngles.y + Input.GetAxis ("Mouse X") * sensitivityX;  
    
                    //根据鼠标移动的快慢(增量), 获得相机上下旋转的角度(处理Y)  
                    rotationY += Input.GetAxis ("Mouse Y") * sensitivityY;  
                    //角度限制. rotationY小于min,返回min. 大于max,返回max. 否则返回value   
                    rotationY = Mathf.Clamp (rotationY, minimumY, maximumY);  
    
                    //总体设置一下相机角度  
                    transform.localEulerAngles = new Vector3 (-rotationY, rotationX, 0);
                        UIzhinanpicture.transform.localEulerAngles = new Vector3(0,0,- rotationX);
                        SMAP.transform.localEulerAngles = new Vector3(0, 0, -rotationX);
                    }
                }
                }
    
        }
    }
    
    展开全文
  • 地图学(复习)

    千次阅读 多人点赞 2020-11-26 10:43:58
    本博文用于复习课程《地图学》,同时用于帮助有需要的朋友。 课程使用的教材是《地图学》,胡圣武,清华大学出版社,北京交通大学出版社。 博文中只涉及课程要求内容,更多详细内容可见教材。
  • 把地面事物的位置表达在二维平面多种方法,古代的风景绘画、现代的摄影技术均可以在一定程度反映出地物的相对位置,但是这些方法最大的问题是没有数学法则支撑,无法进行方位测量、距离量算等空间分析。...
  • 位姿图优化的示意图如图所示,蓝色节点是车辆在特定时间的状态s,其中包含位置p和方向q,用四元数q来表示方向,R(q)表示将四元数转换为旋转矩阵,有两边,蓝边表示GNSS约束,它只存在于GNSS信号好的情况,它只...
  • 今天我们来谈下百度地图的定位功能,在此之前我已经将百度地图的...今天所讲的百度地图所涉及的内容主要有:基本定位的实现,自定义定位图标,结合方向传感器定位,选择定位中的几模式(罗盘模式,普通模式,跟...
  • 根据坐标在地图上显示指定点,并给出点的具体地址
  • 03 第地图投影原理与方位投影 04 第四章 地图投影与投影变换 05 第五章 地图信息源及处理 06 第六章 地图符号设计 07 第七章 地图图形、色彩设计及注记表达 08 普通地图内容(自然要素)表示方法 09 第九章 ...
  • 本文主要内容一、分析目的及数据源简介二、数据展示1、展示流出流入数据方向2、展示流入人口总量3、使用网络图揭秘不同省份之间的关系、本节新知识点小结 一、分析目的及数据源简介 本案例可以直观地看出,我国...
  • 经纬度可以用来表示的某一个点 方位角是,以某一位为原点,顺时针转到目标位置的角度,是一个平面角。 理论经纬度与方位角不能互换,应为有高度的存在,但实际, 将地球视为一个球体,以墨卡托投影法投影到...
  • 常用地图投影

    万次阅读 2020-03-11 11:04:14
    区域图投影 指除世界地图之外的半球图、大洲图、国家图、省区图、地区图,即含区域比较大的中小比例尺地图。 圆锥投影 ...设想用一个圆锥套在地球椭球体,而把地球椭球经纬网投影到圆锥面上,然后沿...
  • 举个例子 如上图所示 比如人物向右移动,如果地图贴在屏幕左边边界 将先移动人物在地图的坐标,当人物在屏幕中超过分之二后 则将地图向人物行走的反方向移动给玩家一人物还在向右移动的假象,其实这时候人物只是...
  • 坐标点地图匹配方法

    千次阅读 热门讨论 2018-04-26 09:18:44
    坐标点地图匹配方法 例如在上图中有个点不在轨迹,也不在道路,本文将通过计算的方法给它找到附近最近的道路的点。 1.2.绑路方法 绑路的方法主要分为以下几个步骤: 1、获取路网数...
  • // 设置定位的类型为定位模式 ,可以由定位、跟随或地图根据面向方向旋转几 mAMap.setMyLocationType(AMap.LOCATION_TYPE_LOCATE); } /** * 方法必须重写 */ @Override protected void onResume() { ...
  • GIS 地图坐标系相互转换的方法学习笔记 一,前言 GIS中有很多不同的坐标系,当数据在不同的坐标系下显示的时候,就要把数据从数据本身的坐标系转换到当前当前地图显示的坐标系。 二,GIS坐标系背景 1、基本概念 地球...
  • //方向变化 bool in(int x, int y) {//确保在地图里面 return 0 <= x && x < n && 0 <= y && y < m; } struct node{//定义node类型的结构体 int x,y,d;//d表示路径 node(int...
  • 绝大多数整车制造商都认为高清地图是自动驾驶技术实现的最重要一环之一。 相信许多人对现在所用的普通精度的汽车导航地图(standard definition, SD)有深刻的认识。无论是十字路口直走就可以却让你右拐调头再右拐...
  • 打开天龙2场景地图,会有一个小箭头的图片,代表人物位置和方向方向的做法是: 1 生成360度方向的一些图片(数量可根据情况而定) 2 计算角色的方向,从第一步生成的图片里面取一张,贴到UI,就可以代表角色的...
  • 使用高德地图在很多时候需要在地图上标记位置,并且很多时候需要用到自定义的图标去完成这种位置的标记。 当然,这些功能高德地图都为我们准备了,比如常用的地图覆盖物Marker和信息窗体等。这里就先说一下点标记的...
  • 移动机器人定位与地图创建(SLAM)方法

    万次阅读 多人点赞 2016-04-22 16:14:43
    自主移动机器人同时定位与地图创建(SLAM)方法 1.引言: 机器人的研究越来越多的得到关注和投入,随着计算机技术和人工智能的发展,智能自主移动机器人成为机器人领域的一个重要研究方向和研究热点。移动机器人的...
  • 今天所讲的百度地图所涉及的内容主要有:基本定位的实现,自定义定位图标,结合方向传感器定位,选择定位中的几模式(罗盘模式,普通模式,跟随模式)。 一、基本定位的实现: 所谓定位无非就是获取到一个
  • 百度地图地图API(常用)

    千次阅读 2020-01-05 18:58:27
    百度地图开发常用网站 1、百度地图开放平台 http://lbsyun.baidu.com/ 2、百度地图Javascript API JavaScript API v3.0http://lbsyun.baidu.com/index.php?title=jspopular3.0 JavaScript API v2.0...
  • 背景:公司想要做一个基于百度地图实时展示车的运行轨迹,且在运行过程中需要车头方向随着角度进行变化。 1.先把地图构建出来,然后造一组数据用以画线。 数据格式为: var PointArr = [ {long: 117.128937 ,lat:...
  • 知环境中定位自身方位并同时构建环境地图, 从而保证叠加的虚拟物体与现实场景在几何的一致性. 文中首 先简述基于视觉的同时定位与地图构建的基本原理; 然后介绍几个代表性的基于单目视...
  • 一篇:Android 天气APP(二十)增加灾害预警、优化主页面UI 前言 之前也看过和风天气自己做的APP,主页面的地图点击之后,定位到某一个点,然后查看这个地方的天气,实际思路还是通过区县来查询天气的,只不过,...
  • SLAM中的混合地图表达

    千次阅读 2017-03-08 11:02:34
    SLAM中的混合地图表达方式SLAM的地图类型混合地图有哪些表达形式总结SLAM地图类型介绍地图的表现形式,很大程度取决于当前的任务,传感器还有就是环境类型,具体可以如下图所示: 单一的地图类型主要由以下集中...
  • ***转载、引用请标明出处***http://www.jianshu.com/p/29ccac3e1e42本文出自[zhh_happig的简书博客](http://www.jianshu.com/u/d82bd37b1d29),谢谢[Android百度地图(二):百度地图sdk显示位置点、图层绘制]...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 44,153
精华内容 17,661
关键字:

地图上表示方向的三种方法