如何在MONO 3D寻找最短路路径
前段时间有个客户说他们想在我们的3D的机房中找从A点到B点的最短路径,然而在2D中确实有很多成熟的寻路算法,其中A*是最为常见的,而这个Demo也是用的A*算法,以下计算的是从左上角到右下角的最短路径:
具体的实现方式是,先将地板进行了分割,分成一个数组,然后再计算该点上是否有3D的对象,若是有,就置成该点不能通过的标记,否则就表示该点可以通过(如果你分割的越细那么算的就越精确,但是算的当然也就慢一些,关键看你的要求),以下是分割地板的代码:
var size = {x: 100, y: 100}; // 100*100
var topLeft = {x: 228, y: 53};
var width = 524;
var height = 400;
var dw = width / size.x;
var dh = height / size.y;
var start;
var end;
var graph;
function to2d() {
var nodes = [];
for (var i = 0; i < size.x; i++) {
var nodeRow = [];
var x = topLeft.x + dw * i
for (var j = 0; j < size.y; j++) {
var y = topLeft.y + dh * j;
if (isHasObj(x, y)) { //判断该点上是否有物体
nodeRow.push(0);
} else {
nodeRow.push(1);
}
}
nodes.push(nodeRow);
}
graph = new Graph(nodes, {
closest: null,
diagonal: false
});
//这里是找一条从(0,0)到(79,80)的路径。
start = graph.grid[0][0];
drawPath(79, 80);
}
分割好地板后就相当于将3D中的寻路转换成了2D中的寻路,此时就可以直接使用A*算法来进行寻路了,这里的A*寻路算法如下:
function search(graph, start, end, options) {
astar.init(graph);
options = options || {};
var heuristic = options.heuristic || astar.heuristics.manhattan,
closest = options.closest || false;
var openHeap = getHeap(),
closestNode = start; // set the start node to be the closest if required
start.h = heuristic(start, end);
openHeap.push(start);
while(openHeap.size() > 0) {
var currentNode = openHeap.pop();
if(currentNode === end) {
return pathTo(currentNode);
}
// Normal case -- move currentNode from open to closed, process each of its neighbors.
currentNode.closed = true;
// Find all neighbors for the current node.
var neighbors = graph.neighbors(currentNode);
for (var i = 0, il = neighbors.length; i < il; ++i) {
var neighbor = neighbors[i];
if (neighbor.closed || neighbor.isWall()) {
// Not a valid node to process, skip to next neighbor.
continue;
}
var gScore = currentNode.g + neighbor.getCost(currentNode),
beenVisited = neighbor.visited;
if (!beenVisited || gScore < neighbor.g) {
neighbor.visited = true;
neighbor.parent = currentNode;
neighbor.h = neighbor.h || heuristic(neighbor, end);
neighbor.g = gScore;
neighbor.f = neighbor.g + neighbor.h;
if (closest) {
if (neighbor.h < closestNode.h || (neighbor.h === closestNode.h && neighbor.g < closestNode.g)) {
closestNode = neighbor;
}
}
if (!beenVisited) {
// Pushing to heap will put it in proper place based on the 'f' value.
openHeap.push(neighbor);
}
else {
openHeap.rescoreElement(neighbor);
}
}
}
}
if (closest) {
return pathTo(closestNode);
}
return [];
}
看似实现了,如果你细心的话,你可以会发现在3D中存在类似像门那样的可以穿过的物体,或者说有两层楼,那这就不好转换了,确实是存在这样的问题,但是我们可以改进isHasObj这个方法,假如我们寻路的是一个人的话,那么我们人是有高度的,设置高度为man.height,我们判断某点上是否存在物体的话,然后在该点上“发射”一条Ray的方式(具体实现牵涉到一些数学知识,这里不多讲,下次可以单独弄了blog讲解),然后会返回的参数中有一个“距离”的属性,该属性就是我们地板上的点到该点上面那个物体的距离,因此我们可以通过这个距离来和man的身高的关系来确定该点是否可以通过,代码如下:
function isHasObj(x, y) {
var obj = getElementsByPosition(x, y);
if (obj && obj.length > 1) { //length > 1, bc is must a obj that is shapenode
for (var i = 0; i < obj.length; i++) {
if (obj[i] && !(obj[i].element instanceof mono.ShapeNode) && obj[i].element != man) {
if (isCheckHeight) {
console.log("x:" + x + ";y:" + y + ";distance:" + obj[i].distance);
if (obj[i].distance < (man.height + 10)) {
return true;
} else {
return false;
}
} else {
return true;
}
}
}
}
return false;
}
如下是通过一个ShapePath这样的物体:
该Demo主要是想表达这个意思,美化方面还有改进的空间,比如可以考虑用我们的mono创建一个人的模型,还可以去判断该通过物体的宽度等等!
如何在MONO 3D寻找最短路路径的更多相关文章
- Pots(POJ - 3414)【BFS 寻找最短路+路径输出】
Pots(POJ - 3414) 题目链接 算法 BFS 1.这道题问的是给你两个体积分别为A和B的容器,你对它们有三种操作,一种是装满其中一个瓶子,另一种是把其中一个瓶子的水都倒掉,还有一种就是把其 ...
- 堆优化Dijkstra计算最短路+路径计数
今天考试的时候遇到了一道题需要路径计数,然而蒟蒻从来没有做过,所以在考场上真的一脸懵逼.然后出题人NaVi_Awson说明天考试还会卡SPFA,吓得我赶紧又来学一波堆优化的Dijkstra(之前只会S ...
- CodeForces - 449B 最短路(迪杰斯特拉+堆优化)判断最短路路径数
题意: 给出n个点m条公路k条铁路. 接下来m行 u v w //u->v 距离w 然后k行 v w //1->v 距离w 如果修建了铁路并不影响两点的最短距离, ...
- L2-001 紧急救援 (25 分) (最短路+路径打印)
链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805073643683840 题目: 作为一个城市的应急救援队伍的负 ...
- POJ 1122 FDNY to the Rescue!(最短路+路径输出)
http://poj.org/problem?id=1122 题意:给出地图并且给出终点和多个起点,输出从各个起点到终点的路径和时间. 思路: 因为有多个起点,所以这里反向建图,这样就相当于把终点变成 ...
- BFS(最短路+路径打印) POJ 3984 迷宫问题
题目传送门 /* BFS:额,这题的数据范围太小了.但是重点是最短路的求法和输出路径的写法. dir数组记录是当前点的上一个点是从哪个方向过来的,搜索+,那么回溯- */ /************* ...
- *HDU 1385 最短路 路径
Minimum Transport Cost Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/O ...
- 如何在idea中设置Tomcat虚拟路径
设置项目的根路径: 设置指定文件的在Tomcat中的虚拟路径: 代码: String fileName = MyFileUtil.getFileName(uploadFileName); File f ...
- leetCode题解寻找最短字符路径
1.题目描述 2.分析 最简单的方案,对每一个字符,向两边寻找. 3.代码 vector<int> shortestToChar(string S, char C) { vector< ...
随机推荐
- HDU 4850 Wow! Such String!(欧拉道路)
HDU 4850 Wow! Such String! 题目链接 题意:求50W内的字符串.要求长度大于等于4的子串,仅仅出现一次 思路:须要推理.考虑4个字母的字符串,一共同拥有26^4种,这些由这些 ...
- 【bug】Android版QQ浏览器广告过滤
省流加速 - 广告过滤 默认开启 设别广告是添加的标签最外层标签带有adv download
- jquery input 赋值和取值
记录一下: 在写一个input赋值,二话不说就直接利用了$('#xx').val()来进行取值和赋值,取值ok,赋值后利用alert显示正确,但是在html上并没有正确的显示出来,后来改为使用如下代码 ...
- Commons-FileUpload 文件上传(模板)
// 创建FileItem工厂函数 FileItemFactory FIF = new DiskFileItemFactory(); // 获取ServletFileUpload对象,使用工厂实例传入 ...
- bzoj 1671: [Usaco2005 Dec]Knights of Ni 骑士【bfs】
bfs预处理出每个点s和t的距离d1和d2(无法到达标为inf),然后在若干灌木丛格子(x,y)里取min(d1[x][y]+d2[x][y]) /* 0:贝茜可以通过的空地 1:由于各种原因而不可通 ...
- 洛谷 P3121 [USACO15FEB]审查(黄金)Censoring (Gold) 【AC自动机+栈】
这个和bzoj同名题不一样,有多个匹配串 但是思路是一样的,写个AC自动机,同样是开两个栈,一个存字符,一个存当前点在trie树上的位置,然后如果到了某个匹配串的末尾,则弹栈 #include< ...
- P3482 [POI2009]SLO-Elephants
传送门 首先,交换关系肯定是构成一个环的时候最优 如果这个环是自环,不用交换了 如果环的大小为2,直接交换便是 否则的话,我们可以用环里最小的点最为交换媒介,然后去和其他交换直到到达正确的位置,那么环 ...
- RT-Thread 设备驱动-硬件定时器浅析与使用
RT-Thread 4.0.0 访问硬件定时器设备 应用程序通过 RT-Thread 提供的 I/O 设备管理接口来访问硬件定时器设备,相关接口如下所示: 函数 描述 rt_device_find() ...
- 【洛谷2617_BZOJ1901】Dynamic Rankings(树套树)
题目: 洛谷 2617 BZOJ 1901 是权限题,\(n=10^4\) ,内存 128 MB :洛谷 2617 \(n=10^5\) ,内存 1024 MB ,数据比较坑. 分析: 蒟蒻初学树套树 ...
- jQuery学习笔记(5)-事件与事件对象
一.前言 主要讲解事件的绑定与触发 二.jQuery中添加事件 1.使用bind()方法绑定事件 <input id="btn" type="button" ...