三维地图中的A*寻路
跟二维地图原理一样,只不过搜索方向多了,二维只搜8个方向,而三维要搜26个方向。
不懂的看我以前写的文章,这里直接贴代码:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <windows.h>
#include <cmath>
#include <list>
#include <cstdio> using namespace std; const double LEN=10;
const int MAX=500;
const char ROAD='*';
const char WALL='#';
const char START='0';
const char STOP='1'; typedef struct node
{
node()
{
x=y=z=0;
f=g=h=0;
parent=NULL;
}
int x,y,z;
double f,g,h;
struct node *parent;
} Node; char mmap[MAX][MAX][MAX]; //地图
list<Node*> startList,stopList; //开启列表和关闭列表 int sx,sy,sz,ex,ey,ez; //起点坐标(sx,sy,sz)和终点坐标(ex,ey,ez)
int k,n,m; //高度k,m行n列 //26个方向,三阶魔方模型自己想象一下
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};
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};
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}; //计算两点距离
double getDis(int x1,int y1,int z1,int x2,int y2,int z2)
{
double xx1=x1*LEN+LEN/2.0; //获取中心点坐标
double yy1=y1*LEN+LEN/2.0;
double zz1=z1*LEN+LEN/2.0; double xx2=x2*LEN+LEN/2.0;
double yy2=y2*LEN+LEN/2.0;
double zz2=z2*LEN+LEN/2.0; return sqrt((xx1-xx2)*(xx1-xx2)+(yy1-yy2)*(yy1-yy2)+(zz1-zz2)*(zz1-zz2));
} //判断节点是否在列表中
bool in_List(Node *pnode,list<Node*> mlist)
{
for(list<Node*>::iterator it=mlist.begin(); it!=mlist.end(); it++)
{
if(pnode->x==(*it)->x&&pnode->y==(*it)->y&&pnode->z==(*it)->z)
return true;
}
return false;
} //从列表中删除节点
bool del(Node *pnode,list<Node*> &mlist)
{
for(list<Node*>::iterator it=mlist.begin(); it!=mlist.end(); it++)
{
if(pnode==(*it))
{
mlist.erase(it);
return true;
}
}
return false;
} //向列表中添加节点
void add(Node *pnode,list<Node*> &mlist)
{
mlist.push_back(pnode);
return;
} //从列表中获取f最小的节点
Node* getMin(list<Node*> mlist)
{
double mmin=100000000;
Node *temp=NULL;
for(list<Node*>::iterator it=mlist.begin(); it!=mlist.end(); it++)
{
if((*it)->f<mmin)
{
mmin=(*it)->f;
temp=(*it);
}
}
return temp;
} //设置路径
void setRoad(Node *root)
{
while(root->parent!=NULL)
{
if(root->x==ex&&root->y==ey&&root->z==ez)
{
mmap[root->z][root->x][root->y]=STOP;
}
else
mmap[root->z][root->x][root->y]=ROAD;
root=root->parent;
}
} void printRoad()
{
for(int kk=0; kk<k; kk++)
{
for(int i=0; i<m; i++)
{
for(int j=0; j<n; j++)
{
if(mmap[kk][i][j]==ROAD||mmap[kk][i][j]==START||mmap[kk][i][j]==STOP)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN);
cout<<mmap[kk][i][j]<<" ";
}
else
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY);
cout<<mmap[kk][i][j]<<" ";
}
}
cout<<endl;
}
cout<<endl<<endl;
}
cout<<endl<<endl<<endl;
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY);
} //搜索
void bfs()
{
startList.clear();
stopList.clear();
Node *preNode = new Node;
preNode->x=sx;
preNode->y=sy;
preNode->z=sz;
preNode->g=0;
preNode->h=getDis(sx,sy,sz,ex,ey,ez);
preNode->f=preNode->g+preNode->h;
preNode->parent=NULL;
add(preNode,startList);
while(!startList.empty())
{
//cout<<"-.-"<<endl;
preNode=getMin(startList);
if(preNode==NULL)
{
cout<<"自动寻路失败"<<endl;
return;
}
del(preNode,startList);
add(preNode,stopList);
for(int d=0; d<26; d++)
{
int cx=preNode->x+dx[d];
int cy=preNode->y+dy[d];
int cz=preNode->z+dz[d]; Node *curNode=new Node;
curNode->x=cx;
curNode->y=cy;
curNode->z=cz;
curNode->g=preNode->g+getDis(cx,cy,cz,preNode->x,preNode->y,preNode->z);
curNode->h=getDis(cx,cy,cz,ex,ey,ez);
curNode->f=curNode->g+curNode->h;
curNode->parent=preNode; if(cx<0||cy<0||cz<0||cx>=m||cy>=n||cz>=k) continue; //越界 或碰墙
else if(mmap[cz][cx][cy]==WALL) continue;
else if(in_List(curNode,startList)||in_List(curNode,stopList)) continue; //在开启或关闭列表 if(cx==ex&&cy==ey&&cz==ez)
{
setRoad(curNode);
printRoad();
return;
}
add(curNode,startList);
}
}
cout<<"自动寻路失败"<<endl;
return;
} int main()
{
while(cin>>k>>m>>n)
{
if(k==0||n==0||m==0) break;
for(int kk=0; kk<k; kk++)
{
for(int i=0; i<m; i++)
{
for(int j=0; j<n; j++)
{
cin>>mmap[kk][i][j];
if(mmap[kk][i][j]==START)
{
sx=i,sy=j,sz=kk;
}
if(mmap[kk][i][j]==STOP)
{
ex=i,ey=j,ez=kk;
}
}
}
}
bfs();
//printRoad(); }
return 0;
}
测试样例:
````#```
``###```
``###```
``#`````
``#`##``
``#`#``#
`##`#``#
`###`##`
`##`##`
####`#`` ````#```
``#`#```
``#`#```
``#`````
``#`##``
``#`#``#
`##`#`##
`###`##`
``##`##`
####`#`` ````#```
``#`#```
``#`#```
``#`````
``#`##``
``#`#``#
`##`#``#
`###`##`
``#``##`
####`#`
输出结果:
三维地图中的A*寻路的更多相关文章
- eCharts二三维地图总结
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 最近多个项目中的登录页面陆续提出了不少地图需求,主要围绕地图的 ...
- 【三维地图】开发攻略 —— 详解“GeoJSON”技术和应用场景
GeoJSON ,一个用于存储地理信息的数据格式.GoeJSON对象可以表示几何.特征或特征集合,支持:点.线.面.多点.多线.多面和几何集合.在基于平面地图,三维地图中都需要用到的一种数据类型. 由 ...
- 如何在Cocos2D游戏中实现A*寻路算法(一)
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交流 ...
- 使用ESMap的地图平台开发三维地图
本文简单的介绍使用ESmap的SDK开发(DIY自己地图的)一个地图的过程.若有不足,欢迎指正. 一.创建地图 只需四步,从无到有,在浏览器中创建一个自己的三维地图,炫酷到爆! 第一步:引入ESM ...
- 如何使用JS来开发室内三维地图的轨迹回放功能
在制作完成室内三维地图的功能后,最经常有的需求就是如何做人员的轨迹回放,一般流程都是从数据库中查询轨迹坐标后,经过后台查询接口返回给前端,接下来的事情都交给JS来完成. 如果想做好一个性能好的轨迹回 ...
- SkylineGlobe 7.0.1 & 7.0.2版本Web开发 如何正确使用三维地图控件和工程树控件
Skyline TerraExplorer Pro目前正式发布的7.0.1&7.0.2版本,还只是64位的版本, 在Web开发的时候,如何在页面中正确嵌入三维地图控件,让一些小伙伴凌乱了. 下 ...
- 如何屏蔽SkylineGlobe提供的三维地图控件上的快捷键
SkyllineGlobe提供的 <OBJECT ID=" TerraExplorer3DWindow" CLASSID="CLSID:3a4f9192-65a8- ...
- 使用EXCEL绘制三维地图(超简单的五分钟绘制地图方法,妈妈再也不用担心我不会画地图啦~)
博主为从区域规划转行地图学的小学渣一枚,最近处理数据希望对结果进行三维可视化,意外发现从小用到大的EXCEL可以绘制地图且功能非常强大,在这里做一下简单介绍,希望可以给看官提供些许帮助.那下面就开始吧 ...
- [GitHub开源]基于HTML5实现的轻量级Google Earth三维地图引擎,带你畅游世界 【转】
http://blog.csdn.net/iispring/article/details/52679185 WebGlobe HTML5基于原生WebGL实现的轻量级Google Earth三维地图 ...
随机推荐
- JavaScript基础的记录
一.JavaScript的六种基本类型: 基本数据类型: String.Number.Boolean.Null.Undefined 引用数据类型: Object 二.强制类型转换: 主要指将其他的数据 ...
- (37)Spring Boot集成EHCache实现缓存机制【从零开始学Spring Boot】
[本文章是否对你有用以及是否有好的建议,请留言] 写后感:博主写这么一系列文章也不容易啊,请评论支持下. 如果看过我之前(35)的文章这一篇的文章就会很简单,没有什么挑战性了. 那么我们先说说这一篇文 ...
- [bzoj1180][CROATIAN2009]OTOCI_LCT
OTOCI bzoj-1180 CROATIAN-2009 题目大意:给你n个离散的点,m个操作.支持:两点加边(保证还是森林),修改单点权值,询问两点是否联通,查询联通两点之间路径权值. 注释:$1 ...
- HDU 4506
EASY题,快速幂... #include <iostream> #include <cstdio> #include <cstring> #include < ...
- POJ1789&ZOJ2158--Truck History【最小生成树变形】
链接:http://poj.org/problem?id=1789 题意:卡车公司有悠久的历史,它的每一种卡车都有一个唯一的字符串来表示,长度为7,它的全部卡车(除了第一辆)都是由曾经的卡车派生出来的 ...
- 金融扫盲-资本市场从天使轮、ABCD轮、风投、到上市圈钱、借壳上市。
转载请标明出处:http://blog.csdn.net/hu948162999/article/details/47777859 对于金融知识零基础的人进行扫盲,故事浅显易懂.趣味性强. 来之知乎. ...
- sikuli运行错误:Traceback (most recent call last):
错误信息: Traceback (most recent call last): File "C:\Users\wb-cailu.a\AppData\Local\Temp\sikuli-tm ...
- JavaScript大数组如何根据对象的key快速找到并删除
查找:上代码. function isBigEnough(element) { return element >= 15; } var ret1 = [12, 5, 8, 130, 44].fi ...
- 国王的烦恼---nyoj
国王的烦恼 时间限制:3000 ms | 内存限制:65535 KB 难度:2 描述 C国由n个小岛组成,为了方便小岛之间联络,C国在小岛间建立了m座大桥,每座大桥连接两座小岛.两个小岛间可能存在 ...
- Node.js:Strea
ylbtech-Node.js:Stream 1.返回顶部 1. Node.js Stream(流) Stream 是一个抽象接口,Node 中有很多对象实现了这个接口.例如,对http 服务器发起请 ...