跟二维地图原理一样,只不过搜索方向多了,二维只搜8个方向,而三维要搜26个方向。

不懂的看我以前写的文章,这里直接贴代码:

  1. #include <iostream>
  2. #include <cstring>
  3. #include <algorithm>
  4. #include <windows.h>
  5. #include <cmath>
  6. #include <list>
  7. #include <cstdio>
  8.  
  9. using namespace std;
  10.  
  11. const double LEN=10;
  12. const int MAX=500;
  13. const char ROAD='*';
  14. const char WALL='#';
  15. const char START='0';
  16. const char STOP='1';
  17.  
  18. typedef struct node
  19. {
  20. node()
  21. {
  22. x=y=z=0;
  23. f=g=h=0;
  24. parent=NULL;
  25. }
  26. int x,y,z;
  27. double f,g,h;
  28. struct node *parent;
  29. } Node;
  30.  
  31. char mmap[MAX][MAX][MAX]; //地图
  32. list<Node*> startList,stopList; //开启列表和关闭列表
  33.  
  34. int sx,sy,sz,ex,ey,ez; //起点坐标(sx,sy,sz)和终点坐标(ex,ey,ez)
  35. int k,n,m; //高度k,m行n列
  36.  
  37. //26个方向,三阶魔方模型自己想象一下
  38. int dx[26]= {-1,1,0,0,-1,1,-1,1,0,-1,1,0,0,-1,1,-1,1,0,-1,1,0,0,-1,1,-1,1};
  39. int dy[26]= {0,0,-1,1,-1,-1,1,1,0,0,0,-1,1,-1,-1,1,1,0,0,0,-1,1,-1,-1,1,1};
  40. int dz[26]= {0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
  41.  
  42. //计算两点距离
  43. double getDis(int x1,int y1,int z1,int x2,int y2,int z2)
  44. {
  45. double xx1=x1*LEN+LEN/2.0; //获取中心点坐标
  46. double yy1=y1*LEN+LEN/2.0;
  47. double zz1=z1*LEN+LEN/2.0;
  48.  
  49. double xx2=x2*LEN+LEN/2.0;
  50. double yy2=y2*LEN+LEN/2.0;
  51. double zz2=z2*LEN+LEN/2.0;
  52.  
  53. return sqrt((xx1-xx2)*(xx1-xx2)+(yy1-yy2)*(yy1-yy2)+(zz1-zz2)*(zz1-zz2));
  54. }
  55.  
  56. //判断节点是否在列表中
  57. bool in_List(Node *pnode,list<Node*> mlist)
  58. {
  59. for(list<Node*>::iterator it=mlist.begin(); it!=mlist.end(); it++)
  60. {
  61. if(pnode->x==(*it)->x&&pnode->y==(*it)->y&&pnode->z==(*it)->z)
  62. return true;
  63. }
  64. return false;
  65. }
  66.  
  67. //从列表中删除节点
  68. bool del(Node *pnode,list<Node*> &mlist)
  69. {
  70. for(list<Node*>::iterator it=mlist.begin(); it!=mlist.end(); it++)
  71. {
  72. if(pnode==(*it))
  73. {
  74. mlist.erase(it);
  75. return true;
  76. }
  77. }
  78. return false;
  79. }
  80.  
  81. //向列表中添加节点
  82. void add(Node *pnode,list<Node*> &mlist)
  83. {
  84. mlist.push_back(pnode);
  85. return;
  86. }
  87.  
  88. //从列表中获取f最小的节点
  89. Node* getMin(list<Node*> mlist)
  90. {
  91. double mmin=100000000;
  92. Node *temp=NULL;
  93. for(list<Node*>::iterator it=mlist.begin(); it!=mlist.end(); it++)
  94. {
  95. if((*it)->f<mmin)
  96. {
  97. mmin=(*it)->f;
  98. temp=(*it);
  99. }
  100. }
  101. return temp;
  102. }
  103.  
  104. //设置路径
  105. void setRoad(Node *root)
  106. {
  107. while(root->parent!=NULL)
  108. {
  109. if(root->x==ex&&root->y==ey&&root->z==ez)
  110. {
  111. mmap[root->z][root->x][root->y]=STOP;
  112. }
  113. else
  114. mmap[root->z][root->x][root->y]=ROAD;
  115. root=root->parent;
  116. }
  117. }
  118.  
  119. void printRoad()
  120. {
  121. for(int kk=0; kk<k; kk++)
  122. {
  123. for(int i=0; i<m; i++)
  124. {
  125. for(int j=0; j<n; j++)
  126. {
  127. if(mmap[kk][i][j]==ROAD||mmap[kk][i][j]==START||mmap[kk][i][j]==STOP)
  128. {
  129. SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN);
  130. cout<<mmap[kk][i][j]<<" ";
  131. }
  132. else
  133. {
  134. SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY);
  135. cout<<mmap[kk][i][j]<<" ";
  136. }
  137. }
  138. cout<<endl;
  139. }
  140. cout<<endl<<endl;
  141. }
  142. cout<<endl<<endl<<endl;
  143. SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY);
  144. }
  145.  
  146. //搜索
  147. void bfs()
  148. {
  149. startList.clear();
  150. stopList.clear();
  151. Node *preNode = new Node;
  152. preNode->x=sx;
  153. preNode->y=sy;
  154. preNode->z=sz;
  155. preNode->g=0;
  156. preNode->h=getDis(sx,sy,sz,ex,ey,ez);
  157. preNode->f=preNode->g+preNode->h;
  158. preNode->parent=NULL;
  159. add(preNode,startList);
  160. while(!startList.empty())
  161. {
  162. //cout<<"-.-"<<endl;
  163. preNode=getMin(startList);
  164. if(preNode==NULL)
  165. {
  166. cout<<"自动寻路失败"<<endl;
  167. return;
  168. }
  169. del(preNode,startList);
  170. add(preNode,stopList);
  171. for(int d=0; d<26; d++)
  172. {
  173. int cx=preNode->x+dx[d];
  174. int cy=preNode->y+dy[d];
  175. int cz=preNode->z+dz[d];
  176.  
  177. Node *curNode=new Node;
  178. curNode->x=cx;
  179. curNode->y=cy;
  180. curNode->z=cz;
  181. curNode->g=preNode->g+getDis(cx,cy,cz,preNode->x,preNode->y,preNode->z);
  182. curNode->h=getDis(cx,cy,cz,ex,ey,ez);
  183. curNode->f=curNode->g+curNode->h;
  184. curNode->parent=preNode;
  185.  
  186. if(cx<0||cy<0||cz<0||cx>=m||cy>=n||cz>=k) continue; //越界 或碰墙
  187. else if(mmap[cz][cx][cy]==WALL) continue;
  188. else if(in_List(curNode,startList)||in_List(curNode,stopList)) continue; //在开启或关闭列表
  189.  
  190. if(cx==ex&&cy==ey&&cz==ez)
  191. {
  192. setRoad(curNode);
  193. printRoad();
  194. return;
  195. }
  196. add(curNode,startList);
  197. }
  198. }
  199. cout<<"自动寻路失败"<<endl;
  200. return;
  201. }
  202.  
  203. int main()
  204. {
  205. while(cin>>k>>m>>n)
  206. {
  207. if(k==0||n==0||m==0) break;
  208. for(int kk=0; kk<k; kk++)
  209. {
  210. for(int i=0; i<m; i++)
  211. {
  212. for(int j=0; j<n; j++)
  213. {
  214. cin>>mmap[kk][i][j];
  215. if(mmap[kk][i][j]==START)
  216. {
  217. sx=i,sy=j,sz=kk;
  218. }
  219. if(mmap[kk][i][j]==STOP)
  220. {
  221. ex=i,ey=j,ez=kk;
  222. }
  223. }
  224. }
  225. }
  226. bfs();
  227. //printRoad();
  228.  
  229. }
  230. return 0;
  231. }

  测试样例:

  1. ````#```
  2. ``###```
  3. ``###```
  4. ``#`````
  5. ``#`##``
  6. ``#`#``#
  7. `##`#``#
  8. `###`##`
  9. `##`##`
  10. ####`#``
  11.  
  12. ````#```
  13. ``#`#```
  14. ``#`#```
  15. ``#`````
  16. ``#`##``
  17. ``#`#``#
  18. `##`#`##
  19. `###`##`
  20. ``##`##`
  21. ####`#``
  22.  
  23. ````#```
  24. ``#`#```
  25. ``#`#```
  26. ``#`````
  27. ``#`##``
  28. ``#`#``#
  29. `##`#``#
  30. `###`##`
  31. ``#``##`
  32. ####`#`

输出结果:

三维地图中的A*寻路的更多相关文章

  1. eCharts二三维地图总结

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 最近多个项目中的登录页面陆续提出了不少地图需求,主要围绕地图的 ...

  2. 【三维地图】开发攻略 —— 详解“GeoJSON”技术和应用场景

    GeoJSON ,一个用于存储地理信息的数据格式.GoeJSON对象可以表示几何.特征或特征集合,支持:点.线.面.多点.多线.多面和几何集合.在基于平面地图,三维地图中都需要用到的一种数据类型. 由 ...

  3. 如何在Cocos2D游戏中实现A*寻路算法(一)

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交流 ...

  4. 使用ESMap的地图平台开发三维地图

      本文简单的介绍使用ESmap的SDK开发(DIY自己地图的)一个地图的过程.若有不足,欢迎指正. 一.创建地图 只需四步,从无到有,在浏览器中创建一个自己的三维地图,炫酷到爆! 第一步:引入ESM ...

  5. 如何使用JS来开发室内三维地图的轨迹回放功能

     在制作完成室内三维地图的功能后,最经常有的需求就是如何做人员的轨迹回放,一般流程都是从数据库中查询轨迹坐标后,经过后台查询接口返回给前端,接下来的事情都交给JS来完成. 如果想做好一个性能好的轨迹回 ...

  6. SkylineGlobe 7.0.1 & 7.0.2版本Web开发 如何正确使用三维地图控件和工程树控件

    Skyline TerraExplorer Pro目前正式发布的7.0.1&7.0.2版本,还只是64位的版本, 在Web开发的时候,如何在页面中正确嵌入三维地图控件,让一些小伙伴凌乱了. 下 ...

  7. 如何屏蔽SkylineGlobe提供的三维地图控件上的快捷键

    SkyllineGlobe提供的 <OBJECT ID=" TerraExplorer3DWindow" CLASSID="CLSID:3a4f9192-65a8- ...

  8. 使用EXCEL绘制三维地图(超简单的五分钟绘制地图方法,妈妈再也不用担心我不会画地图啦~)

    博主为从区域规划转行地图学的小学渣一枚,最近处理数据希望对结果进行三维可视化,意外发现从小用到大的EXCEL可以绘制地图且功能非常强大,在这里做一下简单介绍,希望可以给看官提供些许帮助.那下面就开始吧 ...

  9. [GitHub开源]基于HTML5实现的轻量级Google Earth三维地图引擎,带你畅游世界 【转】

    http://blog.csdn.net/iispring/article/details/52679185 WebGlobe HTML5基于原生WebGL实现的轻量级Google Earth三维地图 ...

随机推荐

  1. 如何使用qtp12 utf进行功能测试

    首先,按照本博客的安装教程走的,右键管理员运行 接下来点击继续,这个界面只需要勾选到web即可 点击ok,开始运行 进入到主界面之后,file新建一个测试. 可以修改路径等等 点击create之后,出 ...

  2. Number Puzzle

    Number Puzzle Time Limit: 2 Seconds      Memory Limit: 65536 KB Given a list of integers (A1, A2, .. ...

  3. 第五节、矩阵分解之LU分解

    一.A的LU分解:A=LU 我们之前探讨过矩阵消元,当时我们通过EA=U将A消元得到了U,这一节,我们从另一个角度分析A与U的关系 假设A是非奇异矩阵且消元过程中没有行交换,我们便可以将矩阵消元的EA ...

  4. axios 全攻略之基本介绍与使用(GET 与 POST)

    axios axios 是一个基于 Promise 的 HTTP 客户端,专门为浏览器和 node.js 服务 Vue 2.0 官方推荐使用 axios 来代替原来的 Vue request,所以这里 ...

  5. android 软键盘的显示与隐藏问题的研究

    在android中,常常会和输入法的软件键盘交互.在Manifest文件中,系统给activity的一个属性-windowSoftInputMode来控制输入法的显示方式. 该属性提供了Activit ...

  6. HDU 3662

    求的是凸包有多少个面. 注意,求的是面.这就需要把同一个面的三角形合并.只需判断两个三角形的法向量是否同向平行. /* 增量法求凸包.选取一个四面体,同时把它各面的方向向量向外,增加一个点时,若该点与 ...

  7. Thread和ThreadGroup

    Thread和ThreadGroup 学习了:https://www.cnblogs.com/yiwangzhibujian/p/6212104.html  这个里面有Thread的基本内容: htt ...

  8. 关于PHP浮点数之 intval((0.1+0.7)*10) 为什么是7

    PHP是一种弱类型语言, 这样的特性, 必然要求有无缝透明的隐式类型转换, PHP内部使用zval来保存任意类型的数值, zval的结构如下(5.2为例): struct _zval_struct { ...

  9. Codeforces Beta Round #95 (Div. 2) D. Subway 边双联通+spfa

    D. Subway   A subway scheme, classic for all Berland cities is represented by a set of n stations co ...

  10. luogu3942 将军令 贪心

    题目大意:给你一个地图(树),共有1~n个驿站(点),编号分别为1~n,告诉你第ui个驿站与第vi个驿站有一条长度为1的路(边),每个小队(可以放在任意驿站上)最多有k的覆盖长度,问最多要放置多少个小 ...