@rxflow/manhattan 0.0.2-alpha.8 → 0.0.2

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.
Files changed (157) hide show
  1. package/README.md +214 -10
  2. package/esm/getManHattanPath.js +92 -69
  3. package/esm/obstacle/ObstacleMap.js +218 -99
  4. package/esm/obstacle/QuadTree.js +488 -0
  5. package/esm/options/resolver.js +147 -18
  6. package/esm/pathfinder/PathCache.js +278 -0
  7. package/esm/pathfinder/findRoute.js +98 -44
  8. package/esm/pathfinder/index.js +2 -1
  9. package/esm/svg/pathConverter.js +170 -1
  10. package/esm/utils/AdaptiveStepCalculator.js +252 -0
  11. package/esm/utils/ErrorRecovery.js +499 -0
  12. package/esm/utils/GlobalGrid.js +259 -0
  13. package/esm/utils/PerformanceMonitor.js +360 -0
  14. package/esm/utils/getAnchorPoints.js +0 -4
  15. package/esm/utils/grid.js +18 -13
  16. package/esm/utils/heuristics.js +144 -0
  17. package/esm/utils/index.js +7 -1
  18. package/esm/utils/pathProcessing.js +270 -0
  19. package/esm/utils/pathValidation.js +0 -1
  20. package/esm/utils/rect.js +11 -4
  21. package/esm/utils/route.js +18 -2
  22. package/package.json +10 -2
  23. package/cjs/geometry/Line.d.ts +0 -21
  24. package/cjs/geometry/Line.d.ts.map +0 -1
  25. package/cjs/geometry/Line.js +0 -88
  26. package/cjs/geometry/Point.d.ts +0 -49
  27. package/cjs/geometry/Point.d.ts.map +0 -1
  28. package/cjs/geometry/Point.js +0 -94
  29. package/cjs/geometry/Rectangle.d.ts +0 -41
  30. package/cjs/geometry/Rectangle.d.ts.map +0 -1
  31. package/cjs/geometry/Rectangle.js +0 -65
  32. package/cjs/geometry/collision.d.ts +0 -15
  33. package/cjs/geometry/collision.d.ts.map +0 -1
  34. package/cjs/geometry/collision.js +0 -81
  35. package/cjs/geometry/index.d.ts +0 -5
  36. package/cjs/geometry/index.d.ts.map +0 -1
  37. package/cjs/geometry/index.js +0 -45
  38. package/cjs/getManHattanPath.d.ts +0 -53
  39. package/cjs/getManHattanPath.d.ts.map +0 -1
  40. package/cjs/getManHattanPath.js +0 -418
  41. package/cjs/index.d.ts +0 -16
  42. package/cjs/index.d.ts.map +0 -1
  43. package/cjs/index.js +0 -117
  44. package/cjs/obstacle/ObstacleMap.d.ts +0 -34
  45. package/cjs/obstacle/ObstacleMap.d.ts.map +0 -1
  46. package/cjs/obstacle/ObstacleMap.js +0 -223
  47. package/cjs/obstacle/index.d.ts +0 -2
  48. package/cjs/obstacle/index.d.ts.map +0 -1
  49. package/cjs/obstacle/index.js +0 -12
  50. package/cjs/options/defaults.d.ts +0 -16
  51. package/cjs/options/defaults.d.ts.map +0 -1
  52. package/cjs/options/defaults.js +0 -39
  53. package/cjs/options/index.d.ts +0 -4
  54. package/cjs/options/index.d.ts.map +0 -1
  55. package/cjs/options/index.js +0 -38
  56. package/cjs/options/resolver.d.ts +0 -10
  57. package/cjs/options/resolver.d.ts.map +0 -1
  58. package/cjs/options/resolver.js +0 -120
  59. package/cjs/options/types.d.ts +0 -169
  60. package/cjs/options/types.d.ts.map +0 -1
  61. package/cjs/options/types.js +0 -5
  62. package/cjs/pathfinder/SortedSet.d.ts +0 -35
  63. package/cjs/pathfinder/SortedSet.d.ts.map +0 -1
  64. package/cjs/pathfinder/SortedSet.js +0 -95
  65. package/cjs/pathfinder/findRoute.d.ts +0 -8
  66. package/cjs/pathfinder/findRoute.d.ts.map +0 -1
  67. package/cjs/pathfinder/findRoute.js +0 -330
  68. package/cjs/pathfinder/index.d.ts +0 -3
  69. package/cjs/pathfinder/index.d.ts.map +0 -1
  70. package/cjs/pathfinder/index.js +0 -19
  71. package/cjs/svg/index.d.ts +0 -3
  72. package/cjs/svg/index.d.ts.map +0 -1
  73. package/cjs/svg/index.js +0 -31
  74. package/cjs/svg/pathConverter.d.ts +0 -10
  75. package/cjs/svg/pathConverter.d.ts.map +0 -1
  76. package/cjs/svg/pathConverter.js +0 -116
  77. package/cjs/svg/pathParser.d.ts +0 -11
  78. package/cjs/svg/pathParser.d.ts.map +0 -1
  79. package/cjs/svg/pathParser.js +0 -76
  80. package/cjs/utils/direction.d.ts +0 -24
  81. package/cjs/utils/direction.d.ts.map +0 -1
  82. package/cjs/utils/direction.js +0 -54
  83. package/cjs/utils/getAnchorPoints.d.ts +0 -15
  84. package/cjs/utils/getAnchorPoints.d.ts.map +0 -1
  85. package/cjs/utils/getAnchorPoints.js +0 -75
  86. package/cjs/utils/grid.d.ts +0 -27
  87. package/cjs/utils/grid.d.ts.map +0 -1
  88. package/cjs/utils/grid.js +0 -66
  89. package/cjs/utils/index.d.ts +0 -8
  90. package/cjs/utils/index.d.ts.map +0 -1
  91. package/cjs/utils/index.js +0 -82
  92. package/cjs/utils/node.d.ts +0 -27
  93. package/cjs/utils/node.d.ts.map +0 -1
  94. package/cjs/utils/node.js +0 -36
  95. package/cjs/utils/pathValidation.d.ts +0 -11
  96. package/cjs/utils/pathValidation.d.ts.map +0 -1
  97. package/cjs/utils/pathValidation.js +0 -130
  98. package/cjs/utils/rect.d.ts +0 -9
  99. package/cjs/utils/rect.d.ts.map +0 -1
  100. package/cjs/utils/rect.js +0 -103
  101. package/cjs/utils/route.d.ts +0 -19
  102. package/cjs/utils/route.d.ts.map +0 -1
  103. package/cjs/utils/route.js +0 -76
  104. package/esm/geometry/Line.d.ts +0 -21
  105. package/esm/geometry/Line.d.ts.map +0 -1
  106. package/esm/geometry/Point.d.ts +0 -49
  107. package/esm/geometry/Point.d.ts.map +0 -1
  108. package/esm/geometry/Rectangle.d.ts +0 -41
  109. package/esm/geometry/Rectangle.d.ts.map +0 -1
  110. package/esm/geometry/collision.d.ts +0 -15
  111. package/esm/geometry/collision.d.ts.map +0 -1
  112. package/esm/geometry/index.d.ts +0 -5
  113. package/esm/geometry/index.d.ts.map +0 -1
  114. package/esm/getManHattanPath.d.ts +0 -53
  115. package/esm/getManHattanPath.d.ts.map +0 -1
  116. package/esm/index.d.ts +0 -16
  117. package/esm/index.d.ts.map +0 -1
  118. package/esm/obstacle/ObstacleMap.d.ts +0 -34
  119. package/esm/obstacle/ObstacleMap.d.ts.map +0 -1
  120. package/esm/obstacle/index.d.ts +0 -2
  121. package/esm/obstacle/index.d.ts.map +0 -1
  122. package/esm/options/defaults.d.ts +0 -16
  123. package/esm/options/defaults.d.ts.map +0 -1
  124. package/esm/options/index.d.ts +0 -4
  125. package/esm/options/index.d.ts.map +0 -1
  126. package/esm/options/resolver.d.ts +0 -10
  127. package/esm/options/resolver.d.ts.map +0 -1
  128. package/esm/options/types.d.ts +0 -169
  129. package/esm/options/types.d.ts.map +0 -1
  130. package/esm/pathfinder/SortedSet.d.ts +0 -35
  131. package/esm/pathfinder/SortedSet.d.ts.map +0 -1
  132. package/esm/pathfinder/findRoute.d.ts +0 -8
  133. package/esm/pathfinder/findRoute.d.ts.map +0 -1
  134. package/esm/pathfinder/index.d.ts +0 -3
  135. package/esm/pathfinder/index.d.ts.map +0 -1
  136. package/esm/svg/index.d.ts +0 -3
  137. package/esm/svg/index.d.ts.map +0 -1
  138. package/esm/svg/pathConverter.d.ts +0 -10
  139. package/esm/svg/pathConverter.d.ts.map +0 -1
  140. package/esm/svg/pathParser.d.ts +0 -11
  141. package/esm/svg/pathParser.d.ts.map +0 -1
  142. package/esm/utils/direction.d.ts +0 -24
  143. package/esm/utils/direction.d.ts.map +0 -1
  144. package/esm/utils/getAnchorPoints.d.ts +0 -15
  145. package/esm/utils/getAnchorPoints.d.ts.map +0 -1
  146. package/esm/utils/grid.d.ts +0 -27
  147. package/esm/utils/grid.d.ts.map +0 -1
  148. package/esm/utils/index.d.ts +0 -8
  149. package/esm/utils/index.d.ts.map +0 -1
  150. package/esm/utils/node.d.ts +0 -27
  151. package/esm/utils/node.d.ts.map +0 -1
  152. package/esm/utils/pathValidation.d.ts +0 -11
  153. package/esm/utils/pathValidation.d.ts.map +0 -1
  154. package/esm/utils/rect.d.ts +0 -9
  155. package/esm/utils/rect.d.ts.map +0 -1
  156. package/esm/utils/route.d.ts +0 -19
  157. package/esm/utils/route.d.ts.map +0 -1
@@ -0,0 +1,488 @@
1
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
+ function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
3
+ function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
4
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
5
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
6
+ function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
7
+ function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
8
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
9
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
10
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
11
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
12
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
13
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
14
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
15
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
16
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
17
+ /**
18
+ * QuadTree implementation for efficient spatial queries
19
+ * Feature: manhattan-optimization
20
+ *
21
+ * A QuadTree is a tree data structure that recursively subdivides 2D space
22
+ * into four quadrants. This enables O(log n) spatial queries instead of O(n).
23
+ */
24
+ import { Rectangle } from "../geometry";
25
+
26
+ /**
27
+ * Item stored in the QuadTree
28
+ */
29
+
30
+ /**
31
+ * QuadTree configuration
32
+ */
33
+
34
+ /**
35
+ * Default QuadTree configuration
36
+ */
37
+ var DEFAULT_CONFIG = {
38
+ maxItems: 8,
39
+ maxDepth: 8,
40
+ minSize: 10
41
+ };
42
+
43
+ /**
44
+ * QuadTree node for spatial partitioning
45
+ */
46
+ export var QuadTree = /*#__PURE__*/function () {
47
+ function QuadTree(bounds) {
48
+ var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
49
+ var depth = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
50
+ _classCallCheck(this, QuadTree);
51
+ _defineProperty(this, "bounds", void 0);
52
+ _defineProperty(this, "items", void 0);
53
+ _defineProperty(this, "children", void 0);
54
+ _defineProperty(this, "depth", void 0);
55
+ _defineProperty(this, "config", void 0);
56
+ this.bounds = bounds;
57
+ this.items = [];
58
+ this.children = null;
59
+ this.depth = depth;
60
+ this.config = _objectSpread(_objectSpread({}, DEFAULT_CONFIG), config);
61
+ }
62
+
63
+ /**
64
+ * Insert an item into the QuadTree
65
+ */
66
+ _createClass(QuadTree, [{
67
+ key: "insert",
68
+ value: function insert(item) {
69
+ // Check if item intersects this node's bounds
70
+ if (!this.intersects(item.bounds)) {
71
+ return false;
72
+ }
73
+
74
+ // If we have children, try to insert into them
75
+ if (this.children !== null) {
76
+ return this.insertIntoChildren(item);
77
+ }
78
+
79
+ // Add to this node
80
+ this.items.push(item);
81
+
82
+ // Check if we need to split
83
+ if (this.shouldSplit()) {
84
+ this.split();
85
+ }
86
+ return true;
87
+ }
88
+
89
+ /**
90
+ * Insert an item with just bounds and data
91
+ */
92
+ }, {
93
+ key: "insertRect",
94
+ value: function insertRect(bounds, data) {
95
+ return this.insert({
96
+ bounds: bounds,
97
+ data: data
98
+ });
99
+ }
100
+
101
+ /**
102
+ * Query all items that intersect with the given bounds
103
+ */
104
+ }, {
105
+ key: "query",
106
+ value: function query(bounds) {
107
+ var results = [];
108
+ this.queryInternal(bounds, results);
109
+ return results;
110
+ }
111
+
112
+ /**
113
+ * Query all items that contain the given point
114
+ */
115
+ }, {
116
+ key: "queryPoint",
117
+ value: function queryPoint(point) {
118
+ var results = [];
119
+ this.queryPointInternal(point, results);
120
+ return results;
121
+ }
122
+
123
+ /**
124
+ * Get all items in the tree
125
+ */
126
+ }, {
127
+ key: "getAllItems",
128
+ value: function getAllItems() {
129
+ var results = _toConsumableArray(this.items);
130
+ if (this.children !== null) {
131
+ var _iterator = _createForOfIteratorHelper(this.children),
132
+ _step;
133
+ try {
134
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
135
+ var child = _step.value;
136
+ results.push.apply(results, _toConsumableArray(child.getAllItems()));
137
+ }
138
+ } catch (err) {
139
+ _iterator.e(err);
140
+ } finally {
141
+ _iterator.f();
142
+ }
143
+ }
144
+ return results;
145
+ }
146
+
147
+ /**
148
+ * Clear all items from the tree
149
+ */
150
+ }, {
151
+ key: "clear",
152
+ value: function clear() {
153
+ this.items = [];
154
+ this.children = null;
155
+ }
156
+
157
+ /**
158
+ * Get the total number of items in the tree
159
+ */
160
+ }, {
161
+ key: "size",
162
+ get: function get() {
163
+ var count = this.items.length;
164
+ if (this.children !== null) {
165
+ var _iterator2 = _createForOfIteratorHelper(this.children),
166
+ _step2;
167
+ try {
168
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
169
+ var child = _step2.value;
170
+ count += child.size;
171
+ }
172
+ } catch (err) {
173
+ _iterator2.e(err);
174
+ } finally {
175
+ _iterator2.f();
176
+ }
177
+ }
178
+ return count;
179
+ }
180
+
181
+ /**
182
+ * Get the depth of the tree
183
+ */
184
+ }, {
185
+ key: "getMaxDepth",
186
+ value: function getMaxDepth() {
187
+ if (this.children === null) {
188
+ return this.depth;
189
+ }
190
+ var maxChildDepth = this.depth;
191
+ var _iterator3 = _createForOfIteratorHelper(this.children),
192
+ _step3;
193
+ try {
194
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
195
+ var child = _step3.value;
196
+ maxChildDepth = Math.max(maxChildDepth, child.getMaxDepth());
197
+ }
198
+ } catch (err) {
199
+ _iterator3.e(err);
200
+ } finally {
201
+ _iterator3.f();
202
+ }
203
+ return maxChildDepth;
204
+ }
205
+
206
+ /**
207
+ * Internal query implementation
208
+ */
209
+ }, {
210
+ key: "queryInternal",
211
+ value: function queryInternal(bounds, results) {
212
+ // Check if query bounds intersects this node
213
+ if (!this.intersects(bounds)) {
214
+ return;
215
+ }
216
+
217
+ // Check items in this node
218
+ var _iterator4 = _createForOfIteratorHelper(this.items),
219
+ _step4;
220
+ try {
221
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
222
+ var item = _step4.value;
223
+ if (this.rectanglesIntersect(item.bounds, bounds)) {
224
+ results.push(item);
225
+ }
226
+ }
227
+
228
+ // Query children
229
+ } catch (err) {
230
+ _iterator4.e(err);
231
+ } finally {
232
+ _iterator4.f();
233
+ }
234
+ if (this.children !== null) {
235
+ var _iterator5 = _createForOfIteratorHelper(this.children),
236
+ _step5;
237
+ try {
238
+ for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
239
+ var child = _step5.value;
240
+ child.queryInternal(bounds, results);
241
+ }
242
+ } catch (err) {
243
+ _iterator5.e(err);
244
+ } finally {
245
+ _iterator5.f();
246
+ }
247
+ }
248
+ }
249
+
250
+ /**
251
+ * Internal point query implementation
252
+ */
253
+ }, {
254
+ key: "queryPointInternal",
255
+ value: function queryPointInternal(point, results) {
256
+ // Check if point is within this node's bounds
257
+ if (!this.containsPoint(point)) {
258
+ return;
259
+ }
260
+
261
+ // Check items in this node
262
+ var _iterator6 = _createForOfIteratorHelper(this.items),
263
+ _step6;
264
+ try {
265
+ for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
266
+ var item = _step6.value;
267
+ if (item.bounds.containsPoint(point)) {
268
+ results.push(item);
269
+ }
270
+ }
271
+
272
+ // Query children
273
+ } catch (err) {
274
+ _iterator6.e(err);
275
+ } finally {
276
+ _iterator6.f();
277
+ }
278
+ if (this.children !== null) {
279
+ var _iterator7 = _createForOfIteratorHelper(this.children),
280
+ _step7;
281
+ try {
282
+ for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
283
+ var child = _step7.value;
284
+ child.queryPointInternal(point, results);
285
+ }
286
+ } catch (err) {
287
+ _iterator7.e(err);
288
+ } finally {
289
+ _iterator7.f();
290
+ }
291
+ }
292
+ }
293
+
294
+ /**
295
+ * Check if this node should split
296
+ */
297
+ }, {
298
+ key: "shouldSplit",
299
+ value: function shouldSplit() {
300
+ return this.items.length > this.config.maxItems && this.depth < this.config.maxDepth && this.bounds.width > this.config.minSize * 2 && this.bounds.height > this.config.minSize * 2;
301
+ }
302
+
303
+ /**
304
+ * Split this node into four children
305
+ */
306
+ }, {
307
+ key: "split",
308
+ value: function split() {
309
+ var halfWidth = this.bounds.width / 2;
310
+ var halfHeight = this.bounds.height / 2;
311
+ var x = this.bounds.x;
312
+ var y = this.bounds.y;
313
+ var nextDepth = this.depth + 1;
314
+ this.children = [
315
+ // Top-left
316
+ new QuadTree(new Rectangle(x, y, halfWidth, halfHeight), this.config, nextDepth),
317
+ // Top-right
318
+ new QuadTree(new Rectangle(x + halfWidth, y, halfWidth, halfHeight), this.config, nextDepth),
319
+ // Bottom-left
320
+ new QuadTree(new Rectangle(x, y + halfHeight, halfWidth, halfHeight), this.config, nextDepth),
321
+ // Bottom-right
322
+ new QuadTree(new Rectangle(x + halfWidth, y + halfHeight, halfWidth, halfHeight), this.config, nextDepth)];
323
+
324
+ // Redistribute items to children
325
+ var itemsToRedistribute = this.items;
326
+ this.items = [];
327
+ var _iterator8 = _createForOfIteratorHelper(itemsToRedistribute),
328
+ _step8;
329
+ try {
330
+ for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
331
+ var item = _step8.value;
332
+ this.insertIntoChildren(item);
333
+ }
334
+ } catch (err) {
335
+ _iterator8.e(err);
336
+ } finally {
337
+ _iterator8.f();
338
+ }
339
+ }
340
+
341
+ /**
342
+ * Insert item into appropriate children
343
+ */
344
+ }, {
345
+ key: "insertIntoChildren",
346
+ value: function insertIntoChildren(item) {
347
+ if (this.children === null) {
348
+ return false;
349
+ }
350
+ var inserted = false;
351
+ var _iterator9 = _createForOfIteratorHelper(this.children),
352
+ _step9;
353
+ try {
354
+ for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {
355
+ var child = _step9.value;
356
+ if (child.insert(item)) {
357
+ inserted = true;
358
+ }
359
+ }
360
+
361
+ // If item doesn't fit in any child (spans multiple), keep in this node
362
+ } catch (err) {
363
+ _iterator9.e(err);
364
+ } finally {
365
+ _iterator9.f();
366
+ }
367
+ if (!inserted) {
368
+ this.items.push(item);
369
+ inserted = true;
370
+ }
371
+ return inserted;
372
+ }
373
+
374
+ /**
375
+ * Check if a rectangle intersects this node's bounds
376
+ */
377
+ }, {
378
+ key: "intersects",
379
+ value: function intersects(rect) {
380
+ return this.rectanglesIntersect(this.bounds, rect);
381
+ }
382
+
383
+ /**
384
+ * Check if two rectangles intersect
385
+ */
386
+ }, {
387
+ key: "rectanglesIntersect",
388
+ value: function rectanglesIntersect(a, b) {
389
+ return !(a.x + a.width <= b.x || b.x + b.width <= a.x || a.y + a.height <= b.y || b.y + b.height <= a.y);
390
+ }
391
+
392
+ /**
393
+ * Check if this node's bounds contain a point
394
+ */
395
+ }, {
396
+ key: "containsPoint",
397
+ value: function containsPoint(point) {
398
+ return point.x >= this.bounds.x && point.x <= this.bounds.x + this.bounds.width && point.y >= this.bounds.y && point.y <= this.bounds.y + this.bounds.height;
399
+ }
400
+
401
+ /**
402
+ * Get statistics about the tree
403
+ */
404
+ }, {
405
+ key: "getStats",
406
+ value: function getStats() {
407
+ var stats = {
408
+ totalItems: 0,
409
+ maxDepth: 0,
410
+ nodeCount: 0,
411
+ itemsPerNode: 0
412
+ };
413
+ this.collectStats(stats);
414
+ stats.itemsPerNode = stats.nodeCount > 0 ? stats.totalItems / stats.nodeCount : 0;
415
+ return stats;
416
+ }
417
+ }, {
418
+ key: "collectStats",
419
+ value: function collectStats(stats) {
420
+ stats.totalItems += this.items.length;
421
+ stats.maxDepth = Math.max(stats.maxDepth, this.depth);
422
+ stats.nodeCount++;
423
+ if (this.children !== null) {
424
+ var _iterator10 = _createForOfIteratorHelper(this.children),
425
+ _step10;
426
+ try {
427
+ for (_iterator10.s(); !(_step10 = _iterator10.n()).done;) {
428
+ var child = _step10.value;
429
+ child.collectStats(stats);
430
+ }
431
+ } catch (err) {
432
+ _iterator10.e(err);
433
+ } finally {
434
+ _iterator10.f();
435
+ }
436
+ }
437
+ }
438
+ }]);
439
+ return QuadTree;
440
+ }();
441
+
442
+ /**
443
+ * Create a QuadTree with bounds that cover all given rectangles
444
+ */
445
+ export function createQuadTreeFromRects(items, config) {
446
+ if (items.length === 0) {
447
+ return new QuadTree(new Rectangle(0, 0, 1000, 1000), config);
448
+ }
449
+
450
+ // Calculate bounding box of all items
451
+ var minX = Infinity;
452
+ var minY = Infinity;
453
+ var maxX = -Infinity;
454
+ var maxY = -Infinity;
455
+ var _iterator11 = _createForOfIteratorHelper(items),
456
+ _step11;
457
+ try {
458
+ for (_iterator11.s(); !(_step11 = _iterator11.n()).done;) {
459
+ var item = _step11.value;
460
+ minX = Math.min(minX, item.bounds.x);
461
+ minY = Math.min(minY, item.bounds.y);
462
+ maxX = Math.max(maxX, item.bounds.x + item.bounds.width);
463
+ maxY = Math.max(maxY, item.bounds.y + item.bounds.height);
464
+ }
465
+
466
+ // Add some padding
467
+ } catch (err) {
468
+ _iterator11.e(err);
469
+ } finally {
470
+ _iterator11.f();
471
+ }
472
+ var padding = 100;
473
+ var bounds = new Rectangle(minX - padding, minY - padding, maxX - minX + padding * 2, maxY - minY + padding * 2);
474
+ var tree = new QuadTree(bounds, config);
475
+ var _iterator12 = _createForOfIteratorHelper(items),
476
+ _step12;
477
+ try {
478
+ for (_iterator12.s(); !(_step12 = _iterator12.n()).done;) {
479
+ var _item = _step12.value;
480
+ tree.insert(_item);
481
+ }
482
+ } catch (err) {
483
+ _iterator12.e(err);
484
+ } finally {
485
+ _iterator12.f();
486
+ }
487
+ return tree;
488
+ }