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.
@@ -36710,7 +36710,7 @@ function getNeighbors(node2, grid, obstacles) {
36710
36710
  { x: node2.xGrid, y: node2.yGrid + 1 }
36711
36711
  ];
36712
36712
  for (const pos of potentialNeighbors) {
36713
- if (pos.x >= 0 && pos.x < grid.length && pos.y >= 0) {
36713
+ if (pos.x >= 0 && pos.x < grid.length && pos.y >= 0 && grid[pos.x] && grid[pos.x][pos.y]) {
36714
36714
  const newPoint = grid[pos.x][pos.y];
36715
36715
  if (newPoint && !obstacles.some((obstacle) => obstacle.isAlmostInside(newPoint, conf.CONNECTOR_ITEM_OFFSET - 1))) {
36716
36716
  neighbors.push({
@@ -36740,16 +36740,20 @@ function findCenterLine(grid, start, end, middle) {
36740
36740
  }
36741
36741
  if (width > height) {
36742
36742
  const centerIdx = grid.findIndex((row2) => row2[0].x === middlePoint.x || Math.abs(row2[0].x - middlePoint.x) < 0.01);
36743
- for (let y = 0;y < grid[0].length && centerIdx !== -1; y++) {
36744
- 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) {
36745
- centerLine.push(grid[centerIdx][y]);
36743
+ if (centerIdx !== -1) {
36744
+ for (let y = 0;y < grid[0].length; y++) {
36745
+ 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) {
36746
+ centerLine.push(grid[centerIdx][y]);
36747
+ }
36746
36748
  }
36747
36749
  }
36748
36750
  } else {
36749
36751
  const centerIdx = grid[0].findIndex((point5) => point5.y === middlePoint.y || Math.abs(point5.y - middlePoint.y) < 0.01);
36750
- for (let x = 0;x < grid.length && centerIdx !== -1; x++) {
36751
- 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) {
36752
- centerLine.push(grid[x][centerIdx]);
36752
+ if (centerIdx !== -1) {
36753
+ for (let x = 0;x < grid.length; x++) {
36754
+ 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) {
36755
+ centerLine.push(grid[x][centerIdx]);
36756
+ }
36753
36757
  }
36754
36758
  }
36755
36759
  }
@@ -36805,18 +36809,27 @@ function createGrid(start, end, toVisitPoints = []) {
36805
36809
  middlePoint: middle
36806
36810
  };
36807
36811
  }
36808
- function findPath(start, end, grid, obstacles, newStart, newEnd) {
36809
- const startIdx = grid.findIndex((row2) => row2.some((point5) => point5.barelyEqual(start)));
36810
- const endIdx = grid.findIndex((row2) => row2.some((point5) => point5.barelyEqual(end)));
36811
- if (startIdx === -1 || endIdx === -1) {
36812
- throw new Error("Start or end point not found in the grid");
36812
+ function findPath(start, end, grid, obstacles, existingPath, newStart, newEnd) {
36813
+ const startRowIndex = grid.findIndex((row2) => row2.some((point5) => point5.barelyEqual(start)));
36814
+ if (startRowIndex === -1) {
36815
+ throw new Error("Start point not found in the grid row");
36816
+ }
36817
+ const startPointIndex = grid[startRowIndex].findIndex((point5) => point5.barelyEqual(start));
36818
+ if (startPointIndex === -1) {
36819
+ throw new Error("Start point not found in the grid column");
36820
+ }
36821
+ const endRowIndex = grid.findIndex((row2) => row2.some((point5) => point5.barelyEqual(end)));
36822
+ if (endRowIndex === -1) {
36823
+ throw new Error("End point not found in the grid row");
36824
+ }
36825
+ const endPointIndex = grid[endRowIndex].findIndex((point5) => point5.barelyEqual(end));
36826
+ if (endPointIndex === -1) {
36827
+ throw new Error("End point not found in the grid column");
36813
36828
  }
36814
- const startPointIdx = grid[startIdx].findIndex((point5) => point5.barelyEqual(start));
36815
- const endPointIdx = grid[endIdx].findIndex((point5) => point5.barelyEqual(end));
36816
36829
  const endNode = {
36817
36830
  point: end,
36818
- xGrid: endIdx,
36819
- yGrid: endPointIdx,
36831
+ xGrid: endRowIndex,
36832
+ yGrid: endPointIndex,
36820
36833
  costSoFar: 0,
36821
36834
  heuristic: 0,
36822
36835
  toFinish: 0
@@ -36824,53 +36837,72 @@ function findPath(start, end, grid, obstacles, newStart, newEnd) {
36824
36837
  const startNode = {
36825
36838
  point: start,
36826
36839
  costSoFar: 0,
36827
- heuristic: heuristic({ point: start, xGrid: startIdx, yGrid: startPointIdx }, endNode),
36828
- toFinish: heuristic({ point: start, xGrid: startIdx, yGrid: startPointIdx }, endNode),
36829
- xGrid: startIdx,
36830
- yGrid: startPointIdx
36840
+ heuristic: heuristic({ point: start, xGrid: startRowIndex, yGrid: startPointIndex }, endNode),
36841
+ toFinish: heuristic({ point: start, xGrid: startRowIndex, yGrid: startPointIndex }, endNode),
36842
+ xGrid: startRowIndex,
36843
+ yGrid: startPointIndex
36831
36844
  };
36832
36845
  const openSet = [startNode];
36833
36846
  const closedSet = new Set;
36834
36847
  while (openSet.length > 0) {
36835
36848
  openSet.sort((aa, bb) => aa.toFinish - bb.toFinish);
36836
36849
  const current = openSet.shift();
36850
+ const currentKey = `${current.point.x},${current.point.y}`;
36837
36851
  if (current.point.barelyEqual(end)) {
36838
36852
  const path2 = reconstructPath(current);
36839
36853
  return path2;
36840
36854
  }
36841
- closedSet.add(current.point);
36855
+ closedSet.add(currentKey);
36842
36856
  const neighbors = getNeighbors(current, grid, obstacles);
36843
36857
  for (const neighbor of neighbors) {
36844
- if (closedSet.has(neighbor.point)) {
36858
+ const neighborKey = `${neighbor.point.x},${neighbor.point.y}`;
36859
+ if (closedSet.has(neighborKey) || existingPath.has(neighborKey) && !neighbor.point.barelyEqual(end)) {
36845
36860
  continue;
36846
36861
  }
36847
36862
  const extraCost = isChangingDirection(current, neighbor, newStart, newEnd);
36848
- const tentativeCost = current.costSoFar + 1;
36849
- if (!openSet.some((node2) => node2.point.barelyEqual(neighbor.point) && node2.costSoFar <= tentativeCost)) {
36850
- neighbor.costSoFar = tentativeCost + extraCost;
36851
- neighbor.heuristic = heuristic(neighbor, endNode);
36852
- neighbor.toFinish = neighbor.costSoFar + neighbor.heuristic;
36853
- openSet.push(neighbor);
36863
+ const pathOverlapCost = existingPath.has(neighborKey) ? 1000 : 0;
36864
+ const tentativeCost = current.costSoFar + 1 + pathOverlapCost;
36865
+ let existingNodeInOpenSet = openSet.find((node2) => node2.point.barelyEqual(neighbor.point));
36866
+ if (!existingNodeInOpenSet || tentativeCost < existingNodeInOpenSet.costSoFar) {
36867
+ if (existingNodeInOpenSet) {
36868
+ existingNodeInOpenSet.costSoFar = tentativeCost + extraCost;
36869
+ existingNodeInOpenSet.heuristic = heuristic(neighbor, endNode);
36870
+ existingNodeInOpenSet.toFinish = existingNodeInOpenSet.costSoFar + existingNodeInOpenSet.heuristic;
36871
+ existingNodeInOpenSet.parent = current;
36872
+ } else {
36873
+ neighbor.costSoFar = tentativeCost + extraCost;
36874
+ neighbor.heuristic = heuristic(neighbor, endNode);
36875
+ neighbor.toFinish = neighbor.costSoFar + neighbor.heuristic;
36876
+ openSet.push(neighbor);
36877
+ }
36854
36878
  }
36855
36879
  }
36856
36880
  }
36857
36881
  return;
36858
36882
  }
36859
36883
  function findPathPoints(points, grid, obstacles, newStart, newEnd) {
36860
- const pathPoints = [];
36884
+ const finalPath = [];
36885
+ const existingPathSegments = new Set;
36886
+ if (points.length > 0) {
36887
+ finalPath.push(points[0]);
36888
+ const startKey = `${points[0].x},${points[0].y}`;
36889
+ existingPathSegments.add(startKey);
36890
+ }
36861
36891
  for (let i = 0;i < points.length - 1; i += 1) {
36862
- const segmentPath = findPath(points[i], points[i + 1], grid, obstacles, newStart, newEnd);
36863
- if (segmentPath) {
36864
- pathPoints.push(...segmentPath.slice(0, -1));
36892
+ const segmentPath = findPath(points[i], points[i + 1], grid, obstacles, existingPathSegments, newStart, newEnd);
36893
+ if (segmentPath && segmentPath.length > 0) {
36894
+ for (let j = 1;j < segmentPath.length; j++) {
36895
+ const point5 = segmentPath[j];
36896
+ const key = `${point5.x},${point5.y}`;
36897
+ finalPath.push(point5);
36898
+ existingPathSegments.add(key);
36899
+ }
36865
36900
  } else {
36866
36901
  points.splice(i + 1, 1);
36867
36902
  i--;
36868
36903
  }
36869
36904
  }
36870
- if (pathPoints.length !== 0) {
36871
- pathPoints.push(points[points.length - 1]);
36872
- }
36873
- return pathPoints;
36905
+ return finalPath;
36874
36906
  }
36875
36907
  function reducePoints(points) {
36876
36908
  const uniquePoints = new Map;
@@ -36881,6 +36913,12 @@ function reducePoints(points) {
36881
36913
  if (uniquePoints.has(key)) {
36882
36914
  const loopStartIndex = uniquePoints.get(key);
36883
36915
  result.splice(loopStartIndex + 1);
36916
+ const removedPoints = points.slice(loopStartIndex + 1, i + 1);
36917
+ removedPoints.forEach((p3) => {
36918
+ uniquePoints.delete(`${p3.x},${p3.y}`);
36919
+ });
36920
+ uniquePoints.set(key, result.length);
36921
+ result.push(point5);
36884
36922
  } else {
36885
36923
  uniquePoints.set(key, result.length);
36886
36924
  result.push(point5);
@@ -36890,19 +36928,32 @@ function reducePoints(points) {
36890
36928
  }
36891
36929
  function getLines(pathPoints) {
36892
36930
  const lines = [];
36931
+ if (pathPoints.length < 2) {
36932
+ return [];
36933
+ }
36893
36934
  const reducedPoints = reducePoints(pathPoints);
36935
+ if (reducedPoints.length < 2) {
36936
+ return [];
36937
+ }
36894
36938
  let startPoint = reducedPoints[0];
36895
- for (let i = 1;i < reducedPoints.length - 1; i += 1) {
36939
+ for (let i = 1;i < reducedPoints.length; i += 1) {
36896
36940
  const prevPoint = reducedPoints[i - 1];
36897
36941
  const currPoint = reducedPoints[i];
36898
- const nextPoint = reducedPoints[i + 1];
36899
- if (prevPoint.x !== nextPoint.x && prevPoint.y !== nextPoint.y) {
36942
+ const nextPoint = i + 1 < reducedPoints.length ? reducedPoints[i + 1] : null;
36943
+ if (!nextPoint || prevPoint.x !== nextPoint.x && prevPoint.y !== nextPoint.y) {
36900
36944
  lines.push(new Line(startPoint, currPoint));
36901
36945
  startPoint = currPoint;
36902
36946
  }
36903
36947
  }
36904
- if (lines.length > 0) {
36905
- lines.push(new Line(startPoint, pathPoints[pathPoints.length - 1]));
36948
+ if (lines.length === 0 && reducedPoints.length > 1) {
36949
+ lines.push(new Line(reducedPoints[0], reducedPoints[reducedPoints.length - 1]));
36950
+ } else if (lines.length > 0) {
36951
+ const lastLine = lines[lines.length - 1];
36952
+ const lastPointInLines = lastLine.getEndPoint();
36953
+ const lastPointInReduced = reducedPoints[reducedPoints.length - 1];
36954
+ if (!lastPointInLines.barelyEqual(lastPointInReduced)) {
36955
+ lines.push(new Line(lastPointInLines, lastPointInReduced));
36956
+ }
36906
36957
  }
36907
36958
  return lines;
36908
36959
  }
package/dist/cjs/index.js CHANGED
@@ -36710,7 +36710,7 @@ function getNeighbors(node2, grid, obstacles) {
36710
36710
  { x: node2.xGrid, y: node2.yGrid + 1 }
36711
36711
  ];
36712
36712
  for (const pos of potentialNeighbors) {
36713
- if (pos.x >= 0 && pos.x < grid.length && pos.y >= 0) {
36713
+ if (pos.x >= 0 && pos.x < grid.length && pos.y >= 0 && grid[pos.x] && grid[pos.x][pos.y]) {
36714
36714
  const newPoint = grid[pos.x][pos.y];
36715
36715
  if (newPoint && !obstacles.some((obstacle) => obstacle.isAlmostInside(newPoint, conf.CONNECTOR_ITEM_OFFSET - 1))) {
36716
36716
  neighbors.push({
@@ -36740,16 +36740,20 @@ function findCenterLine(grid, start, end, middle) {
36740
36740
  }
36741
36741
  if (width > height) {
36742
36742
  const centerIdx = grid.findIndex((row2) => row2[0].x === middlePoint.x || Math.abs(row2[0].x - middlePoint.x) < 0.01);
36743
- for (let y = 0;y < grid[0].length && centerIdx !== -1; y++) {
36744
- 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) {
36745
- centerLine.push(grid[centerIdx][y]);
36743
+ if (centerIdx !== -1) {
36744
+ for (let y = 0;y < grid[0].length; y++) {
36745
+ 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) {
36746
+ centerLine.push(grid[centerIdx][y]);
36747
+ }
36746
36748
  }
36747
36749
  }
36748
36750
  } else {
36749
36751
  const centerIdx = grid[0].findIndex((point5) => point5.y === middlePoint.y || Math.abs(point5.y - middlePoint.y) < 0.01);
36750
- for (let x = 0;x < grid.length && centerIdx !== -1; x++) {
36751
- 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) {
36752
- centerLine.push(grid[x][centerIdx]);
36752
+ if (centerIdx !== -1) {
36753
+ for (let x = 0;x < grid.length; x++) {
36754
+ 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) {
36755
+ centerLine.push(grid[x][centerIdx]);
36756
+ }
36753
36757
  }
36754
36758
  }
36755
36759
  }
@@ -36805,18 +36809,27 @@ function createGrid(start, end, toVisitPoints = []) {
36805
36809
  middlePoint: middle
36806
36810
  };
36807
36811
  }
36808
- function findPath(start, end, grid, obstacles, newStart, newEnd) {
36809
- const startIdx = grid.findIndex((row2) => row2.some((point5) => point5.barelyEqual(start)));
36810
- const endIdx = grid.findIndex((row2) => row2.some((point5) => point5.barelyEqual(end)));
36811
- if (startIdx === -1 || endIdx === -1) {
36812
- throw new Error("Start or end point not found in the grid");
36812
+ function findPath(start, end, grid, obstacles, existingPath, newStart, newEnd) {
36813
+ const startRowIndex = grid.findIndex((row2) => row2.some((point5) => point5.barelyEqual(start)));
36814
+ if (startRowIndex === -1) {
36815
+ throw new Error("Start point not found in the grid row");
36816
+ }
36817
+ const startPointIndex = grid[startRowIndex].findIndex((point5) => point5.barelyEqual(start));
36818
+ if (startPointIndex === -1) {
36819
+ throw new Error("Start point not found in the grid column");
36820
+ }
36821
+ const endRowIndex = grid.findIndex((row2) => row2.some((point5) => point5.barelyEqual(end)));
36822
+ if (endRowIndex === -1) {
36823
+ throw new Error("End point not found in the grid row");
36824
+ }
36825
+ const endPointIndex = grid[endRowIndex].findIndex((point5) => point5.barelyEqual(end));
36826
+ if (endPointIndex === -1) {
36827
+ throw new Error("End point not found in the grid column");
36813
36828
  }
36814
- const startPointIdx = grid[startIdx].findIndex((point5) => point5.barelyEqual(start));
36815
- const endPointIdx = grid[endIdx].findIndex((point5) => point5.barelyEqual(end));
36816
36829
  const endNode = {
36817
36830
  point: end,
36818
- xGrid: endIdx,
36819
- yGrid: endPointIdx,
36831
+ xGrid: endRowIndex,
36832
+ yGrid: endPointIndex,
36820
36833
  costSoFar: 0,
36821
36834
  heuristic: 0,
36822
36835
  toFinish: 0
@@ -36824,53 +36837,72 @@ function findPath(start, end, grid, obstacles, newStart, newEnd) {
36824
36837
  const startNode = {
36825
36838
  point: start,
36826
36839
  costSoFar: 0,
36827
- heuristic: heuristic({ point: start, xGrid: startIdx, yGrid: startPointIdx }, endNode),
36828
- toFinish: heuristic({ point: start, xGrid: startIdx, yGrid: startPointIdx }, endNode),
36829
- xGrid: startIdx,
36830
- yGrid: startPointIdx
36840
+ heuristic: heuristic({ point: start, xGrid: startRowIndex, yGrid: startPointIndex }, endNode),
36841
+ toFinish: heuristic({ point: start, xGrid: startRowIndex, yGrid: startPointIndex }, endNode),
36842
+ xGrid: startRowIndex,
36843
+ yGrid: startPointIndex
36831
36844
  };
36832
36845
  const openSet = [startNode];
36833
36846
  const closedSet = new Set;
36834
36847
  while (openSet.length > 0) {
36835
36848
  openSet.sort((aa, bb) => aa.toFinish - bb.toFinish);
36836
36849
  const current = openSet.shift();
36850
+ const currentKey = `${current.point.x},${current.point.y}`;
36837
36851
  if (current.point.barelyEqual(end)) {
36838
36852
  const path2 = reconstructPath(current);
36839
36853
  return path2;
36840
36854
  }
36841
- closedSet.add(current.point);
36855
+ closedSet.add(currentKey);
36842
36856
  const neighbors = getNeighbors(current, grid, obstacles);
36843
36857
  for (const neighbor of neighbors) {
36844
- if (closedSet.has(neighbor.point)) {
36858
+ const neighborKey = `${neighbor.point.x},${neighbor.point.y}`;
36859
+ if (closedSet.has(neighborKey) || existingPath.has(neighborKey) && !neighbor.point.barelyEqual(end)) {
36845
36860
  continue;
36846
36861
  }
36847
36862
  const extraCost = isChangingDirection(current, neighbor, newStart, newEnd);
36848
- const tentativeCost = current.costSoFar + 1;
36849
- if (!openSet.some((node2) => node2.point.barelyEqual(neighbor.point) && node2.costSoFar <= tentativeCost)) {
36850
- neighbor.costSoFar = tentativeCost + extraCost;
36851
- neighbor.heuristic = heuristic(neighbor, endNode);
36852
- neighbor.toFinish = neighbor.costSoFar + neighbor.heuristic;
36853
- openSet.push(neighbor);
36863
+ const pathOverlapCost = existingPath.has(neighborKey) ? 1000 : 0;
36864
+ const tentativeCost = current.costSoFar + 1 + pathOverlapCost;
36865
+ let existingNodeInOpenSet = openSet.find((node2) => node2.point.barelyEqual(neighbor.point));
36866
+ if (!existingNodeInOpenSet || tentativeCost < existingNodeInOpenSet.costSoFar) {
36867
+ if (existingNodeInOpenSet) {
36868
+ existingNodeInOpenSet.costSoFar = tentativeCost + extraCost;
36869
+ existingNodeInOpenSet.heuristic = heuristic(neighbor, endNode);
36870
+ existingNodeInOpenSet.toFinish = existingNodeInOpenSet.costSoFar + existingNodeInOpenSet.heuristic;
36871
+ existingNodeInOpenSet.parent = current;
36872
+ } else {
36873
+ neighbor.costSoFar = tentativeCost + extraCost;
36874
+ neighbor.heuristic = heuristic(neighbor, endNode);
36875
+ neighbor.toFinish = neighbor.costSoFar + neighbor.heuristic;
36876
+ openSet.push(neighbor);
36877
+ }
36854
36878
  }
36855
36879
  }
36856
36880
  }
36857
36881
  return;
36858
36882
  }
36859
36883
  function findPathPoints(points, grid, obstacles, newStart, newEnd) {
36860
- const pathPoints = [];
36884
+ const finalPath = [];
36885
+ const existingPathSegments = new Set;
36886
+ if (points.length > 0) {
36887
+ finalPath.push(points[0]);
36888
+ const startKey = `${points[0].x},${points[0].y}`;
36889
+ existingPathSegments.add(startKey);
36890
+ }
36861
36891
  for (let i = 0;i < points.length - 1; i += 1) {
36862
- const segmentPath = findPath(points[i], points[i + 1], grid, obstacles, newStart, newEnd);
36863
- if (segmentPath) {
36864
- pathPoints.push(...segmentPath.slice(0, -1));
36892
+ const segmentPath = findPath(points[i], points[i + 1], grid, obstacles, existingPathSegments, newStart, newEnd);
36893
+ if (segmentPath && segmentPath.length > 0) {
36894
+ for (let j = 1;j < segmentPath.length; j++) {
36895
+ const point5 = segmentPath[j];
36896
+ const key = `${point5.x},${point5.y}`;
36897
+ finalPath.push(point5);
36898
+ existingPathSegments.add(key);
36899
+ }
36865
36900
  } else {
36866
36901
  points.splice(i + 1, 1);
36867
36902
  i--;
36868
36903
  }
36869
36904
  }
36870
- if (pathPoints.length !== 0) {
36871
- pathPoints.push(points[points.length - 1]);
36872
- }
36873
- return pathPoints;
36905
+ return finalPath;
36874
36906
  }
36875
36907
  function reducePoints(points) {
36876
36908
  const uniquePoints = new Map;
@@ -36881,6 +36913,12 @@ function reducePoints(points) {
36881
36913
  if (uniquePoints.has(key)) {
36882
36914
  const loopStartIndex = uniquePoints.get(key);
36883
36915
  result.splice(loopStartIndex + 1);
36916
+ const removedPoints = points.slice(loopStartIndex + 1, i + 1);
36917
+ removedPoints.forEach((p3) => {
36918
+ uniquePoints.delete(`${p3.x},${p3.y}`);
36919
+ });
36920
+ uniquePoints.set(key, result.length);
36921
+ result.push(point5);
36884
36922
  } else {
36885
36923
  uniquePoints.set(key, result.length);
36886
36924
  result.push(point5);
@@ -36890,19 +36928,32 @@ function reducePoints(points) {
36890
36928
  }
36891
36929
  function getLines(pathPoints) {
36892
36930
  const lines = [];
36931
+ if (pathPoints.length < 2) {
36932
+ return [];
36933
+ }
36893
36934
  const reducedPoints = reducePoints(pathPoints);
36935
+ if (reducedPoints.length < 2) {
36936
+ return [];
36937
+ }
36894
36938
  let startPoint = reducedPoints[0];
36895
- for (let i = 1;i < reducedPoints.length - 1; i += 1) {
36939
+ for (let i = 1;i < reducedPoints.length; i += 1) {
36896
36940
  const prevPoint = reducedPoints[i - 1];
36897
36941
  const currPoint = reducedPoints[i];
36898
- const nextPoint = reducedPoints[i + 1];
36899
- if (prevPoint.x !== nextPoint.x && prevPoint.y !== nextPoint.y) {
36942
+ const nextPoint = i + 1 < reducedPoints.length ? reducedPoints[i + 1] : null;
36943
+ if (!nextPoint || prevPoint.x !== nextPoint.x && prevPoint.y !== nextPoint.y) {
36900
36944
  lines.push(new Line(startPoint, currPoint));
36901
36945
  startPoint = currPoint;
36902
36946
  }
36903
36947
  }
36904
- if (lines.length > 0) {
36905
- lines.push(new Line(startPoint, pathPoints[pathPoints.length - 1]));
36948
+ if (lines.length === 0 && reducedPoints.length > 1) {
36949
+ lines.push(new Line(reducedPoints[0], reducedPoints[reducedPoints.length - 1]));
36950
+ } else if (lines.length > 0) {
36951
+ const lastLine = lines[lines.length - 1];
36952
+ const lastPointInLines = lastLine.getEndPoint();
36953
+ const lastPointInReduced = reducedPoints[reducedPoints.length - 1];
36954
+ if (!lastPointInLines.barelyEqual(lastPointInReduced)) {
36955
+ lines.push(new Line(lastPointInLines, lastPointInReduced));
36956
+ }
36906
36957
  }
36907
36958
  return lines;
36908
36959
  }
package/dist/cjs/node.js CHANGED
@@ -39183,7 +39183,7 @@ function getNeighbors(node2, grid, obstacles) {
39183
39183
  { x: node2.xGrid, y: node2.yGrid + 1 }
39184
39184
  ];
39185
39185
  for (const pos of potentialNeighbors) {
39186
- if (pos.x >= 0 && pos.x < grid.length && pos.y >= 0) {
39186
+ if (pos.x >= 0 && pos.x < grid.length && pos.y >= 0 && grid[pos.x] && grid[pos.x][pos.y]) {
39187
39187
  const newPoint = grid[pos.x][pos.y];
39188
39188
  if (newPoint && !obstacles.some((obstacle) => obstacle.isAlmostInside(newPoint, conf.CONNECTOR_ITEM_OFFSET - 1))) {
39189
39189
  neighbors.push({
@@ -39213,16 +39213,20 @@ function findCenterLine(grid, start, end, middle) {
39213
39213
  }
39214
39214
  if (width > height) {
39215
39215
  const centerIdx = grid.findIndex((row2) => row2[0].x === middlePoint.x || Math.abs(row2[0].x - middlePoint.x) < 0.01);
39216
- for (let y = 0;y < grid[0].length && centerIdx !== -1; y++) {
39217
- 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) {
39218
- centerLine.push(grid[centerIdx][y]);
39216
+ if (centerIdx !== -1) {
39217
+ for (let y = 0;y < grid[0].length; y++) {
39218
+ 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) {
39219
+ centerLine.push(grid[centerIdx][y]);
39220
+ }
39219
39221
  }
39220
39222
  }
39221
39223
  } else {
39222
39224
  const centerIdx = grid[0].findIndex((point5) => point5.y === middlePoint.y || Math.abs(point5.y - middlePoint.y) < 0.01);
39223
- for (let x = 0;x < grid.length && centerIdx !== -1; x++) {
39224
- 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) {
39225
- centerLine.push(grid[x][centerIdx]);
39225
+ if (centerIdx !== -1) {
39226
+ for (let x = 0;x < grid.length; x++) {
39227
+ 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) {
39228
+ centerLine.push(grid[x][centerIdx]);
39229
+ }
39226
39230
  }
39227
39231
  }
39228
39232
  }
@@ -39278,18 +39282,27 @@ function createGrid(start, end, toVisitPoints = []) {
39278
39282
  middlePoint: middle
39279
39283
  };
39280
39284
  }
39281
- function findPath(start, end, grid, obstacles, newStart, newEnd) {
39282
- const startIdx = grid.findIndex((row2) => row2.some((point5) => point5.barelyEqual(start)));
39283
- const endIdx = grid.findIndex((row2) => row2.some((point5) => point5.barelyEqual(end)));
39284
- if (startIdx === -1 || endIdx === -1) {
39285
- throw new Error("Start or end point not found in the grid");
39285
+ function findPath(start, end, grid, obstacles, existingPath, newStart, newEnd) {
39286
+ const startRowIndex = grid.findIndex((row2) => row2.some((point5) => point5.barelyEqual(start)));
39287
+ if (startRowIndex === -1) {
39288
+ throw new Error("Start point not found in the grid row");
39289
+ }
39290
+ const startPointIndex = grid[startRowIndex].findIndex((point5) => point5.barelyEqual(start));
39291
+ if (startPointIndex === -1) {
39292
+ throw new Error("Start point not found in the grid column");
39293
+ }
39294
+ const endRowIndex = grid.findIndex((row2) => row2.some((point5) => point5.barelyEqual(end)));
39295
+ if (endRowIndex === -1) {
39296
+ throw new Error("End point not found in the grid row");
39297
+ }
39298
+ const endPointIndex = grid[endRowIndex].findIndex((point5) => point5.barelyEqual(end));
39299
+ if (endPointIndex === -1) {
39300
+ throw new Error("End point not found in the grid column");
39286
39301
  }
39287
- const startPointIdx = grid[startIdx].findIndex((point5) => point5.barelyEqual(start));
39288
- const endPointIdx = grid[endIdx].findIndex((point5) => point5.barelyEqual(end));
39289
39302
  const endNode = {
39290
39303
  point: end,
39291
- xGrid: endIdx,
39292
- yGrid: endPointIdx,
39304
+ xGrid: endRowIndex,
39305
+ yGrid: endPointIndex,
39293
39306
  costSoFar: 0,
39294
39307
  heuristic: 0,
39295
39308
  toFinish: 0
@@ -39297,53 +39310,72 @@ function findPath(start, end, grid, obstacles, newStart, newEnd) {
39297
39310
  const startNode = {
39298
39311
  point: start,
39299
39312
  costSoFar: 0,
39300
- heuristic: heuristic({ point: start, xGrid: startIdx, yGrid: startPointIdx }, endNode),
39301
- toFinish: heuristic({ point: start, xGrid: startIdx, yGrid: startPointIdx }, endNode),
39302
- xGrid: startIdx,
39303
- yGrid: startPointIdx
39313
+ heuristic: heuristic({ point: start, xGrid: startRowIndex, yGrid: startPointIndex }, endNode),
39314
+ toFinish: heuristic({ point: start, xGrid: startRowIndex, yGrid: startPointIndex }, endNode),
39315
+ xGrid: startRowIndex,
39316
+ yGrid: startPointIndex
39304
39317
  };
39305
39318
  const openSet = [startNode];
39306
39319
  const closedSet = new Set;
39307
39320
  while (openSet.length > 0) {
39308
39321
  openSet.sort((aa, bb) => aa.toFinish - bb.toFinish);
39309
39322
  const current = openSet.shift();
39323
+ const currentKey = `${current.point.x},${current.point.y}`;
39310
39324
  if (current.point.barelyEqual(end)) {
39311
39325
  const path2 = reconstructPath(current);
39312
39326
  return path2;
39313
39327
  }
39314
- closedSet.add(current.point);
39328
+ closedSet.add(currentKey);
39315
39329
  const neighbors = getNeighbors(current, grid, obstacles);
39316
39330
  for (const neighbor of neighbors) {
39317
- if (closedSet.has(neighbor.point)) {
39331
+ const neighborKey = `${neighbor.point.x},${neighbor.point.y}`;
39332
+ if (closedSet.has(neighborKey) || existingPath.has(neighborKey) && !neighbor.point.barelyEqual(end)) {
39318
39333
  continue;
39319
39334
  }
39320
39335
  const extraCost = isChangingDirection(current, neighbor, newStart, newEnd);
39321
- const tentativeCost = current.costSoFar + 1;
39322
- if (!openSet.some((node2) => node2.point.barelyEqual(neighbor.point) && node2.costSoFar <= tentativeCost)) {
39323
- neighbor.costSoFar = tentativeCost + extraCost;
39324
- neighbor.heuristic = heuristic(neighbor, endNode);
39325
- neighbor.toFinish = neighbor.costSoFar + neighbor.heuristic;
39326
- openSet.push(neighbor);
39336
+ const pathOverlapCost = existingPath.has(neighborKey) ? 1000 : 0;
39337
+ const tentativeCost = current.costSoFar + 1 + pathOverlapCost;
39338
+ let existingNodeInOpenSet = openSet.find((node2) => node2.point.barelyEqual(neighbor.point));
39339
+ if (!existingNodeInOpenSet || tentativeCost < existingNodeInOpenSet.costSoFar) {
39340
+ if (existingNodeInOpenSet) {
39341
+ existingNodeInOpenSet.costSoFar = tentativeCost + extraCost;
39342
+ existingNodeInOpenSet.heuristic = heuristic(neighbor, endNode);
39343
+ existingNodeInOpenSet.toFinish = existingNodeInOpenSet.costSoFar + existingNodeInOpenSet.heuristic;
39344
+ existingNodeInOpenSet.parent = current;
39345
+ } else {
39346
+ neighbor.costSoFar = tentativeCost + extraCost;
39347
+ neighbor.heuristic = heuristic(neighbor, endNode);
39348
+ neighbor.toFinish = neighbor.costSoFar + neighbor.heuristic;
39349
+ openSet.push(neighbor);
39350
+ }
39327
39351
  }
39328
39352
  }
39329
39353
  }
39330
39354
  return;
39331
39355
  }
39332
39356
  function findPathPoints(points, grid, obstacles, newStart, newEnd) {
39333
- const pathPoints = [];
39357
+ const finalPath = [];
39358
+ const existingPathSegments = new Set;
39359
+ if (points.length > 0) {
39360
+ finalPath.push(points[0]);
39361
+ const startKey = `${points[0].x},${points[0].y}`;
39362
+ existingPathSegments.add(startKey);
39363
+ }
39334
39364
  for (let i = 0;i < points.length - 1; i += 1) {
39335
- const segmentPath = findPath(points[i], points[i + 1], grid, obstacles, newStart, newEnd);
39336
- if (segmentPath) {
39337
- pathPoints.push(...segmentPath.slice(0, -1));
39365
+ const segmentPath = findPath(points[i], points[i + 1], grid, obstacles, existingPathSegments, newStart, newEnd);
39366
+ if (segmentPath && segmentPath.length > 0) {
39367
+ for (let j = 1;j < segmentPath.length; j++) {
39368
+ const point5 = segmentPath[j];
39369
+ const key = `${point5.x},${point5.y}`;
39370
+ finalPath.push(point5);
39371
+ existingPathSegments.add(key);
39372
+ }
39338
39373
  } else {
39339
39374
  points.splice(i + 1, 1);
39340
39375
  i--;
39341
39376
  }
39342
39377
  }
39343
- if (pathPoints.length !== 0) {
39344
- pathPoints.push(points[points.length - 1]);
39345
- }
39346
- return pathPoints;
39378
+ return finalPath;
39347
39379
  }
39348
39380
  function reducePoints(points) {
39349
39381
  const uniquePoints = new Map;
@@ -39354,6 +39386,12 @@ function reducePoints(points) {
39354
39386
  if (uniquePoints.has(key)) {
39355
39387
  const loopStartIndex = uniquePoints.get(key);
39356
39388
  result.splice(loopStartIndex + 1);
39389
+ const removedPoints = points.slice(loopStartIndex + 1, i + 1);
39390
+ removedPoints.forEach((p3) => {
39391
+ uniquePoints.delete(`${p3.x},${p3.y}`);
39392
+ });
39393
+ uniquePoints.set(key, result.length);
39394
+ result.push(point5);
39357
39395
  } else {
39358
39396
  uniquePoints.set(key, result.length);
39359
39397
  result.push(point5);
@@ -39363,19 +39401,32 @@ function reducePoints(points) {
39363
39401
  }
39364
39402
  function getLines(pathPoints) {
39365
39403
  const lines = [];
39404
+ if (pathPoints.length < 2) {
39405
+ return [];
39406
+ }
39366
39407
  const reducedPoints = reducePoints(pathPoints);
39408
+ if (reducedPoints.length < 2) {
39409
+ return [];
39410
+ }
39367
39411
  let startPoint = reducedPoints[0];
39368
- for (let i = 1;i < reducedPoints.length - 1; i += 1) {
39412
+ for (let i = 1;i < reducedPoints.length; i += 1) {
39369
39413
  const prevPoint = reducedPoints[i - 1];
39370
39414
  const currPoint = reducedPoints[i];
39371
- const nextPoint = reducedPoints[i + 1];
39372
- if (prevPoint.x !== nextPoint.x && prevPoint.y !== nextPoint.y) {
39415
+ const nextPoint = i + 1 < reducedPoints.length ? reducedPoints[i + 1] : null;
39416
+ if (!nextPoint || prevPoint.x !== nextPoint.x && prevPoint.y !== nextPoint.y) {
39373
39417
  lines.push(new Line(startPoint, currPoint));
39374
39418
  startPoint = currPoint;
39375
39419
  }
39376
39420
  }
39377
- if (lines.length > 0) {
39378
- lines.push(new Line(startPoint, pathPoints[pathPoints.length - 1]));
39421
+ if (lines.length === 0 && reducedPoints.length > 1) {
39422
+ lines.push(new Line(reducedPoints[0], reducedPoints[reducedPoints.length - 1]));
39423
+ } else if (lines.length > 0) {
39424
+ const lastLine = lines[lines.length - 1];
39425
+ const lastPointInLines = lastLine.getEndPoint();
39426
+ const lastPointInReduced = reducedPoints[reducedPoints.length - 1];
39427
+ if (!lastPointInLines.barelyEqual(lastPointInReduced)) {
39428
+ lines.push(new Line(lastPointInLines, lastPointInReduced));
39429
+ }
39379
39430
  }
39380
39431
  return lines;
39381
39432
  }