如何在 pathfinding3d.js 中的两个远距离节点之间构建路径?
How can I construct a path between two distant node in pathfinding3d.js?
要在 pathfinding3d.js 中创建路径,我们必须添加所有节点及其邻居。
var nodes = [
new PF.Node(0,0,0),
new PF.Node(1,0,0),
new PF.Node(2,0,0),
];
nodes[0].neighbors.push(nodes[1]);
nodes[1].neighbors.push(nodes[0],nodes[2]);
nodes[2].neighbors.push(nodes[1]);
var finder = new PF.AStarFinder();
var path = finder.findPath(nodes[0], nodes[2], nodes);
问题是,如果我想创建一个大型节点的 3d 网格,要创建一条路径,我需要在每个节点中推送邻居以创建一条路径。
还有另一种方法吗?我可以通过添加源节点和目标节点来创建从一个点到另一个距离的路径吗?如createPath(node(1,2,3),node(4,5,6)和它们之间的路径创建路径。
或者还有比这更合适的方案吗?
我已经设法找到解决方案。首先,我创建了三个函数来帮助我创建布局,连接所有节点,然后使用 pathfinding3d.js 仅连接必要的节点,以根据建议的连接节点计算需要连接的节点。这是函数:
function create3DLayout(x, y, z) {
let layout = new Array(x);
for (let i = 0; i < x; i++) {
layout[i] = new Array(y);
for (let j = 0; j < y; j++) {
layout[i][j] = new Array(z);
for (let k = 0; k < z; k++) {
layout[i][j][k] = new PF.Node(i, j, k);
}
}
}
return layout;
}
function createAllWalkable(layout) {
for (let i = 0; i < layout.length; i++) {
for (let j = 0; j < layout[i].length; j++) {
for (let k = 0; k < layout[i][j].length; k++) {
let mInit = (i + -1 >= 0) ? -1 : 0;
let mEnd = (i + 1 < layout.length) ? 1 : 0;
for (let m = mInit; m <= mEnd; m++) {
let nInit = (j + -1 >= 0) ? -1 : 0;
let nEnd = (j + 1 < layout[i].length) ? 1 : 0;
for (let n = nInit; n <= nEnd; n++) {
let oInit = (k + -1 >= 0) ? -1 : 0;
let oEnd = (k + 1 < layout[i][j].length) ? 1 : 0;
for (let o = oInit; o <= oEnd; o++) {
let xt = m + i;
let yt = n + j;
let zt = o + k;
if (layout[xt][yt][zt] != layout[i][j][k]) {
layout[i][j][k].neighbors.push(layout[xt][yt][zt]);
}
}
}
}
}
}
}
}
function createWalkablePath(layout, nodeStart, nodeEnd) {
// Create building
let walkablelayout = create3DLayout(layout.length, layout[0].length, layout[0][0].length);
// Create path to every corner of building
createAllWalkable(walkablelayout);
let startPath = walkablelayout[nodeStart.x][nodeStart.y][nodeStart.z];
let endPath = walkablelayout[nodeEnd.x][nodeEnd.y][nodeEnd.z];
let explorer = new PF.AStarFinder();
let exploredPath = explorer.findPath(startPath, endPath, walkablelayout);
for (let i = 0; i < exploredPath.length - 1; i++) {
layout[exploredPath[i][0]][exploredPath[i][1]][exploredPath[i][2]].neighbors.push(layout[exploredPath[i + 1][0]][exploredPath[i + 1][1]][exploredPath[i + 1][2]]);
layout[exploredPath[i + 1][0]][exploredPath[i + 1][1]][exploredPath[i + 1][2]].neighbors.push(layout[exploredPath[i][0]][exploredPath[i][1]][exploredPath[i][2]]);
}
}
那我算一下:
var nodes = create3DLayout(26, 26, 3);
createWalkablePath(nodes, nodes[7][14][0], nodes[9][17][0]);
createWalkablePath(nodes, nodes[0][0][0], nodes[25][25][2]);
createWalkablePath(nodes, nodes[0][25][0], nodes[9][17][0]);
createWalkablePath(nodes, nodes[1][15][1], nodes[9][17][0]);
createWalkablePath(nodes, nodes[20][25][1], nodes[9][17][0]);
// Create finder
var finder = new PF.AStarFinder();
// origin
var startNode = nodes[14][14][2];
console.log(startNode);
// Destination
var endNode = nodes[17][17][2];
console.log(endNode);
var path;
// Find path
path = finder.findPath(startNode, endNode, nodes);
console.log(path);
希望这对遇到同样问题的人有所帮助。
要在 pathfinding3d.js 中创建路径,我们必须添加所有节点及其邻居。
var nodes = [
new PF.Node(0,0,0),
new PF.Node(1,0,0),
new PF.Node(2,0,0),
];
nodes[0].neighbors.push(nodes[1]);
nodes[1].neighbors.push(nodes[0],nodes[2]);
nodes[2].neighbors.push(nodes[1]);
var finder = new PF.AStarFinder();
var path = finder.findPath(nodes[0], nodes[2], nodes);
问题是,如果我想创建一个大型节点的 3d 网格,要创建一条路径,我需要在每个节点中推送邻居以创建一条路径。 还有另一种方法吗?我可以通过添加源节点和目标节点来创建从一个点到另一个距离的路径吗?如createPath(node(1,2,3),node(4,5,6)和它们之间的路径创建路径。 或者还有比这更合适的方案吗?
我已经设法找到解决方案。首先,我创建了三个函数来帮助我创建布局,连接所有节点,然后使用 pathfinding3d.js 仅连接必要的节点,以根据建议的连接节点计算需要连接的节点。这是函数:
function create3DLayout(x, y, z) {
let layout = new Array(x);
for (let i = 0; i < x; i++) {
layout[i] = new Array(y);
for (let j = 0; j < y; j++) {
layout[i][j] = new Array(z);
for (let k = 0; k < z; k++) {
layout[i][j][k] = new PF.Node(i, j, k);
}
}
}
return layout;
}
function createAllWalkable(layout) {
for (let i = 0; i < layout.length; i++) {
for (let j = 0; j < layout[i].length; j++) {
for (let k = 0; k < layout[i][j].length; k++) {
let mInit = (i + -1 >= 0) ? -1 : 0;
let mEnd = (i + 1 < layout.length) ? 1 : 0;
for (let m = mInit; m <= mEnd; m++) {
let nInit = (j + -1 >= 0) ? -1 : 0;
let nEnd = (j + 1 < layout[i].length) ? 1 : 0;
for (let n = nInit; n <= nEnd; n++) {
let oInit = (k + -1 >= 0) ? -1 : 0;
let oEnd = (k + 1 < layout[i][j].length) ? 1 : 0;
for (let o = oInit; o <= oEnd; o++) {
let xt = m + i;
let yt = n + j;
let zt = o + k;
if (layout[xt][yt][zt] != layout[i][j][k]) {
layout[i][j][k].neighbors.push(layout[xt][yt][zt]);
}
}
}
}
}
}
}
}
function createWalkablePath(layout, nodeStart, nodeEnd) {
// Create building
let walkablelayout = create3DLayout(layout.length, layout[0].length, layout[0][0].length);
// Create path to every corner of building
createAllWalkable(walkablelayout);
let startPath = walkablelayout[nodeStart.x][nodeStart.y][nodeStart.z];
let endPath = walkablelayout[nodeEnd.x][nodeEnd.y][nodeEnd.z];
let explorer = new PF.AStarFinder();
let exploredPath = explorer.findPath(startPath, endPath, walkablelayout);
for (let i = 0; i < exploredPath.length - 1; i++) {
layout[exploredPath[i][0]][exploredPath[i][1]][exploredPath[i][2]].neighbors.push(layout[exploredPath[i + 1][0]][exploredPath[i + 1][1]][exploredPath[i + 1][2]]);
layout[exploredPath[i + 1][0]][exploredPath[i + 1][1]][exploredPath[i + 1][2]].neighbors.push(layout[exploredPath[i][0]][exploredPath[i][1]][exploredPath[i][2]]);
}
}
那我算一下:
var nodes = create3DLayout(26, 26, 3);
createWalkablePath(nodes, nodes[7][14][0], nodes[9][17][0]);
createWalkablePath(nodes, nodes[0][0][0], nodes[25][25][2]);
createWalkablePath(nodes, nodes[0][25][0], nodes[9][17][0]);
createWalkablePath(nodes, nodes[1][15][1], nodes[9][17][0]);
createWalkablePath(nodes, nodes[20][25][1], nodes[9][17][0]);
// Create finder
var finder = new PF.AStarFinder();
// origin
var startNode = nodes[14][14][2];
console.log(startNode);
// Destination
var endNode = nodes[17][17][2];
console.log(endNode);
var path;
// Find path
path = finder.findPath(startNode, endNode, nodes);
console.log(path);
希望这对遇到同样问题的人有所帮助。