feat(pkg): Add pathfinding edge pkg to packages dir

This commit is contained in:
Braks
2022-05-22 22:46:47 +02:00
parent b9dbb97374
commit 4ee7eb909a
27 changed files with 6901 additions and 0 deletions
@@ -0,0 +1,70 @@
import { Grid } from 'pathfinding'
import { Position } from '@braks/vue-flow'
import { guaranteeWalkablePath, getNextPointFromPosition } from './guaranteeWalkablePath'
import { graphToGridPoint } from './pointConversion'
import { round } from './utils'
import type { NodeBoundingBox, GraphBoundingBox } from './getBoundingBoxes'
export const gridRatio = 10
export type PointInfo = {
x: number
y: number
position: Position
}
export const createGrid = (graph: GraphBoundingBox, nodes: NodeBoundingBox[], source: PointInfo, target: PointInfo) => {
const { xMin, yMin, width, height } = graph
// Create a grid representation of the graph box, where each cell is
// equivalent to 10x10 pixels on the graph. We'll use this simplified grid
// to do pathfinding.
const mapColumns = width / gridRatio
const mapRows = height / gridRatio
const grid = new Grid(mapColumns, mapRows)
// Update the grid representation with the space the nodes take up
nodes.forEach((node) => {
const nodeStart = graphToGridPoint(node.topLeft, xMin, yMin)
const nodeEnd = graphToGridPoint(node.bottomRight, xMin, yMin)
for (let x = nodeStart.x; x < nodeEnd.x; x++) {
for (let y = nodeStart.y; y < nodeEnd.y; y++) {
grid.setWalkableAt(x, y, false)
}
}
})
// Convert the starting and ending graph points to grid points
const startGrid = graphToGridPoint(
{
x: round(source.x, gridRatio),
y: round(source.y, gridRatio),
},
xMin,
yMin,
)
const endGrid = graphToGridPoint(
{
x: round(target.x, gridRatio),
y: round(target.y, gridRatio),
},
xMin,
yMin,
)
// Guarantee a walkable path between the start and end points, even if the
// source or target where covered by another node or by padding
const startingNode = grid.getNodeAt(startGrid.x, startGrid.y)
guaranteeWalkablePath(grid, startingNode, source.position)
const endingNode = grid.getNodeAt(endGrid.x, endGrid.y)
guaranteeWalkablePath(grid, endingNode, target.position)
// Use the next closest points as the start and end points, so
// pathfinding does not start too close to the nodes
const start = getNextPointFromPosition(startingNode, source.position)
const end = getNextPointFromPosition(endingNode, target.position)
return { grid, start, end }
}