microboard-temp 0.5.76 → 0.5.77

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.
@@ -36555,7 +36555,7 @@ function getNeighbors(node2, grid, obstacles) {
36555
36555
  { x: node2.xGrid, y: node2.yGrid + 1 }
36556
36556
  ];
36557
36557
  for (const pos of potentialNeighbors) {
36558
- if (pos.x >= 0 && pos.x < grid.length && pos.y >= 0) {
36558
+ if (pos.x >= 0 && pos.x < grid.length && pos.y >= 0 && grid[pos.x] && grid[pos.x][pos.y]) {
36559
36559
  const newPoint = grid[pos.x][pos.y];
36560
36560
  if (newPoint && !obstacles.some((obstacle) => obstacle.isAlmostInside(newPoint, conf.CONNECTOR_ITEM_OFFSET - 1))) {
36561
36561
  neighbors.push({
@@ -36585,16 +36585,20 @@ function findCenterLine(grid, start, end, middle) {
36585
36585
  }
36586
36586
  if (width > height) {
36587
36587
  const centerIdx = grid.findIndex((row2) => row2[0].x === middlePoint.x || Math.abs(row2[0].x - middlePoint.x) < 0.01);
36588
- for (let y = 0;y < grid[0].length && centerIdx !== -1; y++) {
36589
- if (grid[centerIdx][y] && grid[centerIdx][y].x >= min2.x - 0.01 && grid[centerIdx][y].x <= max2.x + 0.01 && grid[centerIdx][y].y >= min2.y - 0.01 && grid[centerIdx][y].y <= max2.y + 0.01) {
36590
- centerLine.push(grid[centerIdx][y]);
36588
+ if (centerIdx !== -1) {
36589
+ for (let y = 0;y < grid[0].length; y++) {
36590
+ if (grid[centerIdx][y] && grid[centerIdx][y].x >= min2.x - 0.01 && grid[centerIdx][y].x <= max2.x + 0.01 && grid[centerIdx][y].y >= min2.y - 0.01 && grid[centerIdx][y].y <= max2.y + 0.01) {
36591
+ centerLine.push(grid[centerIdx][y]);
36592
+ }
36591
36593
  }
36592
36594
  }
36593
36595
  } else {
36594
36596
  const centerIdx = grid[0].findIndex((point5) => point5.y === middlePoint.y || Math.abs(point5.y - middlePoint.y) < 0.01);
36595
- for (let x = 0;x < grid.length && centerIdx !== -1; x++) {
36596
- if (grid[x][centerIdx].x >= min2.x - 0.01 && grid[x][centerIdx].x <= max2.x + 0.01 && grid[x][centerIdx].y >= min2.y - 0.01 && grid[x][centerIdx].y <= max2.y + 0.01) {
36597
- centerLine.push(grid[x][centerIdx]);
36597
+ if (centerIdx !== -1) {
36598
+ for (let x = 0;x < grid.length; x++) {
36599
+ if (grid[x][centerIdx] && grid[x][centerIdx].x >= min2.x - 0.01 && grid[x][centerIdx].x <= max2.x + 0.01 && grid[x][centerIdx].y >= min2.y - 0.01 && grid[x][centerIdx].y <= max2.y + 0.01) {
36600
+ centerLine.push(grid[x][centerIdx]);
36601
+ }
36598
36602
  }
36599
36603
  }
36600
36604
  }
@@ -36650,18 +36654,27 @@ function createGrid(start, end, toVisitPoints = []) {
36650
36654
  middlePoint: middle
36651
36655
  };
36652
36656
  }
36653
- function findPath(start, end, grid, obstacles, newStart, newEnd) {
36654
- const startIdx = grid.findIndex((row2) => row2.some((point5) => point5.barelyEqual(start)));
36655
- const endIdx = grid.findIndex((row2) => row2.some((point5) => point5.barelyEqual(end)));
36656
- if (startIdx === -1 || endIdx === -1) {
36657
- throw new Error("Start or end point not found in the grid");
36657
+ function findPath(start, end, grid, obstacles, existingPath, newStart, newEnd) {
36658
+ const startRowIndex = grid.findIndex((row2) => row2.some((point5) => point5.barelyEqual(start)));
36659
+ if (startRowIndex === -1) {
36660
+ throw new Error("Start point not found in the grid row");
36661
+ }
36662
+ const startPointIndex = grid[startRowIndex].findIndex((point5) => point5.barelyEqual(start));
36663
+ if (startPointIndex === -1) {
36664
+ throw new Error("Start point not found in the grid column");
36665
+ }
36666
+ const endRowIndex = grid.findIndex((row2) => row2.some((point5) => point5.barelyEqual(end)));
36667
+ if (endRowIndex === -1) {
36668
+ throw new Error("End point not found in the grid row");
36669
+ }
36670
+ const endPointIndex = grid[endRowIndex].findIndex((point5) => point5.barelyEqual(end));
36671
+ if (endPointIndex === -1) {
36672
+ throw new Error("End point not found in the grid column");
36658
36673
  }
36659
- const startPointIdx = grid[startIdx].findIndex((point5) => point5.barelyEqual(start));
36660
- const endPointIdx = grid[endIdx].findIndex((point5) => point5.barelyEqual(end));
36661
36674
  const endNode = {
36662
36675
  point: end,
36663
- xGrid: endIdx,
36664
- yGrid: endPointIdx,
36676
+ xGrid: endRowIndex,
36677
+ yGrid: endPointIndex,
36665
36678
  costSoFar: 0,
36666
36679
  heuristic: 0,
36667
36680
  toFinish: 0
@@ -36669,53 +36682,72 @@ function findPath(start, end, grid, obstacles, newStart, newEnd) {
36669
36682
  const startNode = {
36670
36683
  point: start,
36671
36684
  costSoFar: 0,
36672
- heuristic: heuristic({ point: start, xGrid: startIdx, yGrid: startPointIdx }, endNode),
36673
- toFinish: heuristic({ point: start, xGrid: startIdx, yGrid: startPointIdx }, endNode),
36674
- xGrid: startIdx,
36675
- yGrid: startPointIdx
36685
+ heuristic: heuristic({ point: start, xGrid: startRowIndex, yGrid: startPointIndex }, endNode),
36686
+ toFinish: heuristic({ point: start, xGrid: startRowIndex, yGrid: startPointIndex }, endNode),
36687
+ xGrid: startRowIndex,
36688
+ yGrid: startPointIndex
36676
36689
  };
36677
36690
  const openSet = [startNode];
36678
36691
  const closedSet = new Set;
36679
36692
  while (openSet.length > 0) {
36680
36693
  openSet.sort((aa, bb) => aa.toFinish - bb.toFinish);
36681
36694
  const current = openSet.shift();
36695
+ const currentKey = `${current.point.x},${current.point.y}`;
36682
36696
  if (current.point.barelyEqual(end)) {
36683
36697
  const path2 = reconstructPath(current);
36684
36698
  return path2;
36685
36699
  }
36686
- closedSet.add(current.point);
36700
+ closedSet.add(currentKey);
36687
36701
  const neighbors = getNeighbors(current, grid, obstacles);
36688
36702
  for (const neighbor of neighbors) {
36689
- if (closedSet.has(neighbor.point)) {
36703
+ const neighborKey = `${neighbor.point.x},${neighbor.point.y}`;
36704
+ if (closedSet.has(neighborKey) || existingPath.has(neighborKey) && !neighbor.point.barelyEqual(end)) {
36690
36705
  continue;
36691
36706
  }
36692
36707
  const extraCost = isChangingDirection(current, neighbor, newStart, newEnd);
36693
- const tentativeCost = current.costSoFar + 1;
36694
- if (!openSet.some((node2) => node2.point.barelyEqual(neighbor.point) && node2.costSoFar <= tentativeCost)) {
36695
- neighbor.costSoFar = tentativeCost + extraCost;
36696
- neighbor.heuristic = heuristic(neighbor, endNode);
36697
- neighbor.toFinish = neighbor.costSoFar + neighbor.heuristic;
36698
- openSet.push(neighbor);
36708
+ const pathOverlapCost = existingPath.has(neighborKey) ? 1000 : 0;
36709
+ const tentativeCost = current.costSoFar + 1 + pathOverlapCost;
36710
+ let existingNodeInOpenSet = openSet.find((node2) => node2.point.barelyEqual(neighbor.point));
36711
+ if (!existingNodeInOpenSet || tentativeCost < existingNodeInOpenSet.costSoFar) {
36712
+ if (existingNodeInOpenSet) {
36713
+ existingNodeInOpenSet.costSoFar = tentativeCost + extraCost;
36714
+ existingNodeInOpenSet.heuristic = heuristic(neighbor, endNode);
36715
+ existingNodeInOpenSet.toFinish = existingNodeInOpenSet.costSoFar + existingNodeInOpenSet.heuristic;
36716
+ existingNodeInOpenSet.parent = current;
36717
+ } else {
36718
+ neighbor.costSoFar = tentativeCost + extraCost;
36719
+ neighbor.heuristic = heuristic(neighbor, endNode);
36720
+ neighbor.toFinish = neighbor.costSoFar + neighbor.heuristic;
36721
+ openSet.push(neighbor);
36722
+ }
36699
36723
  }
36700
36724
  }
36701
36725
  }
36702
36726
  return;
36703
36727
  }
36704
36728
  function findPathPoints(points, grid, obstacles, newStart, newEnd) {
36705
- const pathPoints = [];
36729
+ const finalPath = [];
36730
+ const existingPathSegments = new Set;
36731
+ if (points.length > 0) {
36732
+ finalPath.push(points[0]);
36733
+ const startKey = `${points[0].x},${points[0].y}`;
36734
+ existingPathSegments.add(startKey);
36735
+ }
36706
36736
  for (let i = 0;i < points.length - 1; i += 1) {
36707
- const segmentPath = findPath(points[i], points[i + 1], grid, obstacles, newStart, newEnd);
36708
- if (segmentPath) {
36709
- pathPoints.push(...segmentPath.slice(0, -1));
36737
+ const segmentPath = findPath(points[i], points[i + 1], grid, obstacles, existingPathSegments, newStart, newEnd);
36738
+ if (segmentPath && segmentPath.length > 0) {
36739
+ for (let j = 1;j < segmentPath.length; j++) {
36740
+ const point5 = segmentPath[j];
36741
+ const key = `${point5.x},${point5.y}`;
36742
+ finalPath.push(point5);
36743
+ existingPathSegments.add(key);
36744
+ }
36710
36745
  } else {
36711
36746
  points.splice(i + 1, 1);
36712
36747
  i--;
36713
36748
  }
36714
36749
  }
36715
- if (pathPoints.length !== 0) {
36716
- pathPoints.push(points[points.length - 1]);
36717
- }
36718
- return pathPoints;
36750
+ return finalPath;
36719
36751
  }
36720
36752
  function reducePoints(points) {
36721
36753
  const uniquePoints = new Map;
@@ -36726,6 +36758,12 @@ function reducePoints(points) {
36726
36758
  if (uniquePoints.has(key)) {
36727
36759
  const loopStartIndex = uniquePoints.get(key);
36728
36760
  result.splice(loopStartIndex + 1);
36761
+ const removedPoints = points.slice(loopStartIndex + 1, i + 1);
36762
+ removedPoints.forEach((p3) => {
36763
+ uniquePoints.delete(`${p3.x},${p3.y}`);
36764
+ });
36765
+ uniquePoints.set(key, result.length);
36766
+ result.push(point5);
36729
36767
  } else {
36730
36768
  uniquePoints.set(key, result.length);
36731
36769
  result.push(point5);
@@ -36735,19 +36773,32 @@ function reducePoints(points) {
36735
36773
  }
36736
36774
  function getLines(pathPoints) {
36737
36775
  const lines = [];
36776
+ if (pathPoints.length < 2) {
36777
+ return [];
36778
+ }
36738
36779
  const reducedPoints = reducePoints(pathPoints);
36780
+ if (reducedPoints.length < 2) {
36781
+ return [];
36782
+ }
36739
36783
  let startPoint = reducedPoints[0];
36740
- for (let i = 1;i < reducedPoints.length - 1; i += 1) {
36784
+ for (let i = 1;i < reducedPoints.length; i += 1) {
36741
36785
  const prevPoint = reducedPoints[i - 1];
36742
36786
  const currPoint = reducedPoints[i];
36743
- const nextPoint = reducedPoints[i + 1];
36744
- if (prevPoint.x !== nextPoint.x && prevPoint.y !== nextPoint.y) {
36787
+ const nextPoint = i + 1 < reducedPoints.length ? reducedPoints[i + 1] : null;
36788
+ if (!nextPoint || prevPoint.x !== nextPoint.x && prevPoint.y !== nextPoint.y) {
36745
36789
  lines.push(new Line(startPoint, currPoint));
36746
36790
  startPoint = currPoint;
36747
36791
  }
36748
36792
  }
36749
- if (lines.length > 0) {
36750
- lines.push(new Line(startPoint, pathPoints[pathPoints.length - 1]));
36793
+ if (lines.length === 0 && reducedPoints.length > 1) {
36794
+ lines.push(new Line(reducedPoints[0], reducedPoints[reducedPoints.length - 1]));
36795
+ } else if (lines.length > 0) {
36796
+ const lastLine = lines[lines.length - 1];
36797
+ const lastPointInLines = lastLine.getEndPoint();
36798
+ const lastPointInReduced = reducedPoints[reducedPoints.length - 1];
36799
+ if (!lastPointInLines.barelyEqual(lastPointInReduced)) {
36800
+ lines.push(new Line(lastPointInLines, lastPointInReduced));
36801
+ }
36751
36802
  }
36752
36803
  return lines;
36753
36804
  }
package/dist/esm/index.js CHANGED
@@ -36548,7 +36548,7 @@ function getNeighbors(node2, grid, obstacles) {
36548
36548
  { x: node2.xGrid, y: node2.yGrid + 1 }
36549
36549
  ];
36550
36550
  for (const pos of potentialNeighbors) {
36551
- if (pos.x >= 0 && pos.x < grid.length && pos.y >= 0) {
36551
+ if (pos.x >= 0 && pos.x < grid.length && pos.y >= 0 && grid[pos.x] && grid[pos.x][pos.y]) {
36552
36552
  const newPoint = grid[pos.x][pos.y];
36553
36553
  if (newPoint && !obstacles.some((obstacle) => obstacle.isAlmostInside(newPoint, conf.CONNECTOR_ITEM_OFFSET - 1))) {
36554
36554
  neighbors.push({
@@ -36578,16 +36578,20 @@ function findCenterLine(grid, start, end, middle) {
36578
36578
  }
36579
36579
  if (width > height) {
36580
36580
  const centerIdx = grid.findIndex((row2) => row2[0].x === middlePoint.x || Math.abs(row2[0].x - middlePoint.x) < 0.01);
36581
- for (let y = 0;y < grid[0].length && centerIdx !== -1; y++) {
36582
- if (grid[centerIdx][y] && grid[centerIdx][y].x >= min2.x - 0.01 && grid[centerIdx][y].x <= max2.x + 0.01 && grid[centerIdx][y].y >= min2.y - 0.01 && grid[centerIdx][y].y <= max2.y + 0.01) {
36583
- centerLine.push(grid[centerIdx][y]);
36581
+ if (centerIdx !== -1) {
36582
+ for (let y = 0;y < grid[0].length; y++) {
36583
+ if (grid[centerIdx][y] && grid[centerIdx][y].x >= min2.x - 0.01 && grid[centerIdx][y].x <= max2.x + 0.01 && grid[centerIdx][y].y >= min2.y - 0.01 && grid[centerIdx][y].y <= max2.y + 0.01) {
36584
+ centerLine.push(grid[centerIdx][y]);
36585
+ }
36584
36586
  }
36585
36587
  }
36586
36588
  } else {
36587
36589
  const centerIdx = grid[0].findIndex((point5) => point5.y === middlePoint.y || Math.abs(point5.y - middlePoint.y) < 0.01);
36588
- for (let x = 0;x < grid.length && centerIdx !== -1; x++) {
36589
- if (grid[x][centerIdx].x >= min2.x - 0.01 && grid[x][centerIdx].x <= max2.x + 0.01 && grid[x][centerIdx].y >= min2.y - 0.01 && grid[x][centerIdx].y <= max2.y + 0.01) {
36590
- centerLine.push(grid[x][centerIdx]);
36590
+ if (centerIdx !== -1) {
36591
+ for (let x = 0;x < grid.length; x++) {
36592
+ if (grid[x][centerIdx] && grid[x][centerIdx].x >= min2.x - 0.01 && grid[x][centerIdx].x <= max2.x + 0.01 && grid[x][centerIdx].y >= min2.y - 0.01 && grid[x][centerIdx].y <= max2.y + 0.01) {
36593
+ centerLine.push(grid[x][centerIdx]);
36594
+ }
36591
36595
  }
36592
36596
  }
36593
36597
  }
@@ -36643,18 +36647,27 @@ function createGrid(start, end, toVisitPoints = []) {
36643
36647
  middlePoint: middle
36644
36648
  };
36645
36649
  }
36646
- function findPath(start, end, grid, obstacles, newStart, newEnd) {
36647
- const startIdx = grid.findIndex((row2) => row2.some((point5) => point5.barelyEqual(start)));
36648
- const endIdx = grid.findIndex((row2) => row2.some((point5) => point5.barelyEqual(end)));
36649
- if (startIdx === -1 || endIdx === -1) {
36650
- throw new Error("Start or end point not found in the grid");
36650
+ function findPath(start, end, grid, obstacles, existingPath, newStart, newEnd) {
36651
+ const startRowIndex = grid.findIndex((row2) => row2.some((point5) => point5.barelyEqual(start)));
36652
+ if (startRowIndex === -1) {
36653
+ throw new Error("Start point not found in the grid row");
36654
+ }
36655
+ const startPointIndex = grid[startRowIndex].findIndex((point5) => point5.barelyEqual(start));
36656
+ if (startPointIndex === -1) {
36657
+ throw new Error("Start point not found in the grid column");
36658
+ }
36659
+ const endRowIndex = grid.findIndex((row2) => row2.some((point5) => point5.barelyEqual(end)));
36660
+ if (endRowIndex === -1) {
36661
+ throw new Error("End point not found in the grid row");
36662
+ }
36663
+ const endPointIndex = grid[endRowIndex].findIndex((point5) => point5.barelyEqual(end));
36664
+ if (endPointIndex === -1) {
36665
+ throw new Error("End point not found in the grid column");
36651
36666
  }
36652
- const startPointIdx = grid[startIdx].findIndex((point5) => point5.barelyEqual(start));
36653
- const endPointIdx = grid[endIdx].findIndex((point5) => point5.barelyEqual(end));
36654
36667
  const endNode = {
36655
36668
  point: end,
36656
- xGrid: endIdx,
36657
- yGrid: endPointIdx,
36669
+ xGrid: endRowIndex,
36670
+ yGrid: endPointIndex,
36658
36671
  costSoFar: 0,
36659
36672
  heuristic: 0,
36660
36673
  toFinish: 0
@@ -36662,53 +36675,72 @@ function findPath(start, end, grid, obstacles, newStart, newEnd) {
36662
36675
  const startNode = {
36663
36676
  point: start,
36664
36677
  costSoFar: 0,
36665
- heuristic: heuristic({ point: start, xGrid: startIdx, yGrid: startPointIdx }, endNode),
36666
- toFinish: heuristic({ point: start, xGrid: startIdx, yGrid: startPointIdx }, endNode),
36667
- xGrid: startIdx,
36668
- yGrid: startPointIdx
36678
+ heuristic: heuristic({ point: start, xGrid: startRowIndex, yGrid: startPointIndex }, endNode),
36679
+ toFinish: heuristic({ point: start, xGrid: startRowIndex, yGrid: startPointIndex }, endNode),
36680
+ xGrid: startRowIndex,
36681
+ yGrid: startPointIndex
36669
36682
  };
36670
36683
  const openSet = [startNode];
36671
36684
  const closedSet = new Set;
36672
36685
  while (openSet.length > 0) {
36673
36686
  openSet.sort((aa, bb) => aa.toFinish - bb.toFinish);
36674
36687
  const current = openSet.shift();
36688
+ const currentKey = `${current.point.x},${current.point.y}`;
36675
36689
  if (current.point.barelyEqual(end)) {
36676
36690
  const path2 = reconstructPath(current);
36677
36691
  return path2;
36678
36692
  }
36679
- closedSet.add(current.point);
36693
+ closedSet.add(currentKey);
36680
36694
  const neighbors = getNeighbors(current, grid, obstacles);
36681
36695
  for (const neighbor of neighbors) {
36682
- if (closedSet.has(neighbor.point)) {
36696
+ const neighborKey = `${neighbor.point.x},${neighbor.point.y}`;
36697
+ if (closedSet.has(neighborKey) || existingPath.has(neighborKey) && !neighbor.point.barelyEqual(end)) {
36683
36698
  continue;
36684
36699
  }
36685
36700
  const extraCost = isChangingDirection(current, neighbor, newStart, newEnd);
36686
- const tentativeCost = current.costSoFar + 1;
36687
- if (!openSet.some((node2) => node2.point.barelyEqual(neighbor.point) && node2.costSoFar <= tentativeCost)) {
36688
- neighbor.costSoFar = tentativeCost + extraCost;
36689
- neighbor.heuristic = heuristic(neighbor, endNode);
36690
- neighbor.toFinish = neighbor.costSoFar + neighbor.heuristic;
36691
- openSet.push(neighbor);
36701
+ const pathOverlapCost = existingPath.has(neighborKey) ? 1000 : 0;
36702
+ const tentativeCost = current.costSoFar + 1 + pathOverlapCost;
36703
+ let existingNodeInOpenSet = openSet.find((node2) => node2.point.barelyEqual(neighbor.point));
36704
+ if (!existingNodeInOpenSet || tentativeCost < existingNodeInOpenSet.costSoFar) {
36705
+ if (existingNodeInOpenSet) {
36706
+ existingNodeInOpenSet.costSoFar = tentativeCost + extraCost;
36707
+ existingNodeInOpenSet.heuristic = heuristic(neighbor, endNode);
36708
+ existingNodeInOpenSet.toFinish = existingNodeInOpenSet.costSoFar + existingNodeInOpenSet.heuristic;
36709
+ existingNodeInOpenSet.parent = current;
36710
+ } else {
36711
+ neighbor.costSoFar = tentativeCost + extraCost;
36712
+ neighbor.heuristic = heuristic(neighbor, endNode);
36713
+ neighbor.toFinish = neighbor.costSoFar + neighbor.heuristic;
36714
+ openSet.push(neighbor);
36715
+ }
36692
36716
  }
36693
36717
  }
36694
36718
  }
36695
36719
  return;
36696
36720
  }
36697
36721
  function findPathPoints(points, grid, obstacles, newStart, newEnd) {
36698
- const pathPoints = [];
36722
+ const finalPath = [];
36723
+ const existingPathSegments = new Set;
36724
+ if (points.length > 0) {
36725
+ finalPath.push(points[0]);
36726
+ const startKey = `${points[0].x},${points[0].y}`;
36727
+ existingPathSegments.add(startKey);
36728
+ }
36699
36729
  for (let i = 0;i < points.length - 1; i += 1) {
36700
- const segmentPath = findPath(points[i], points[i + 1], grid, obstacles, newStart, newEnd);
36701
- if (segmentPath) {
36702
- pathPoints.push(...segmentPath.slice(0, -1));
36730
+ const segmentPath = findPath(points[i], points[i + 1], grid, obstacles, existingPathSegments, newStart, newEnd);
36731
+ if (segmentPath && segmentPath.length > 0) {
36732
+ for (let j = 1;j < segmentPath.length; j++) {
36733
+ const point5 = segmentPath[j];
36734
+ const key = `${point5.x},${point5.y}`;
36735
+ finalPath.push(point5);
36736
+ existingPathSegments.add(key);
36737
+ }
36703
36738
  } else {
36704
36739
  points.splice(i + 1, 1);
36705
36740
  i--;
36706
36741
  }
36707
36742
  }
36708
- if (pathPoints.length !== 0) {
36709
- pathPoints.push(points[points.length - 1]);
36710
- }
36711
- return pathPoints;
36743
+ return finalPath;
36712
36744
  }
36713
36745
  function reducePoints(points) {
36714
36746
  const uniquePoints = new Map;
@@ -36719,6 +36751,12 @@ function reducePoints(points) {
36719
36751
  if (uniquePoints.has(key)) {
36720
36752
  const loopStartIndex = uniquePoints.get(key);
36721
36753
  result.splice(loopStartIndex + 1);
36754
+ const removedPoints = points.slice(loopStartIndex + 1, i + 1);
36755
+ removedPoints.forEach((p3) => {
36756
+ uniquePoints.delete(`${p3.x},${p3.y}`);
36757
+ });
36758
+ uniquePoints.set(key, result.length);
36759
+ result.push(point5);
36722
36760
  } else {
36723
36761
  uniquePoints.set(key, result.length);
36724
36762
  result.push(point5);
@@ -36728,19 +36766,32 @@ function reducePoints(points) {
36728
36766
  }
36729
36767
  function getLines(pathPoints) {
36730
36768
  const lines = [];
36769
+ if (pathPoints.length < 2) {
36770
+ return [];
36771
+ }
36731
36772
  const reducedPoints = reducePoints(pathPoints);
36773
+ if (reducedPoints.length < 2) {
36774
+ return [];
36775
+ }
36732
36776
  let startPoint = reducedPoints[0];
36733
- for (let i = 1;i < reducedPoints.length - 1; i += 1) {
36777
+ for (let i = 1;i < reducedPoints.length; i += 1) {
36734
36778
  const prevPoint = reducedPoints[i - 1];
36735
36779
  const currPoint = reducedPoints[i];
36736
- const nextPoint = reducedPoints[i + 1];
36737
- if (prevPoint.x !== nextPoint.x && prevPoint.y !== nextPoint.y) {
36780
+ const nextPoint = i + 1 < reducedPoints.length ? reducedPoints[i + 1] : null;
36781
+ if (!nextPoint || prevPoint.x !== nextPoint.x && prevPoint.y !== nextPoint.y) {
36738
36782
  lines.push(new Line(startPoint, currPoint));
36739
36783
  startPoint = currPoint;
36740
36784
  }
36741
36785
  }
36742
- if (lines.length > 0) {
36743
- lines.push(new Line(startPoint, pathPoints[pathPoints.length - 1]));
36786
+ if (lines.length === 0 && reducedPoints.length > 1) {
36787
+ lines.push(new Line(reducedPoints[0], reducedPoints[reducedPoints.length - 1]));
36788
+ } else if (lines.length > 0) {
36789
+ const lastLine = lines[lines.length - 1];
36790
+ const lastPointInLines = lastLine.getEndPoint();
36791
+ const lastPointInReduced = reducedPoints[reducedPoints.length - 1];
36792
+ if (!lastPointInLines.barelyEqual(lastPointInReduced)) {
36793
+ lines.push(new Line(lastPointInLines, lastPointInReduced));
36794
+ }
36744
36795
  }
36745
36796
  return lines;
36746
36797
  }
package/dist/esm/node.js CHANGED
@@ -39016,7 +39016,7 @@ function getNeighbors(node2, grid, obstacles) {
39016
39016
  { x: node2.xGrid, y: node2.yGrid + 1 }
39017
39017
  ];
39018
39018
  for (const pos of potentialNeighbors) {
39019
- if (pos.x >= 0 && pos.x < grid.length && pos.y >= 0) {
39019
+ if (pos.x >= 0 && pos.x < grid.length && pos.y >= 0 && grid[pos.x] && grid[pos.x][pos.y]) {
39020
39020
  const newPoint = grid[pos.x][pos.y];
39021
39021
  if (newPoint && !obstacles.some((obstacle) => obstacle.isAlmostInside(newPoint, conf.CONNECTOR_ITEM_OFFSET - 1))) {
39022
39022
  neighbors.push({
@@ -39046,16 +39046,20 @@ function findCenterLine(grid, start, end, middle) {
39046
39046
  }
39047
39047
  if (width > height) {
39048
39048
  const centerIdx = grid.findIndex((row2) => row2[0].x === middlePoint.x || Math.abs(row2[0].x - middlePoint.x) < 0.01);
39049
- for (let y = 0;y < grid[0].length && centerIdx !== -1; y++) {
39050
- if (grid[centerIdx][y] && grid[centerIdx][y].x >= min2.x - 0.01 && grid[centerIdx][y].x <= max2.x + 0.01 && grid[centerIdx][y].y >= min2.y - 0.01 && grid[centerIdx][y].y <= max2.y + 0.01) {
39051
- centerLine.push(grid[centerIdx][y]);
39049
+ if (centerIdx !== -1) {
39050
+ for (let y = 0;y < grid[0].length; y++) {
39051
+ if (grid[centerIdx][y] && grid[centerIdx][y].x >= min2.x - 0.01 && grid[centerIdx][y].x <= max2.x + 0.01 && grid[centerIdx][y].y >= min2.y - 0.01 && grid[centerIdx][y].y <= max2.y + 0.01) {
39052
+ centerLine.push(grid[centerIdx][y]);
39053
+ }
39052
39054
  }
39053
39055
  }
39054
39056
  } else {
39055
39057
  const centerIdx = grid[0].findIndex((point5) => point5.y === middlePoint.y || Math.abs(point5.y - middlePoint.y) < 0.01);
39056
- for (let x = 0;x < grid.length && centerIdx !== -1; x++) {
39057
- if (grid[x][centerIdx].x >= min2.x - 0.01 && grid[x][centerIdx].x <= max2.x + 0.01 && grid[x][centerIdx].y >= min2.y - 0.01 && grid[x][centerIdx].y <= max2.y + 0.01) {
39058
- centerLine.push(grid[x][centerIdx]);
39058
+ if (centerIdx !== -1) {
39059
+ for (let x = 0;x < grid.length; x++) {
39060
+ if (grid[x][centerIdx] && grid[x][centerIdx].x >= min2.x - 0.01 && grid[x][centerIdx].x <= max2.x + 0.01 && grid[x][centerIdx].y >= min2.y - 0.01 && grid[x][centerIdx].y <= max2.y + 0.01) {
39061
+ centerLine.push(grid[x][centerIdx]);
39062
+ }
39059
39063
  }
39060
39064
  }
39061
39065
  }
@@ -39111,18 +39115,27 @@ function createGrid(start, end, toVisitPoints = []) {
39111
39115
  middlePoint: middle
39112
39116
  };
39113
39117
  }
39114
- function findPath(start, end, grid, obstacles, newStart, newEnd) {
39115
- const startIdx = grid.findIndex((row2) => row2.some((point5) => point5.barelyEqual(start)));
39116
- const endIdx = grid.findIndex((row2) => row2.some((point5) => point5.barelyEqual(end)));
39117
- if (startIdx === -1 || endIdx === -1) {
39118
- throw new Error("Start or end point not found in the grid");
39118
+ function findPath(start, end, grid, obstacles, existingPath, newStart, newEnd) {
39119
+ const startRowIndex = grid.findIndex((row2) => row2.some((point5) => point5.barelyEqual(start)));
39120
+ if (startRowIndex === -1) {
39121
+ throw new Error("Start point not found in the grid row");
39122
+ }
39123
+ const startPointIndex = grid[startRowIndex].findIndex((point5) => point5.barelyEqual(start));
39124
+ if (startPointIndex === -1) {
39125
+ throw new Error("Start point not found in the grid column");
39126
+ }
39127
+ const endRowIndex = grid.findIndex((row2) => row2.some((point5) => point5.barelyEqual(end)));
39128
+ if (endRowIndex === -1) {
39129
+ throw new Error("End point not found in the grid row");
39130
+ }
39131
+ const endPointIndex = grid[endRowIndex].findIndex((point5) => point5.barelyEqual(end));
39132
+ if (endPointIndex === -1) {
39133
+ throw new Error("End point not found in the grid column");
39119
39134
  }
39120
- const startPointIdx = grid[startIdx].findIndex((point5) => point5.barelyEqual(start));
39121
- const endPointIdx = grid[endIdx].findIndex((point5) => point5.barelyEqual(end));
39122
39135
  const endNode = {
39123
39136
  point: end,
39124
- xGrid: endIdx,
39125
- yGrid: endPointIdx,
39137
+ xGrid: endRowIndex,
39138
+ yGrid: endPointIndex,
39126
39139
  costSoFar: 0,
39127
39140
  heuristic: 0,
39128
39141
  toFinish: 0
@@ -39130,53 +39143,72 @@ function findPath(start, end, grid, obstacles, newStart, newEnd) {
39130
39143
  const startNode = {
39131
39144
  point: start,
39132
39145
  costSoFar: 0,
39133
- heuristic: heuristic({ point: start, xGrid: startIdx, yGrid: startPointIdx }, endNode),
39134
- toFinish: heuristic({ point: start, xGrid: startIdx, yGrid: startPointIdx }, endNode),
39135
- xGrid: startIdx,
39136
- yGrid: startPointIdx
39146
+ heuristic: heuristic({ point: start, xGrid: startRowIndex, yGrid: startPointIndex }, endNode),
39147
+ toFinish: heuristic({ point: start, xGrid: startRowIndex, yGrid: startPointIndex }, endNode),
39148
+ xGrid: startRowIndex,
39149
+ yGrid: startPointIndex
39137
39150
  };
39138
39151
  const openSet = [startNode];
39139
39152
  const closedSet = new Set;
39140
39153
  while (openSet.length > 0) {
39141
39154
  openSet.sort((aa, bb) => aa.toFinish - bb.toFinish);
39142
39155
  const current = openSet.shift();
39156
+ const currentKey = `${current.point.x},${current.point.y}`;
39143
39157
  if (current.point.barelyEqual(end)) {
39144
39158
  const path2 = reconstructPath(current);
39145
39159
  return path2;
39146
39160
  }
39147
- closedSet.add(current.point);
39161
+ closedSet.add(currentKey);
39148
39162
  const neighbors = getNeighbors(current, grid, obstacles);
39149
39163
  for (const neighbor of neighbors) {
39150
- if (closedSet.has(neighbor.point)) {
39164
+ const neighborKey = `${neighbor.point.x},${neighbor.point.y}`;
39165
+ if (closedSet.has(neighborKey) || existingPath.has(neighborKey) && !neighbor.point.barelyEqual(end)) {
39151
39166
  continue;
39152
39167
  }
39153
39168
  const extraCost = isChangingDirection(current, neighbor, newStart, newEnd);
39154
- const tentativeCost = current.costSoFar + 1;
39155
- if (!openSet.some((node2) => node2.point.barelyEqual(neighbor.point) && node2.costSoFar <= tentativeCost)) {
39156
- neighbor.costSoFar = tentativeCost + extraCost;
39157
- neighbor.heuristic = heuristic(neighbor, endNode);
39158
- neighbor.toFinish = neighbor.costSoFar + neighbor.heuristic;
39159
- openSet.push(neighbor);
39169
+ const pathOverlapCost = existingPath.has(neighborKey) ? 1000 : 0;
39170
+ const tentativeCost = current.costSoFar + 1 + pathOverlapCost;
39171
+ let existingNodeInOpenSet = openSet.find((node2) => node2.point.barelyEqual(neighbor.point));
39172
+ if (!existingNodeInOpenSet || tentativeCost < existingNodeInOpenSet.costSoFar) {
39173
+ if (existingNodeInOpenSet) {
39174
+ existingNodeInOpenSet.costSoFar = tentativeCost + extraCost;
39175
+ existingNodeInOpenSet.heuristic = heuristic(neighbor, endNode);
39176
+ existingNodeInOpenSet.toFinish = existingNodeInOpenSet.costSoFar + existingNodeInOpenSet.heuristic;
39177
+ existingNodeInOpenSet.parent = current;
39178
+ } else {
39179
+ neighbor.costSoFar = tentativeCost + extraCost;
39180
+ neighbor.heuristic = heuristic(neighbor, endNode);
39181
+ neighbor.toFinish = neighbor.costSoFar + neighbor.heuristic;
39182
+ openSet.push(neighbor);
39183
+ }
39160
39184
  }
39161
39185
  }
39162
39186
  }
39163
39187
  return;
39164
39188
  }
39165
39189
  function findPathPoints(points, grid, obstacles, newStart, newEnd) {
39166
- const pathPoints = [];
39190
+ const finalPath = [];
39191
+ const existingPathSegments = new Set;
39192
+ if (points.length > 0) {
39193
+ finalPath.push(points[0]);
39194
+ const startKey = `${points[0].x},${points[0].y}`;
39195
+ existingPathSegments.add(startKey);
39196
+ }
39167
39197
  for (let i = 0;i < points.length - 1; i += 1) {
39168
- const segmentPath = findPath(points[i], points[i + 1], grid, obstacles, newStart, newEnd);
39169
- if (segmentPath) {
39170
- pathPoints.push(...segmentPath.slice(0, -1));
39198
+ const segmentPath = findPath(points[i], points[i + 1], grid, obstacles, existingPathSegments, newStart, newEnd);
39199
+ if (segmentPath && segmentPath.length > 0) {
39200
+ for (let j = 1;j < segmentPath.length; j++) {
39201
+ const point5 = segmentPath[j];
39202
+ const key = `${point5.x},${point5.y}`;
39203
+ finalPath.push(point5);
39204
+ existingPathSegments.add(key);
39205
+ }
39171
39206
  } else {
39172
39207
  points.splice(i + 1, 1);
39173
39208
  i--;
39174
39209
  }
39175
39210
  }
39176
- if (pathPoints.length !== 0) {
39177
- pathPoints.push(points[points.length - 1]);
39178
- }
39179
- return pathPoints;
39211
+ return finalPath;
39180
39212
  }
39181
39213
  function reducePoints(points) {
39182
39214
  const uniquePoints = new Map;
@@ -39187,6 +39219,12 @@ function reducePoints(points) {
39187
39219
  if (uniquePoints.has(key)) {
39188
39220
  const loopStartIndex = uniquePoints.get(key);
39189
39221
  result.splice(loopStartIndex + 1);
39222
+ const removedPoints = points.slice(loopStartIndex + 1, i + 1);
39223
+ removedPoints.forEach((p3) => {
39224
+ uniquePoints.delete(`${p3.x},${p3.y}`);
39225
+ });
39226
+ uniquePoints.set(key, result.length);
39227
+ result.push(point5);
39190
39228
  } else {
39191
39229
  uniquePoints.set(key, result.length);
39192
39230
  result.push(point5);
@@ -39196,19 +39234,32 @@ function reducePoints(points) {
39196
39234
  }
39197
39235
  function getLines(pathPoints) {
39198
39236
  const lines = [];
39237
+ if (pathPoints.length < 2) {
39238
+ return [];
39239
+ }
39199
39240
  const reducedPoints = reducePoints(pathPoints);
39241
+ if (reducedPoints.length < 2) {
39242
+ return [];
39243
+ }
39200
39244
  let startPoint = reducedPoints[0];
39201
- for (let i = 1;i < reducedPoints.length - 1; i += 1) {
39245
+ for (let i = 1;i < reducedPoints.length; i += 1) {
39202
39246
  const prevPoint = reducedPoints[i - 1];
39203
39247
  const currPoint = reducedPoints[i];
39204
- const nextPoint = reducedPoints[i + 1];
39205
- if (prevPoint.x !== nextPoint.x && prevPoint.y !== nextPoint.y) {
39248
+ const nextPoint = i + 1 < reducedPoints.length ? reducedPoints[i + 1] : null;
39249
+ if (!nextPoint || prevPoint.x !== nextPoint.x && prevPoint.y !== nextPoint.y) {
39206
39250
  lines.push(new Line(startPoint, currPoint));
39207
39251
  startPoint = currPoint;
39208
39252
  }
39209
39253
  }
39210
- if (lines.length > 0) {
39211
- lines.push(new Line(startPoint, pathPoints[pathPoints.length - 1]));
39254
+ if (lines.length === 0 && reducedPoints.length > 1) {
39255
+ lines.push(new Line(reducedPoints[0], reducedPoints[reducedPoints.length - 1]));
39256
+ } else if (lines.length > 0) {
39257
+ const lastLine = lines[lines.length - 1];
39258
+ const lastPointInLines = lastLine.getEndPoint();
39259
+ const lastPointInReduced = reducedPoints[reducedPoints.length - 1];
39260
+ if (!lastPointInLines.barelyEqual(lastPointInReduced)) {
39261
+ lines.push(new Line(lastPointInLines, lastPointInReduced));
39262
+ }
39212
39263
  }
39213
39264
  return lines;
39214
39265
  }