@crazyhappyone/auto-graph 0.2.11 → 0.2.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -4161,7 +4161,10 @@ function findObstacleFreePath(source, target, obstacles, options = {}, diagnosti
4161
4161
  detail: {
4162
4162
  xsCount: xs.length,
4163
4163
  ysCount: ys.length,
4164
- maxNodes
4164
+ maxNodes,
4165
+ obstacleCount: obstacles.length,
4166
+ stage: "corridor-filtered",
4167
+ ...corridorMargin === void 0 ? {} : { corridorMargin }
4165
4168
  }
4166
4169
  });
4167
4170
  return null;
@@ -4207,7 +4210,14 @@ function findObstacleFreePath(source, target, obstacles, options = {}, diagnosti
4207
4210
  severity: "warning",
4208
4211
  code: "routing.astar.grid_overflow",
4209
4212
  message: `A* full-retry grid overflow: ${xsFull.length * ysFull.length} nodes > ${maxNodes} limit. Falling back to heuristic routing.`,
4210
- detail: { xsCount: xsFull.length, ysCount: ysFull.length, maxNodes }
4213
+ detail: {
4214
+ xsCount: xsFull.length,
4215
+ ysCount: ysFull.length,
4216
+ maxNodes,
4217
+ obstacleCount: obstacles.length,
4218
+ stage: "full-retry",
4219
+ ...corridorMargin === void 0 ? {} : { corridorMargin }
4220
+ }
4211
4221
  });
4212
4222
  return null;
4213
4223
  }
@@ -4450,6 +4460,64 @@ function areCollinear(a, b, c) {
4450
4460
  return a.x === b.x && b.x === c.x || a.y === b.y && b.y === c.y;
4451
4461
  }
4452
4462
 
4463
+ // src/routing/budget.ts
4464
+ var MIN_CORNER_BUDGET = 600;
4465
+ var MAX_CORNER_BUDGET = 3e3;
4466
+ var MIN_NODE_BUDGET = 4e3;
4467
+ var MAX_NODE_BUDGET = 64e3;
4468
+ var CORNERS_PER_OBSTACLE = 12;
4469
+ var CORNER_HEADROOM = 2;
4470
+ var GRID_SAFETY_FACTOR = 3;
4471
+ var CORRIDOR_SCALING_K = 0.5;
4472
+ var CORRIDOR_SCALING_BASE = 200;
4473
+ function computeRoutingBudget(cornerObstacles, allObstacles, corridorMargin, overrides = {}) {
4474
+ const adaptiveMaxCorners = deriveMaxCorners(
4475
+ cornerObstacles.length,
4476
+ corridorMargin
4477
+ );
4478
+ const adaptiveMaxNodes = deriveMaxNodes(
4479
+ allObstacles.length,
4480
+ corridorMargin
4481
+ );
4482
+ return {
4483
+ maxCorners: resolveBudget(
4484
+ overrides.maxCorners,
4485
+ adaptiveMaxCorners,
4486
+ MIN_CORNER_BUDGET,
4487
+ MAX_CORNER_BUDGET
4488
+ ),
4489
+ maxNodes: resolveBudget(
4490
+ overrides.maxNodes,
4491
+ adaptiveMaxNodes,
4492
+ MIN_NODE_BUDGET,
4493
+ MAX_NODE_BUDGET
4494
+ ),
4495
+ cornerObstacleCount: cornerObstacles.length,
4496
+ gridObstacleCount: allObstacles.length,
4497
+ corridorMargin
4498
+ };
4499
+ }
4500
+ function deriveMaxCorners(obstacleCount, corridorMargin) {
4501
+ const base = 2 + obstacleCount * CORNERS_PER_OBSTACLE * CORNER_HEADROOM;
4502
+ const corridorFactor = corridorScalingFactor(corridorMargin);
4503
+ return Math.ceil(base * corridorFactor);
4504
+ }
4505
+ function deriveMaxNodes(obstacleCount, corridorMargin) {
4506
+ const base = 4 * obstacleCount * obstacleCount + 4 * obstacleCount + 100;
4507
+ const corridorFactor = corridorScalingFactor(corridorMargin);
4508
+ return Math.ceil(base * GRID_SAFETY_FACTOR * corridorFactor);
4509
+ }
4510
+ function corridorScalingFactor(corridorMargin) {
4511
+ return 1 + corridorMargin / CORRIDOR_SCALING_BASE * CORRIDOR_SCALING_K;
4512
+ }
4513
+ function resolveBudget(override, adaptive, min, max) {
4514
+ const chosen = override !== void 0 && Number.isFinite(override) && override >= 1 ? override : adaptive;
4515
+ return clamp(chosen, min, max);
4516
+ }
4517
+ function clamp(value, min, max) {
4518
+ return Math.max(min, Math.min(max, value));
4519
+ }
4520
+
4453
4521
  // src/routing/visibility-router.ts
4454
4522
  function findCornerGraphPath(source, target, obstacles, options = {}, diagnostics) {
4455
4523
  const margin = options.margin ?? 0;
@@ -4463,7 +4531,12 @@ function findCornerGraphPath(source, target, obstacles, options = {}, diagnostic
4463
4531
  severity: "warning",
4464
4532
  code: "routing.visibility.corner_overflow",
4465
4533
  message: `Corner graph overflow: ${vertices.length} vertices > ${maxCorners}. Falling back to grid A*.`,
4466
- detail: { vertexCount: vertices.length, maxCorners }
4534
+ detail: {
4535
+ vertexCount: vertices.length,
4536
+ maxCorners,
4537
+ obstacleCount: obstacles.length,
4538
+ ...options.corridorMargin === void 0 ? {} : { corridorMargin: options.corridorMargin }
4539
+ }
4467
4540
  });
4468
4541
  return null;
4469
4542
  }
@@ -4848,11 +4921,22 @@ function routeEdge(input) {
4848
4921
  corridorMargin
4849
4922
  );
4850
4923
  const cornerObstacles = corridorObstacles.length === 0 && allObstacles.length > 0 ? allObstacles : corridorObstacles;
4924
+ const budget = computeRoutingBudget(
4925
+ cornerObstacles,
4926
+ allObstacles,
4927
+ corridorMargin,
4928
+ { maxCorners: input.maxCorners, maxNodes: input.maxNodes }
4929
+ );
4851
4930
  let cornerPath = findCornerGraphPath(
4852
4931
  source,
4853
4932
  target,
4854
4933
  cornerObstacles,
4855
- { endpointObstacles, margin: 2 },
4934
+ {
4935
+ endpointObstacles,
4936
+ margin: 2,
4937
+ maxCorners: budget.maxCorners,
4938
+ corridorMargin
4939
+ },
4856
4940
  diagnostics
4857
4941
  );
4858
4942
  if (cornerPath === null && cornerObstacles.length < allObstacles.length) {
@@ -4860,7 +4944,12 @@ function routeEdge(input) {
4860
4944
  source,
4861
4945
  target,
4862
4946
  allObstacles,
4863
- { endpointObstacles, margin: 2 },
4947
+ {
4948
+ endpointObstacles,
4949
+ margin: 2,
4950
+ maxCorners: budget.maxCorners,
4951
+ corridorMargin
4952
+ },
4864
4953
  diagnostics
4865
4954
  );
4866
4955
  }
@@ -4868,7 +4957,12 @@ function routeEdge(input) {
4868
4957
  source,
4869
4958
  target,
4870
4959
  allObstacles,
4871
- { endpointObstacles, margin: 0, corridorMargin },
4960
+ {
4961
+ endpointObstacles,
4962
+ margin: 0,
4963
+ corridorMargin,
4964
+ maxNodes: budget.maxNodes
4965
+ },
4872
4966
  diagnostics
4873
4967
  );
4874
4968
  if (path !== null && path.length >= 2) {
@@ -4900,7 +4994,12 @@ function routeEdge(input) {
4900
4994
  source,
4901
4995
  target,
4902
4996
  allObstacles,
4903
- { endpointObstacles, margin: 2 },
4997
+ {
4998
+ endpointObstacles,
4999
+ margin: 2,
5000
+ maxCorners: budget.maxCorners,
5001
+ corridorMargin
5002
+ },
4904
5003
  diagnostics
4905
5004
  ) : null;
4906
5005
  if (fullCornerPath !== null && fullCornerPath.length >= 2) {
@@ -4936,7 +5035,12 @@ function routeEdge(input) {
4936
5035
  source,
4937
5036
  target,
4938
5037
  allObstacles,
4939
- { endpointObstacles, margin: 0, corridorMargin },
5038
+ {
5039
+ endpointObstacles,
5040
+ margin: 0,
5041
+ corridorMargin,
5042
+ maxNodes: budget.maxNodes
5043
+ },
4940
5044
  diagnostics
4941
5045
  );
4942
5046
  if (gridPath !== null && gridPath.length >= 2) {