* @zh 在多边形图上寻路 * @en Find path on polygon graph
(
start: INavPolygon,
end: INavPolygon,
opts: Required<IPathfindingOptions>
)
| 393 | * @en Find path on polygon graph |
| 394 | */ |
| 395 | private findPolygonPath( |
| 396 | start: INavPolygon, |
| 397 | end: INavPolygon, |
| 398 | opts: Required<IPathfindingOptions> |
| 399 | ): { found: boolean; polygons: INavPolygon[]; nodesSearched: number } { |
| 400 | interface AStarState { |
| 401 | polygon: INavPolygon; |
| 402 | g: number; |
| 403 | f: number; |
| 404 | parent: AStarState | null; |
| 405 | } |
| 406 | |
| 407 | const openList = new BinaryHeap<AStarState>((a, b) => a.f - b.f); |
| 408 | const closed = new Set<number>(); |
| 409 | const states = new Map<number, AStarState>(); |
| 410 | |
| 411 | const startState: AStarState = { |
| 412 | polygon: start, |
| 413 | g: 0, |
| 414 | f: euclideanDistance(start.center, end.center) * opts.heuristicWeight, |
| 415 | parent: null |
| 416 | }; |
| 417 | |
| 418 | states.set(start.id, startState); |
| 419 | openList.push(startState); |
| 420 | |
| 421 | let nodesSearched = 0; |
| 422 | |
| 423 | while (!openList.isEmpty && nodesSearched < opts.maxNodes) { |
| 424 | const current = openList.pop()!; |
| 425 | nodesSearched++; |
| 426 | |
| 427 | if (current.polygon.id === end.id) { |
| 428 | // Reconstruct path |
| 429 | const path: INavPolygon[] = []; |
| 430 | let state: AStarState | null = current; |
| 431 | |
| 432 | while (state) { |
| 433 | path.unshift(state.polygon); |
| 434 | state = state.parent; |
| 435 | } |
| 436 | |
| 437 | return { found: true, polygons: path, nodesSearched }; |
| 438 | } |
| 439 | |
| 440 | closed.add(current.polygon.id); |
| 441 | |
| 442 | for (const neighborId of current.polygon.neighbors) { |
| 443 | if (closed.has(neighborId)) { |
| 444 | continue; |
| 445 | } |
| 446 | |
| 447 | const neighborPolygon = this.polygons.get(neighborId); |
| 448 | if (!neighborPolygon) { |
| 449 | continue; |
| 450 | } |
| 451 | |
| 452 | const g = current.g + euclideanDistance( |