@esengine/pathfinding 13.0.0 → 13.2.0

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.
@@ -1,9 +1,11 @@
1
1
  import {
2
2
  EMPTY_PROGRESS,
3
- PathfindingState,
3
+ PathfindingState
4
+ } from "./chunk-YKA3PWU3.js";
5
+ import {
4
6
  __name,
5
7
  __publicField
6
- } from "./chunk-GTFFYRZM.js";
8
+ } from "./chunk-T626JPC7.js";
7
9
 
8
10
  // src/core/IPathfinding.ts
9
11
  function createPoint(x, y) {
@@ -1612,903 +1614,6 @@ function createCombinedSmoother(curveSegments, tension) {
1612
1614
  }
1613
1615
  __name(createCombinedSmoother, "createCombinedSmoother");
1614
1616
 
1615
- // src/avoidance/ILocalAvoidance.ts
1616
- var DEFAULT_ORCA_CONFIG = {
1617
- defaultTimeHorizon: 2,
1618
- defaultTimeHorizonObst: 1,
1619
- timeStep: 1 / 60,
1620
- epsilon: 1e-5
1621
- };
1622
- var DEFAULT_AGENT_PARAMS = {
1623
- radius: 0.5,
1624
- maxSpeed: 5,
1625
- neighborDist: 15,
1626
- maxNeighbors: 10,
1627
- timeHorizon: 2,
1628
- timeHorizonObst: 1
1629
- };
1630
-
1631
- // src/avoidance/LinearProgram.ts
1632
- import { Vector2 } from "@esengine/ecs-framework-math";
1633
- var EPSILON = 1e-5;
1634
- var { dot, det, lengthSq } = Vector2;
1635
- function linearProgram1(lines, lineNo, radius, optVelocity, directionOpt, result) {
1636
- const line = lines[lineNo];
1637
- const dotProduct = dot(line.point, line.direction);
1638
- const discriminant = dotProduct * dotProduct + radius * radius - lengthSq(line.point);
1639
- if (discriminant < 0) {
1640
- return false;
1641
- }
1642
- const sqrtDiscriminant = Math.sqrt(discriminant);
1643
- let tLeft = -dotProduct - sqrtDiscriminant;
1644
- let tRight = -dotProduct + sqrtDiscriminant;
1645
- for (let i = 0; i < lineNo; i++) {
1646
- const constraint = lines[i];
1647
- const denominator = det(line.direction, constraint.direction);
1648
- const numerator = det(constraint.direction, {
1649
- x: line.point.x - constraint.point.x,
1650
- y: line.point.y - constraint.point.y
1651
- });
1652
- if (Math.abs(denominator) <= EPSILON) {
1653
- if (numerator < 0) {
1654
- return false;
1655
- }
1656
- continue;
1657
- }
1658
- const t2 = numerator / denominator;
1659
- if (denominator >= 0) {
1660
- tRight = Math.min(tRight, t2);
1661
- } else {
1662
- tLeft = Math.max(tLeft, t2);
1663
- }
1664
- if (tLeft > tRight) {
1665
- return false;
1666
- }
1667
- }
1668
- let t;
1669
- if (directionOpt) {
1670
- if (dot(optVelocity, line.direction) > 0) {
1671
- t = tRight;
1672
- } else {
1673
- t = tLeft;
1674
- }
1675
- } else {
1676
- t = dot(line.direction, {
1677
- x: optVelocity.x - line.point.x,
1678
- y: optVelocity.y - line.point.y
1679
- });
1680
- if (t < tLeft) {
1681
- t = tLeft;
1682
- } else if (t > tRight) {
1683
- t = tRight;
1684
- }
1685
- }
1686
- result.x = line.point.x + t * line.direction.x;
1687
- result.y = line.point.y + t * line.direction.y;
1688
- return true;
1689
- }
1690
- __name(linearProgram1, "linearProgram1");
1691
- function linearProgram2(lines, radius, optVelocity, directionOpt, result) {
1692
- if (directionOpt) {
1693
- result.x = optVelocity.x * radius;
1694
- result.y = optVelocity.y * radius;
1695
- } else if (lengthSq(optVelocity) > radius * radius) {
1696
- const len2 = Math.sqrt(lengthSq(optVelocity));
1697
- result.x = optVelocity.x / len2 * radius;
1698
- result.y = optVelocity.y / len2 * radius;
1699
- } else {
1700
- result.x = optVelocity.x;
1701
- result.y = optVelocity.y;
1702
- }
1703
- for (let i = 0; i < lines.length; i++) {
1704
- const line = lines[i];
1705
- const detVal = det(line.direction, {
1706
- x: line.point.x - result.x,
1707
- y: line.point.y - result.y
1708
- });
1709
- if (detVal > 0) {
1710
- const tempResult = result.clone();
1711
- if (!linearProgram1(lines, i, radius, optVelocity, directionOpt, result)) {
1712
- result.copy(tempResult);
1713
- return i;
1714
- }
1715
- }
1716
- }
1717
- return lines.length;
1718
- }
1719
- __name(linearProgram2, "linearProgram2");
1720
- function linearProgram3(lines, numObstLines, beginLine, radius, result) {
1721
- let distance = 0;
1722
- for (let i = beginLine; i < lines.length; i++) {
1723
- const line = lines[i];
1724
- if (det(line.direction, {
1725
- x: line.point.x - result.x,
1726
- y: line.point.y - result.y
1727
- }) > distance) {
1728
- const projLines = [];
1729
- for (let j = 0; j < numObstLines; j++) {
1730
- projLines.push(lines[j]);
1731
- }
1732
- for (let j = numObstLines; j < i; j++) {
1733
- const line1 = lines[j];
1734
- const line2 = lines[i];
1735
- let newLine;
1736
- const determinant = det(line1.direction, line2.direction);
1737
- if (Math.abs(determinant) <= EPSILON) {
1738
- if (dot(line1.direction, line2.direction) > 0) {
1739
- continue;
1740
- }
1741
- newLine = {
1742
- point: {
1743
- x: 0.5 * (line1.point.x + line2.point.x),
1744
- y: 0.5 * (line1.point.y + line2.point.y)
1745
- },
1746
- direction: {
1747
- x: 0,
1748
- y: 0
1749
- }
1750
- };
1751
- } else {
1752
- const diff = {
1753
- x: line1.point.x - line2.point.x,
1754
- y: line1.point.y - line2.point.y
1755
- };
1756
- const t = det(line2.direction, diff) / determinant;
1757
- newLine = {
1758
- point: {
1759
- x: line1.point.x + t * line1.direction.x,
1760
- y: line1.point.y + t * line1.direction.y
1761
- },
1762
- direction: {
1763
- x: 0,
1764
- y: 0
1765
- }
1766
- };
1767
- }
1768
- const dirDiff = {
1769
- x: line1.direction.x - line2.direction.x,
1770
- y: line1.direction.y - line2.direction.y
1771
- };
1772
- const dirLen = Math.sqrt(lengthSq(dirDiff));
1773
- if (dirLen > EPSILON) {
1774
- newLine.direction.x = dirDiff.x / dirLen;
1775
- newLine.direction.y = dirDiff.y / dirLen;
1776
- }
1777
- projLines.push(newLine);
1778
- }
1779
- const tempResult = result.clone();
1780
- const optVelocity = {
1781
- x: -lines[i].direction.y,
1782
- y: lines[i].direction.x
1783
- };
1784
- if (linearProgram2(projLines, radius, optVelocity, true, result) < projLines.length) {
1785
- result.copy(tempResult);
1786
- }
1787
- distance = det(lines[i].direction, {
1788
- x: lines[i].point.x - result.x,
1789
- y: lines[i].point.y - result.y
1790
- });
1791
- }
1792
- }
1793
- }
1794
- __name(linearProgram3, "linearProgram3");
1795
- function solveORCALinearProgram(lines, numObstLines, maxSpeed, preferredVelocity) {
1796
- const result = new Vector2();
1797
- const lineFail = linearProgram2(lines, maxSpeed, preferredVelocity, false, result);
1798
- if (lineFail < lines.length) {
1799
- linearProgram3(lines, numObstLines, lineFail, maxSpeed, result);
1800
- }
1801
- return result;
1802
- }
1803
- __name(solveORCALinearProgram, "solveORCALinearProgram");
1804
-
1805
- // src/avoidance/ORCASolver.ts
1806
- import { Vector2 as Vector22 } from "@esengine/ecs-framework-math";
1807
-
1808
- // src/avoidance/ObstacleBuilder.ts
1809
- var EPSILON2 = 1e-5;
1810
- function leftOf(p1, p2, p3) {
1811
- return (p1.x - p3.x) * (p2.y - p1.y) - (p1.y - p3.y) * (p2.x - p1.x);
1812
- }
1813
- __name(leftOf, "leftOf");
1814
- function createObstacleVertices(vertices, startId = 0) {
1815
- const n = vertices.length;
1816
- if (n < 2) {
1817
- return [];
1818
- }
1819
- const obstacleVertices = [];
1820
- for (let i = 0; i < n; i++) {
1821
- obstacleVertices.push({
1822
- point: {
1823
- x: vertices[i].x,
1824
- y: vertices[i].y
1825
- },
1826
- direction: {
1827
- x: 0,
1828
- y: 0
1829
- },
1830
- next: null,
1831
- previous: null,
1832
- isConvex: false,
1833
- id: startId + i
1834
- });
1835
- }
1836
- for (let i = 0; i < n; i++) {
1837
- const curr = obstacleVertices[i];
1838
- const next = obstacleVertices[(i + 1) % n];
1839
- const prev = obstacleVertices[(i + n - 1) % n];
1840
- curr.next = next;
1841
- curr.previous = prev;
1842
- const dx = next.point.x - curr.point.x;
1843
- const dy = next.point.y - curr.point.y;
1844
- const edgeLen = Math.sqrt(dx * dx + dy * dy);
1845
- if (edgeLen > EPSILON2) {
1846
- curr.direction = {
1847
- x: dx / edgeLen,
1848
- y: dy / edgeLen
1849
- };
1850
- } else {
1851
- curr.direction = {
1852
- x: 1,
1853
- y: 0
1854
- };
1855
- }
1856
- }
1857
- for (let i = 0; i < n; i++) {
1858
- const curr = obstacleVertices[i];
1859
- const prev = curr.previous;
1860
- const next = curr.next;
1861
- curr.isConvex = leftOf(prev.point, curr.point, next.point) >= 0;
1862
- }
1863
- return obstacleVertices;
1864
- }
1865
- __name(createObstacleVertices, "createObstacleVertices");
1866
- function buildObstacleVertices(obstacles) {
1867
- const allVertices = [];
1868
- let nextId = 0;
1869
- for (const obstacle of obstacles) {
1870
- const vertices = createObstacleVertices(obstacle.vertices, nextId);
1871
- allVertices.push(...vertices);
1872
- nextId += vertices.length;
1873
- }
1874
- return allVertices;
1875
- }
1876
- __name(buildObstacleVertices, "buildObstacleVertices");
1877
-
1878
- // src/avoidance/ORCASolver.ts
1879
- var EPSILON3 = 1e-5;
1880
- var { det: det2, dot: dot2, lengthSq: lengthSq2, len } = Vector22;
1881
- function normalize(v) {
1882
- const length = len(v);
1883
- if (length < EPSILON3) {
1884
- return {
1885
- x: 0,
1886
- y: 0
1887
- };
1888
- }
1889
- return {
1890
- x: v.x / length,
1891
- y: v.y / length
1892
- };
1893
- }
1894
- __name(normalize, "normalize");
1895
- var _ORCASolver = class _ORCASolver {
1896
- constructor(config = {}) {
1897
- __publicField(this, "config");
1898
- this.config = {
1899
- ...DEFAULT_ORCA_CONFIG,
1900
- ...config
1901
- };
1902
- }
1903
- /**
1904
- * @zh 计算代理的新速度
1905
- * @en Compute new velocity for agent
1906
- *
1907
- * @param agent - @zh 当前代理 @en Current agent
1908
- * @param neighbors - @zh 邻近代理列表 @en List of neighboring agents
1909
- * @param obstacles - @zh 障碍物列表 @en List of obstacles
1910
- * @param deltaTime - @zh 时间步长 @en Time step
1911
- * @returns @zh 计算得到的新速度 @en Computed new velocity
1912
- */
1913
- computeNewVelocity(agent, neighbors, obstacles, deltaTime) {
1914
- const orcaLines = [];
1915
- const obstacleVertices = buildObstacleVertices(obstacles);
1916
- const numObstLines = this.createObstacleORCALines(agent, obstacleVertices, orcaLines);
1917
- this.createAgentORCALines(agent, neighbors, deltaTime, orcaLines);
1918
- return solveORCALinearProgram(orcaLines, numObstLines, agent.maxSpeed, agent.preferredVelocity);
1919
- }
1920
- /**
1921
- * @zh 创建代理间的 ORCA 约束线
1922
- * @en Create ORCA constraint lines for agent-agent avoidance
1923
- */
1924
- createAgentORCALines(agent, neighbors, deltaTime, orcaLines) {
1925
- const invTimeHorizon = 1 / agent.timeHorizon;
1926
- for (const other of neighbors) {
1927
- if (other.id === agent.id) continue;
1928
- const relativePosition = {
1929
- x: other.position.x - agent.position.x,
1930
- y: other.position.y - agent.position.y
1931
- };
1932
- const relativeVelocity = {
1933
- x: agent.velocity.x - other.velocity.x,
1934
- y: agent.velocity.y - other.velocity.y
1935
- };
1936
- const distSq = lengthSq2(relativePosition);
1937
- const combinedRadius = agent.radius + other.radius;
1938
- const combinedRadiusSq = combinedRadius * combinedRadius;
1939
- const line = {
1940
- point: {
1941
- x: 0,
1942
- y: 0
1943
- },
1944
- direction: {
1945
- x: 0,
1946
- y: 0
1947
- }
1948
- };
1949
- let u;
1950
- if (distSq > combinedRadiusSq) {
1951
- const w = {
1952
- x: relativeVelocity.x - invTimeHorizon * relativePosition.x,
1953
- y: relativeVelocity.y - invTimeHorizon * relativePosition.y
1954
- };
1955
- const wLengthSq = lengthSq2(w);
1956
- const dotProduct1 = dot2(w, relativePosition);
1957
- if (dotProduct1 < 0 && dotProduct1 * dotProduct1 > combinedRadiusSq * wLengthSq) {
1958
- const wLength = Math.sqrt(wLengthSq);
1959
- const unitW = normalize(w);
1960
- line.direction = {
1961
- x: unitW.y,
1962
- y: -unitW.x
1963
- };
1964
- u = {
1965
- x: (combinedRadius * invTimeHorizon - wLength) * unitW.x,
1966
- y: (combinedRadius * invTimeHorizon - wLength) * unitW.y
1967
- };
1968
- } else {
1969
- const leg = Math.sqrt(distSq - combinedRadiusSq);
1970
- if (det2(relativePosition, w) > 0) {
1971
- line.direction = {
1972
- x: (relativePosition.x * leg - relativePosition.y * combinedRadius) / distSq,
1973
- y: (relativePosition.x * combinedRadius + relativePosition.y * leg) / distSq
1974
- };
1975
- } else {
1976
- line.direction = {
1977
- x: -(relativePosition.x * leg + relativePosition.y * combinedRadius) / distSq,
1978
- y: -(-relativePosition.x * combinedRadius + relativePosition.y * leg) / distSq
1979
- };
1980
- }
1981
- const dotProduct2 = dot2(relativeVelocity, line.direction);
1982
- u = {
1983
- x: dotProduct2 * line.direction.x - relativeVelocity.x,
1984
- y: dotProduct2 * line.direction.y - relativeVelocity.y
1985
- };
1986
- }
1987
- } else {
1988
- const invTimeStep = 1 / deltaTime;
1989
- const w = {
1990
- x: relativeVelocity.x - invTimeStep * relativePosition.x,
1991
- y: relativeVelocity.y - invTimeStep * relativePosition.y
1992
- };
1993
- const wLength = len(w);
1994
- const unitW = wLength > EPSILON3 ? {
1995
- x: w.x / wLength,
1996
- y: w.y / wLength
1997
- } : {
1998
- x: 1,
1999
- y: 0
2000
- };
2001
- line.direction = {
2002
- x: unitW.y,
2003
- y: -unitW.x
2004
- };
2005
- u = {
2006
- x: (combinedRadius * invTimeStep - wLength) * unitW.x,
2007
- y: (combinedRadius * invTimeStep - wLength) * unitW.y
2008
- };
2009
- }
2010
- line.point = {
2011
- x: agent.velocity.x + 0.5 * u.x,
2012
- y: agent.velocity.y + 0.5 * u.y
2013
- };
2014
- orcaLines.push(line);
2015
- }
2016
- }
2017
- /**
2018
- * @zh 创建障碍物的 ORCA 约束线
2019
- * @en Create ORCA constraint lines for obstacle avoidance
2020
- */
2021
- createObstacleORCALines(agent, obstacleVertices, orcaLines) {
2022
- const invTimeHorizonObst = 1 / agent.timeHorizonObst;
2023
- const radiusSq = agent.radius * agent.radius;
2024
- let numObstLines = 0;
2025
- for (const obstacle1 of obstacleVertices) {
2026
- const obstacle2 = obstacle1.next;
2027
- const relativePosition1 = {
2028
- x: obstacle1.point.x - agent.position.x,
2029
- y: obstacle1.point.y - agent.position.y
2030
- };
2031
- const relativePosition2 = {
2032
- x: obstacle2.point.x - agent.position.x,
2033
- y: obstacle2.point.y - agent.position.y
2034
- };
2035
- const obstacleVector = {
2036
- x: obstacle2.point.x - obstacle1.point.x,
2037
- y: obstacle2.point.y - obstacle1.point.y
2038
- };
2039
- const signedDistToEdge = det2(obstacleVector, relativePosition1);
2040
- if (signedDistToEdge < -EPSILON3) {
2041
- continue;
2042
- }
2043
- let alreadyCovered = false;
2044
- for (const existingLine of orcaLines) {
2045
- const scaledRelPos1 = {
2046
- x: invTimeHorizonObst * relativePosition1.x - existingLine.point.x,
2047
- y: invTimeHorizonObst * relativePosition1.y - existingLine.point.y
2048
- };
2049
- const scaledRelPos2 = {
2050
- x: invTimeHorizonObst * relativePosition2.x - existingLine.point.x,
2051
- y: invTimeHorizonObst * relativePosition2.y - existingLine.point.y
2052
- };
2053
- if (det2(scaledRelPos1, existingLine.direction) - invTimeHorizonObst * agent.radius >= -EPSILON3 && det2(scaledRelPos2, existingLine.direction) - invTimeHorizonObst * agent.radius >= -EPSILON3) {
2054
- alreadyCovered = true;
2055
- break;
2056
- }
2057
- }
2058
- if (alreadyCovered) {
2059
- continue;
2060
- }
2061
- const distSq1 = lengthSq2(relativePosition1);
2062
- const distSq2 = lengthSq2(relativePosition2);
2063
- const obstacleVectorSq = lengthSq2(obstacleVector);
2064
- const s = obstacleVectorSq > EPSILON3 ? -dot2(relativePosition1, obstacleVector) / obstacleVectorSq : 0;
2065
- const distSqLineToEdge = lengthSq2({
2066
- x: -relativePosition1.x - s * obstacleVector.x,
2067
- y: -relativePosition1.y - s * obstacleVector.y
2068
- });
2069
- const line = {
2070
- point: {
2071
- x: 0,
2072
- y: 0
2073
- },
2074
- direction: {
2075
- x: 0,
2076
- y: 0
2077
- }
2078
- };
2079
- if (s < 0 && distSq1 <= radiusSq) {
2080
- if (obstacle1.isConvex) {
2081
- line.point = {
2082
- x: 0,
2083
- y: 0
2084
- };
2085
- line.direction = normalize({
2086
- x: -relativePosition1.y,
2087
- y: relativePosition1.x
2088
- });
2089
- orcaLines.push(line);
2090
- numObstLines++;
2091
- }
2092
- continue;
2093
- }
2094
- if (s > 1 && distSq2 <= radiusSq) {
2095
- if (obstacle2.isConvex && det2(relativePosition2, obstacle2.direction) >= 0) {
2096
- line.point = {
2097
- x: 0,
2098
- y: 0
2099
- };
2100
- line.direction = normalize({
2101
- x: -relativePosition2.y,
2102
- y: relativePosition2.x
2103
- });
2104
- orcaLines.push(line);
2105
- numObstLines++;
2106
- }
2107
- continue;
2108
- }
2109
- if (s >= 0 && s <= 1 && distSqLineToEdge <= radiusSq) {
2110
- line.point = {
2111
- x: 0,
2112
- y: 0
2113
- };
2114
- line.direction = {
2115
- x: -obstacle1.direction.x,
2116
- y: -obstacle1.direction.y
2117
- };
2118
- orcaLines.push(line);
2119
- numObstLines++;
2120
- continue;
2121
- }
2122
- let obs1 = obstacle1;
2123
- let obs2 = obstacle2;
2124
- let leftLegDirection;
2125
- let rightLegDirection;
2126
- if (s < 0 && distSqLineToEdge <= radiusSq) {
2127
- if (!obstacle1.isConvex) continue;
2128
- obs2 = obstacle1;
2129
- const leg1 = Math.sqrt(Math.max(0, distSq1 - radiusSq));
2130
- leftLegDirection = {
2131
- x: (relativePosition1.x * leg1 - relativePosition1.y * agent.radius) / distSq1,
2132
- y: (relativePosition1.x * agent.radius + relativePosition1.y * leg1) / distSq1
2133
- };
2134
- rightLegDirection = {
2135
- x: (relativePosition1.x * leg1 + relativePosition1.y * agent.radius) / distSq1,
2136
- y: (-relativePosition1.x * agent.radius + relativePosition1.y * leg1) / distSq1
2137
- };
2138
- } else if (s > 1 && distSqLineToEdge <= radiusSq) {
2139
- if (!obstacle2.isConvex) continue;
2140
- obs1 = obstacle2;
2141
- const leg2 = Math.sqrt(Math.max(0, distSq2 - radiusSq));
2142
- leftLegDirection = {
2143
- x: (relativePosition2.x * leg2 - relativePosition2.y * agent.radius) / distSq2,
2144
- y: (relativePosition2.x * agent.radius + relativePosition2.y * leg2) / distSq2
2145
- };
2146
- rightLegDirection = {
2147
- x: (relativePosition2.x * leg2 + relativePosition2.y * agent.radius) / distSq2,
2148
- y: (-relativePosition2.x * agent.radius + relativePosition2.y * leg2) / distSq2
2149
- };
2150
- } else {
2151
- if (obstacle1.isConvex) {
2152
- const leg1 = Math.sqrt(Math.max(0, distSq1 - radiusSq));
2153
- leftLegDirection = {
2154
- x: (relativePosition1.x * leg1 - relativePosition1.y * agent.radius) / distSq1,
2155
- y: (relativePosition1.x * agent.radius + relativePosition1.y * leg1) / distSq1
2156
- };
2157
- } else {
2158
- leftLegDirection = {
2159
- x: -obstacle1.direction.x,
2160
- y: -obstacle1.direction.y
2161
- };
2162
- }
2163
- if (obstacle2.isConvex) {
2164
- const leg2 = Math.sqrt(Math.max(0, distSq2 - radiusSq));
2165
- rightLegDirection = {
2166
- x: (relativePosition2.x * leg2 + relativePosition2.y * agent.radius) / distSq2,
2167
- y: (-relativePosition2.x * agent.radius + relativePosition2.y * leg2) / distSq2
2168
- };
2169
- } else {
2170
- rightLegDirection = {
2171
- x: obstacle1.direction.x,
2172
- y: obstacle1.direction.y
2173
- };
2174
- }
2175
- }
2176
- const leftNeighbor = obs1.previous;
2177
- let isLeftLegForeign = false;
2178
- let isRightLegForeign = false;
2179
- if (obs1.isConvex) {
2180
- const negLeftNeighborDir = {
2181
- x: -leftNeighbor.direction.x,
2182
- y: -leftNeighbor.direction.y
2183
- };
2184
- if (det2(leftLegDirection, negLeftNeighborDir) >= 0) {
2185
- leftLegDirection = negLeftNeighborDir;
2186
- isLeftLegForeign = true;
2187
- }
2188
- }
2189
- if (obs2.isConvex) {
2190
- if (det2(rightLegDirection, obs2.direction) <= 0) {
2191
- rightLegDirection = {
2192
- x: obs2.direction.x,
2193
- y: obs2.direction.y
2194
- };
2195
- isRightLegForeign = true;
2196
- }
2197
- }
2198
- const leftCutoff = {
2199
- x: invTimeHorizonObst * (obs1.point.x - agent.position.x),
2200
- y: invTimeHorizonObst * (obs1.point.y - agent.position.y)
2201
- };
2202
- const rightCutoff = {
2203
- x: invTimeHorizonObst * (obs2.point.x - agent.position.x),
2204
- y: invTimeHorizonObst * (obs2.point.y - agent.position.y)
2205
- };
2206
- const cutoffVector = {
2207
- x: rightCutoff.x - leftCutoff.x,
2208
- y: rightCutoff.y - leftCutoff.y
2209
- };
2210
- const sameVertex = obs1 === obs2;
2211
- const cutoffVectorSq = lengthSq2(cutoffVector);
2212
- const t = sameVertex ? 0.5 : cutoffVectorSq > EPSILON3 ? dot2({
2213
- x: agent.velocity.x - leftCutoff.x,
2214
- y: agent.velocity.y - leftCutoff.y
2215
- }, cutoffVector) / cutoffVectorSq : 0.5;
2216
- const tLeft = dot2({
2217
- x: agent.velocity.x - leftCutoff.x,
2218
- y: agent.velocity.y - leftCutoff.y
2219
- }, leftLegDirection);
2220
- const tRight = dot2({
2221
- x: agent.velocity.x - rightCutoff.x,
2222
- y: agent.velocity.y - rightCutoff.y
2223
- }, rightLegDirection);
2224
- if (t < 0 && tLeft < 0 || sameVertex && tLeft < 0 && tRight < 0) {
2225
- const unitW = normalize({
2226
- x: agent.velocity.x - leftCutoff.x,
2227
- y: agent.velocity.y - leftCutoff.y
2228
- });
2229
- line.direction = {
2230
- x: unitW.y,
2231
- y: -unitW.x
2232
- };
2233
- line.point = {
2234
- x: leftCutoff.x + agent.radius * invTimeHorizonObst * unitW.x,
2235
- y: leftCutoff.y + agent.radius * invTimeHorizonObst * unitW.y
2236
- };
2237
- orcaLines.push(line);
2238
- numObstLines++;
2239
- continue;
2240
- }
2241
- if (t > 1 && tRight < 0) {
2242
- const unitW = normalize({
2243
- x: agent.velocity.x - rightCutoff.x,
2244
- y: agent.velocity.y - rightCutoff.y
2245
- });
2246
- line.direction = {
2247
- x: unitW.y,
2248
- y: -unitW.x
2249
- };
2250
- line.point = {
2251
- x: rightCutoff.x + agent.radius * invTimeHorizonObst * unitW.x,
2252
- y: rightCutoff.y + agent.radius * invTimeHorizonObst * unitW.y
2253
- };
2254
- orcaLines.push(line);
2255
- numObstLines++;
2256
- continue;
2257
- }
2258
- const distSqCutoff = t < 0 || t > 1 || sameVertex ? Infinity : lengthSq2({
2259
- x: agent.velocity.x - (leftCutoff.x + t * cutoffVector.x),
2260
- y: agent.velocity.y - (leftCutoff.y + t * cutoffVector.y)
2261
- });
2262
- const distSqLeft = tLeft < 0 ? Infinity : lengthSq2({
2263
- x: agent.velocity.x - (leftCutoff.x + tLeft * leftLegDirection.x),
2264
- y: agent.velocity.y - (leftCutoff.y + tLeft * leftLegDirection.y)
2265
- });
2266
- const distSqRight = tRight < 0 ? Infinity : lengthSq2({
2267
- x: agent.velocity.x - (rightCutoff.x + tRight * rightLegDirection.x),
2268
- y: agent.velocity.y - (rightCutoff.y + tRight * rightLegDirection.y)
2269
- });
2270
- if (distSqCutoff <= distSqLeft && distSqCutoff <= distSqRight) {
2271
- line.direction = {
2272
- x: -obs1.direction.x,
2273
- y: -obs1.direction.y
2274
- };
2275
- line.point = {
2276
- x: leftCutoff.x + agent.radius * invTimeHorizonObst * -line.direction.y,
2277
- y: leftCutoff.y + agent.radius * invTimeHorizonObst * line.direction.x
2278
- };
2279
- orcaLines.push(line);
2280
- numObstLines++;
2281
- continue;
2282
- }
2283
- if (distSqLeft <= distSqRight) {
2284
- if (isLeftLegForeign) {
2285
- continue;
2286
- }
2287
- line.direction = {
2288
- x: leftLegDirection.x,
2289
- y: leftLegDirection.y
2290
- };
2291
- line.point = {
2292
- x: leftCutoff.x + agent.radius * invTimeHorizonObst * -line.direction.y,
2293
- y: leftCutoff.y + agent.radius * invTimeHorizonObst * line.direction.x
2294
- };
2295
- orcaLines.push(line);
2296
- numObstLines++;
2297
- continue;
2298
- }
2299
- if (isRightLegForeign) {
2300
- continue;
2301
- }
2302
- line.direction = {
2303
- x: -rightLegDirection.x,
2304
- y: -rightLegDirection.y
2305
- };
2306
- line.point = {
2307
- x: rightCutoff.x + agent.radius * invTimeHorizonObst * -line.direction.y,
2308
- y: rightCutoff.y + agent.radius * invTimeHorizonObst * line.direction.x
2309
- };
2310
- orcaLines.push(line);
2311
- numObstLines++;
2312
- }
2313
- return numObstLines;
2314
- }
2315
- };
2316
- __name(_ORCASolver, "ORCASolver");
2317
- var ORCASolver = _ORCASolver;
2318
- function createORCASolver(config) {
2319
- return new ORCASolver(config);
2320
- }
2321
- __name(createORCASolver, "createORCASolver");
2322
-
2323
- // src/avoidance/KDTree.ts
2324
- var _KDTree = class _KDTree {
2325
- constructor() {
2326
- __publicField(this, "agents", []);
2327
- __publicField(this, "agentIndices", []);
2328
- __publicField(this, "nodes", []);
2329
- /**
2330
- * @zh 最大叶节点大小
2331
- * @en Maximum leaf size
2332
- */
2333
- __publicField(this, "maxLeafSize", 10);
2334
- }
2335
- /**
2336
- * @zh 构建 KD-Tree
2337
- * @en Build KD-Tree
2338
- */
2339
- build(agents) {
2340
- this.agents = agents;
2341
- this.agentIndices = [];
2342
- this.nodes = [];
2343
- if (agents.length === 0) {
2344
- return;
2345
- }
2346
- for (let i = 0; i < agents.length; i++) {
2347
- this.agentIndices.push(i);
2348
- }
2349
- this.buildRecursive(0, agents.length, 0);
2350
- }
2351
- /**
2352
- * @zh 递归构建 KD-Tree
2353
- * @en Recursively build KD-Tree
2354
- */
2355
- buildRecursive(begin, end, depth) {
2356
- const nodeIndex = this.nodes.length;
2357
- const node = {
2358
- agentIndex: -1,
2359
- splitValue: 0,
2360
- left: -1,
2361
- right: -1,
2362
- begin,
2363
- end,
2364
- minX: Infinity,
2365
- minY: Infinity,
2366
- maxX: -Infinity,
2367
- maxY: -Infinity
2368
- };
2369
- this.nodes.push(node);
2370
- for (let i = begin; i < end; i++) {
2371
- const agent = this.agents[this.agentIndices[i]];
2372
- node.minX = Math.min(node.minX, agent.position.x);
2373
- node.minY = Math.min(node.minY, agent.position.y);
2374
- node.maxX = Math.max(node.maxX, agent.position.x);
2375
- node.maxY = Math.max(node.maxY, agent.position.y);
2376
- }
2377
- const count = end - begin;
2378
- if (count <= this.maxLeafSize) {
2379
- return nodeIndex;
2380
- }
2381
- const splitDim = depth % 2;
2382
- if (splitDim === 0) {
2383
- this.sortByX(begin, end);
2384
- } else {
2385
- this.sortByY(begin, end);
2386
- }
2387
- const mid = Math.floor((begin + end) / 2);
2388
- const midAgent = this.agents[this.agentIndices[mid]];
2389
- node.splitValue = splitDim === 0 ? midAgent.position.x : midAgent.position.y;
2390
- node.left = this.buildRecursive(begin, mid, depth + 1);
2391
- node.right = this.buildRecursive(mid, end, depth + 1);
2392
- return nodeIndex;
2393
- }
2394
- /**
2395
- * @zh 按 X 坐标排序
2396
- * @en Sort by X coordinate
2397
- */
2398
- sortByX(begin, end) {
2399
- const indices = this.agentIndices;
2400
- const agents = this.agents;
2401
- for (let i = begin + 1; i < end; i++) {
2402
- const key = indices[i];
2403
- const keyX = agents[key].position.x;
2404
- let j = i - 1;
2405
- while (j >= begin && agents[indices[j]].position.x > keyX) {
2406
- indices[j + 1] = indices[j];
2407
- j--;
2408
- }
2409
- indices[j + 1] = key;
2410
- }
2411
- }
2412
- /**
2413
- * @zh 按 Y 坐标排序
2414
- * @en Sort by Y coordinate
2415
- */
2416
- sortByY(begin, end) {
2417
- const indices = this.agentIndices;
2418
- const agents = this.agents;
2419
- for (let i = begin + 1; i < end; i++) {
2420
- const key = indices[i];
2421
- const keyY = agents[key].position.y;
2422
- let j = i - 1;
2423
- while (j >= begin && agents[indices[j]].position.y > keyY) {
2424
- indices[j + 1] = indices[j];
2425
- j--;
2426
- }
2427
- indices[j + 1] = key;
2428
- }
2429
- }
2430
- /**
2431
- * @zh 查询邻居
2432
- * @en Query neighbors
2433
- */
2434
- queryNeighbors(position, radius, maxResults, excludeId) {
2435
- const results = [];
2436
- const radiusSq = radius * radius;
2437
- if (this.nodes.length === 0) {
2438
- return results;
2439
- }
2440
- this.queryRecursive(0, position, radiusSq, maxResults, excludeId, results);
2441
- results.sort((a, b) => a.distanceSq - b.distanceSq);
2442
- if (results.length > maxResults) {
2443
- results.length = maxResults;
2444
- }
2445
- return results;
2446
- }
2447
- /**
2448
- * @zh 递归查询
2449
- * @en Recursive query
2450
- */
2451
- queryRecursive(nodeIndex, position, radiusSq, maxResults, excludeId, results) {
2452
- const node = this.nodes[nodeIndex];
2453
- if (!node) return;
2454
- const closestX = Math.max(node.minX, Math.min(position.x, node.maxX));
2455
- const closestY = Math.max(node.minY, Math.min(position.y, node.maxY));
2456
- const dx = position.x - closestX;
2457
- const dy = position.y - closestY;
2458
- const distSqToBBox = dx * dx + dy * dy;
2459
- if (distSqToBBox > radiusSq) {
2460
- return;
2461
- }
2462
- if (node.left === -1 && node.right === -1) {
2463
- for (let i = node.begin; i < node.end; i++) {
2464
- const agentIndex = this.agentIndices[i];
2465
- const agent = this.agents[agentIndex];
2466
- if (excludeId !== void 0 && agent.id === excludeId) {
2467
- continue;
2468
- }
2469
- const adx = position.x - agent.position.x;
2470
- const ady = position.y - agent.position.y;
2471
- const distSq = adx * adx + ady * ady;
2472
- if (distSq < radiusSq) {
2473
- results.push({
2474
- agent,
2475
- distanceSq: distSq
2476
- });
2477
- }
2478
- }
2479
- return;
2480
- }
2481
- if (node.left !== -1) {
2482
- this.queryRecursive(node.left, position, radiusSq, maxResults, excludeId, results);
2483
- }
2484
- if (node.right !== -1) {
2485
- this.queryRecursive(node.right, position, radiusSq, maxResults, excludeId, results);
2486
- }
2487
- }
2488
- /**
2489
- * @zh 清空索引
2490
- * @en Clear the index
2491
- */
2492
- clear() {
2493
- this.agents = [];
2494
- this.agentIndices = [];
2495
- this.nodes = [];
2496
- }
2497
- /**
2498
- * @zh 获取代理数量
2499
- * @en Get agent count
2500
- */
2501
- get agentCount() {
2502
- return this.agents.length;
2503
- }
2504
- };
2505
- __name(_KDTree, "KDTree");
2506
- var KDTree = _KDTree;
2507
- function createKDTree() {
2508
- return new KDTree();
2509
- }
2510
- __name(createKDTree, "createKDTree");
2511
-
2512
1617
  export {
2513
1618
  createPoint,
2514
1619
  EMPTY_PATH_RESULT,
@@ -2540,13 +1645,6 @@ export {
2540
1645
  CombinedSmoother,
2541
1646
  createLineOfSightSmoother,
2542
1647
  createCatmullRomSmoother,
2543
- createCombinedSmoother,
2544
- DEFAULT_ORCA_CONFIG,
2545
- DEFAULT_AGENT_PARAMS,
2546
- solveORCALinearProgram,
2547
- ORCASolver,
2548
- createORCASolver,
2549
- KDTree,
2550
- createKDTree
1648
+ createCombinedSmoother
2551
1649
  };
2552
- //# sourceMappingURL=chunk-OA7ZZQMH.js.map
1650
+ //# sourceMappingURL=chunk-VNC2YAAL.js.map