@thi.ng/geom-axidraw 0.5.45 → 0.5.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1 -1
- package/README.md +1 -1
- package/api.js +0 -1
- package/as-axidraw.js +94 -125
- package/as-geometry.js +88 -100
- package/package.json +18 -15
- package/sort.js +35 -61
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
package/api.js
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/as-axidraw.js
CHANGED
|
@@ -9,46 +9,9 @@ import { __dispatch } from "@thi.ng/geom/internal/dispatch";
|
|
|
9
9
|
import { __sampleAttribs } from "@thi.ng/geom/internal/vertices";
|
|
10
10
|
import { takeNth } from "@thi.ng/transducers/take-nth";
|
|
11
11
|
import { pointsByNearestNeighbor } from "./sort.js";
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
*
|
|
16
|
-
* @remarks
|
|
17
|
-
* The provided conversion options can (and will) be overridden by a shape's
|
|
18
|
-
* `__axi` attribute. See {@link AxiDrawAttribs} for details.
|
|
19
|
-
*
|
|
20
|
-
* Currently supported shape types (at least all types which are supported by
|
|
21
|
-
* the
|
|
22
|
-
* [`asPolyline()`](https://docs.thi.ng/umbrella/geom/functions/asPolyline.html)
|
|
23
|
-
* function):
|
|
24
|
-
*
|
|
25
|
-
* - arc
|
|
26
|
-
* - circle
|
|
27
|
-
* - cubic
|
|
28
|
-
* - ellipse
|
|
29
|
-
* - group
|
|
30
|
-
* - line
|
|
31
|
-
* - path
|
|
32
|
-
* - points
|
|
33
|
-
* - polygon
|
|
34
|
-
* - polyline
|
|
35
|
-
* - quad
|
|
36
|
-
* - quadratic
|
|
37
|
-
* - rect
|
|
38
|
-
* - triangle
|
|
39
|
-
*
|
|
40
|
-
* @example
|
|
41
|
-
* ```ts
|
|
42
|
-
* [...asAxiDraw(circle(100), { samples: 100 })]
|
|
43
|
-
* [
|
|
44
|
-
* [ 'm', [ 10, 0 ] ],
|
|
45
|
-
* [ 'd' ],
|
|
46
|
-
* [ 'm', [ 9.980267284282716, 0.6279051952931337 ], undefined ],
|
|
47
|
-
* ...
|
|
48
|
-
* ]
|
|
49
|
-
* ```
|
|
50
|
-
*/
|
|
51
|
-
export const asAxiDraw = defmulti(__dispatch, {
|
|
12
|
+
const asAxiDraw = defmulti(
|
|
13
|
+
__dispatch,
|
|
14
|
+
{
|
|
52
15
|
arc: "circle",
|
|
53
16
|
cubic: "circle",
|
|
54
17
|
ellipse: "circle",
|
|
@@ -58,105 +21,111 @@ export const asAxiDraw = defmulti(__dispatch, {
|
|
|
58
21
|
quad: "polyline",
|
|
59
22
|
quadratic: "circle",
|
|
60
23
|
rect: "polyline",
|
|
61
|
-
tri: "polyline"
|
|
62
|
-
},
|
|
24
|
+
tri: "polyline"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
63
27
|
points: ($, opts) => __points(applyTransforms($).points, $.attribs, opts),
|
|
64
28
|
// used for all shapes which need to be sampled
|
|
65
|
-
circle: ($, opts) => __polyline(
|
|
29
|
+
circle: ($, opts) => __polyline(
|
|
30
|
+
asPolyline(applyTransforms($), opts?.samples).points,
|
|
31
|
+
$.attribs,
|
|
32
|
+
opts
|
|
33
|
+
),
|
|
66
34
|
// ignore sample opts for polyline & other polygonal shapes
|
|
67
35
|
// i.e. use points verbatim
|
|
68
36
|
polyline: ($, opts) => __polyline(asPolyline(applyTransforms($)).points, $.attribs, opts),
|
|
69
|
-
group: ($, opts) => __group($, opts)
|
|
70
|
-
}
|
|
37
|
+
group: ($, opts) => __group($, opts)
|
|
38
|
+
}
|
|
39
|
+
);
|
|
71
40
|
function* __group($, opts) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
41
|
+
const $sampleOpts = __sampleAttribs(opts?.samples, $.attribs);
|
|
42
|
+
const { skip, sort, interleave } = __axiAttribs($.attribs);
|
|
43
|
+
const children = skip ? [...takeNth(skip + 1, $.children)] : $.children;
|
|
44
|
+
function* emitChunk(chunk) {
|
|
45
|
+
const iter = sort ? sort(chunk) : chunk;
|
|
46
|
+
for (let child of iter) {
|
|
47
|
+
const shape = applyTransforms(child);
|
|
48
|
+
shape.attribs = {
|
|
49
|
+
...$.attribs,
|
|
50
|
+
...shape.attribs,
|
|
51
|
+
__samples: __sampleAttribs($sampleOpts, shape.attribs)
|
|
52
|
+
};
|
|
53
|
+
yield* asAxiDraw(shape, opts);
|
|
86
54
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
if (interleave.end)
|
|
98
|
-
yield* interleave.commands(children.length);
|
|
99
|
-
}
|
|
100
|
-
else {
|
|
101
|
-
yield* emitChunk(children);
|
|
55
|
+
}
|
|
56
|
+
if (interleave) {
|
|
57
|
+
const { num, commands } = interleave;
|
|
58
|
+
if (interleave.start !== false)
|
|
59
|
+
yield* commands(0);
|
|
60
|
+
for (let i = 0, n = children.length; i < n; ) {
|
|
61
|
+
yield* emitChunk(children.slice(i, i + num));
|
|
62
|
+
i += num;
|
|
63
|
+
if (i < n)
|
|
64
|
+
yield* commands(i);
|
|
102
65
|
}
|
|
66
|
+
if (interleave.end)
|
|
67
|
+
yield* interleave.commands(children.length);
|
|
68
|
+
} else {
|
|
69
|
+
yield* emitChunk(children);
|
|
70
|
+
}
|
|
103
71
|
}
|
|
104
72
|
function* __points(pts, attribs, opts) {
|
|
73
|
+
if (!pts.length)
|
|
74
|
+
return;
|
|
75
|
+
const { clip, delayDown, delayUp, down, skip, speed, sort, interleave } = {
|
|
76
|
+
sort: pointsByNearestNeighbor(),
|
|
77
|
+
...__axiAttribs(attribs)
|
|
78
|
+
};
|
|
79
|
+
const clipPts = clip || opts?.clip;
|
|
80
|
+
if (clipPts) {
|
|
81
|
+
pts = pts.filter((p) => !!pointInPolygon2(p, clipPts));
|
|
105
82
|
if (!pts.length)
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
if (
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
pts = [...takeNth(skip + 1, pts)];
|
|
119
|
-
}
|
|
120
|
-
function* emitChunk($pts) {
|
|
121
|
-
if (down != undefined)
|
|
122
|
-
yield ["pen", down];
|
|
123
|
-
for (let p of sort ? sort($pts) : $pts) {
|
|
124
|
-
yield MOVE(p, speed);
|
|
125
|
-
yield DOWN(delayDown);
|
|
126
|
-
yield UP(delayUp);
|
|
127
|
-
}
|
|
128
|
-
if (down != undefined)
|
|
129
|
-
yield ["pen"];
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (skip) {
|
|
86
|
+
pts = [...takeNth(skip + 1, pts)];
|
|
87
|
+
}
|
|
88
|
+
function* emitChunk($pts) {
|
|
89
|
+
if (down != void 0)
|
|
90
|
+
yield ["pen", down];
|
|
91
|
+
for (let p of sort ? sort($pts) : $pts) {
|
|
92
|
+
yield MOVE(p, speed);
|
|
93
|
+
yield DOWN(delayDown);
|
|
94
|
+
yield UP(delayUp);
|
|
130
95
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
}
|
|
145
|
-
else {
|
|
146
|
-
yield* emitChunk(pts);
|
|
96
|
+
if (down != void 0)
|
|
97
|
+
yield ["pen"];
|
|
98
|
+
}
|
|
99
|
+
yield UP();
|
|
100
|
+
if (interleave) {
|
|
101
|
+
const { num, commands } = interleave;
|
|
102
|
+
if (interleave.start !== false)
|
|
103
|
+
yield* commands(0);
|
|
104
|
+
for (let i = 0, n = pts.length; i < n; ) {
|
|
105
|
+
yield* emitChunk(pts.slice(i, i + num));
|
|
106
|
+
i += num;
|
|
107
|
+
if (i < n)
|
|
108
|
+
yield* commands(i);
|
|
147
109
|
}
|
|
110
|
+
if (interleave.end)
|
|
111
|
+
yield* interleave.commands(pts.length);
|
|
112
|
+
} else {
|
|
113
|
+
yield* emitChunk(pts);
|
|
114
|
+
}
|
|
148
115
|
}
|
|
149
116
|
function* __polyline(pts, attribs, opts) {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
117
|
+
if (!pts.length)
|
|
118
|
+
return;
|
|
119
|
+
const { clip, down, delayDown, delayUp, speed } = __axiAttribs(attribs);
|
|
120
|
+
const clipPts = clip || opts?.clip;
|
|
121
|
+
const chunks = clipPts ? clipPolylinePoly(pts, clipPts) : [pts];
|
|
122
|
+
if (!chunks.length)
|
|
123
|
+
return;
|
|
124
|
+
for (let chunk of chunks) {
|
|
125
|
+
yield* polyline(chunk, { down, delayDown, delayUp, speed });
|
|
126
|
+
}
|
|
160
127
|
}
|
|
161
|
-
/** @internal */
|
|
162
128
|
const __axiAttribs = (attribs) => attribs ? attribs.__axi || {} : {};
|
|
129
|
+
export {
|
|
130
|
+
asAxiDraw
|
|
131
|
+
};
|
package/as-geometry.js
CHANGED
|
@@ -4,109 +4,97 @@ import { polyline } from "@thi.ng/geom/polyline";
|
|
|
4
4
|
import { add2 } from "@thi.ng/vectors/add";
|
|
5
5
|
import { copy } from "@thi.ng/vectors/copy";
|
|
6
6
|
const DEFAULT_ATTRIBS = {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
paths: { stroke: "#000" },
|
|
8
|
+
rapids: { stroke: "#0ff" },
|
|
9
|
+
ups: { fill: "#0f0", stroke: "none" },
|
|
10
|
+
downs: { fill: "#f00", stroke: "none" }
|
|
11
11
|
};
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
rapids: true,
|
|
33
|
-
pen: true,
|
|
34
|
-
...opts,
|
|
35
|
-
attribs: { ...DEFAULT_ATTRIBS, ...opts.attribs },
|
|
36
|
-
};
|
|
37
|
-
const rapids = [];
|
|
38
|
-
const paths = [];
|
|
39
|
-
const downs = [];
|
|
40
|
-
const ups = [];
|
|
41
|
-
let penDown = false;
|
|
42
|
-
let pts = null;
|
|
43
|
-
let currPos = [0, 0];
|
|
44
|
-
const $move = (newPos) => {
|
|
45
|
-
if (penDown || opts.rapids) {
|
|
46
|
-
if (!pts)
|
|
47
|
-
pts = [copy(currPos), newPos];
|
|
48
|
-
else
|
|
49
|
-
pts.push(newPos);
|
|
50
|
-
}
|
|
51
|
-
currPos = newPos;
|
|
52
|
-
};
|
|
53
|
-
for (let cmd of src) {
|
|
54
|
-
switch (cmd[0]) {
|
|
55
|
-
// absolute
|
|
56
|
-
case "M":
|
|
57
|
-
$move(copy(cmd[1]));
|
|
58
|
-
break;
|
|
59
|
-
// relative
|
|
60
|
-
case "m":
|
|
61
|
-
$move(add2([], currPos, cmd[1]));
|
|
62
|
-
break;
|
|
63
|
-
case "u":
|
|
64
|
-
if (pts) {
|
|
65
|
-
if (penDown)
|
|
66
|
-
paths.push(pts);
|
|
67
|
-
else if (opts.rapids)
|
|
68
|
-
rapids.push(pts);
|
|
69
|
-
pts = null;
|
|
70
|
-
}
|
|
71
|
-
if (opts.pen)
|
|
72
|
-
ups.push(copy(currPos));
|
|
73
|
-
penDown = false;
|
|
74
|
-
break;
|
|
75
|
-
case "d":
|
|
76
|
-
if (pts) {
|
|
77
|
-
if (!penDown) {
|
|
78
|
-
if (opts.rapids)
|
|
79
|
-
rapids.push(pts);
|
|
80
|
-
}
|
|
81
|
-
else
|
|
82
|
-
paths.push(pts);
|
|
83
|
-
pts = null;
|
|
84
|
-
}
|
|
85
|
-
if (opts.pen)
|
|
86
|
-
downs.push(copy(currPos));
|
|
87
|
-
penDown = true;
|
|
88
|
-
break;
|
|
89
|
-
case "home":
|
|
90
|
-
currPos = [0, 0];
|
|
91
|
-
if (!pts)
|
|
92
|
-
pts = [currPos];
|
|
93
|
-
else
|
|
94
|
-
pts.push(currPos);
|
|
95
|
-
break;
|
|
96
|
-
default:
|
|
97
|
-
console.log("skipping command", cmd);
|
|
98
|
-
}
|
|
12
|
+
const asGeometry = (src, opts = {}) => {
|
|
13
|
+
opts = {
|
|
14
|
+
rapids: true,
|
|
15
|
+
pen: true,
|
|
16
|
+
...opts,
|
|
17
|
+
attribs: { ...DEFAULT_ATTRIBS, ...opts.attribs }
|
|
18
|
+
};
|
|
19
|
+
const rapids = [];
|
|
20
|
+
const paths = [];
|
|
21
|
+
const downs = [];
|
|
22
|
+
const ups = [];
|
|
23
|
+
let penDown = false;
|
|
24
|
+
let pts = null;
|
|
25
|
+
let currPos = [0, 0];
|
|
26
|
+
const $move = (newPos) => {
|
|
27
|
+
if (penDown || opts.rapids) {
|
|
28
|
+
if (!pts)
|
|
29
|
+
pts = [copy(currPos), newPos];
|
|
30
|
+
else
|
|
31
|
+
pts.push(newPos);
|
|
99
32
|
}
|
|
100
|
-
|
|
101
|
-
|
|
33
|
+
currPos = newPos;
|
|
34
|
+
};
|
|
35
|
+
for (let cmd of src) {
|
|
36
|
+
switch (cmd[0]) {
|
|
37
|
+
case "M":
|
|
38
|
+
$move(copy(cmd[1]));
|
|
39
|
+
break;
|
|
40
|
+
case "m":
|
|
41
|
+
$move(add2([], currPos, cmd[1]));
|
|
42
|
+
break;
|
|
43
|
+
case "u":
|
|
44
|
+
if (pts) {
|
|
45
|
+
if (penDown)
|
|
102
46
|
paths.push(pts);
|
|
103
|
-
|
|
47
|
+
else if (opts.rapids)
|
|
104
48
|
rapids.push(pts);
|
|
49
|
+
pts = null;
|
|
50
|
+
}
|
|
51
|
+
if (opts.pen)
|
|
52
|
+
ups.push(copy(currPos));
|
|
53
|
+
penDown = false;
|
|
54
|
+
break;
|
|
55
|
+
case "d":
|
|
56
|
+
if (pts) {
|
|
57
|
+
if (!penDown) {
|
|
58
|
+
if (opts.rapids)
|
|
59
|
+
rapids.push(pts);
|
|
60
|
+
} else
|
|
61
|
+
paths.push(pts);
|
|
62
|
+
pts = null;
|
|
63
|
+
}
|
|
64
|
+
if (opts.pen)
|
|
65
|
+
downs.push(copy(currPos));
|
|
66
|
+
penDown = true;
|
|
67
|
+
break;
|
|
68
|
+
case "home":
|
|
69
|
+
currPos = [0, 0];
|
|
70
|
+
if (!pts)
|
|
71
|
+
pts = [currPos];
|
|
72
|
+
else
|
|
73
|
+
pts.push(currPos);
|
|
74
|
+
break;
|
|
75
|
+
default:
|
|
76
|
+
console.log("skipping command", cmd);
|
|
105
77
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
78
|
+
}
|
|
79
|
+
if (pts) {
|
|
80
|
+
if (penDown)
|
|
81
|
+
paths.push(pts);
|
|
82
|
+
else
|
|
83
|
+
rapids.push(pts);
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
paths: group(
|
|
87
|
+
opts.attribs.paths,
|
|
88
|
+
paths.map((pts2) => polyline(pts2))
|
|
89
|
+
),
|
|
90
|
+
rapids: group(
|
|
91
|
+
opts.attribs.rapids,
|
|
92
|
+
rapids.map((pts2) => polyline(pts2))
|
|
93
|
+
),
|
|
94
|
+
ups: points(ups, opts.attribs.ups),
|
|
95
|
+
downs: points(downs, opts.attribs.downs)
|
|
96
|
+
};
|
|
97
|
+
};
|
|
98
|
+
export {
|
|
99
|
+
asGeometry
|
|
112
100
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thi.ng/geom-axidraw",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.46",
|
|
4
4
|
"description": "Conversion and preparation of thi.ng/geom shapes & shape groups to/from AxiDraw pen plotter draw commands",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -24,7 +24,9 @@
|
|
|
24
24
|
"author": "Karsten Schmidt (https://thi.ng)",
|
|
25
25
|
"license": "Apache-2.0",
|
|
26
26
|
"scripts": {
|
|
27
|
-
"build": "yarn
|
|
27
|
+
"build": "yarn build:esbuild && yarn build:decl",
|
|
28
|
+
"build:decl": "tsc --declaration --emitDeclarationOnly",
|
|
29
|
+
"build:esbuild": "esbuild --format=esm --platform=neutral --target=es2022 --tsconfig=tsconfig.json --outdir=. src/**/*.ts",
|
|
28
30
|
"clean": "rimraf --glob '*.js' '*.d.ts' '*.map' doc",
|
|
29
31
|
"doc": "typedoc --excludePrivate --excludeInternal --out doc src/index.ts",
|
|
30
32
|
"doc:ae": "mkdir -p .ae/doc .ae/temp && api-extractor run --local --verbose",
|
|
@@ -33,21 +35,22 @@
|
|
|
33
35
|
"test": "bun test"
|
|
34
36
|
},
|
|
35
37
|
"dependencies": {
|
|
36
|
-
"@thi.ng/api": "^8.9.
|
|
37
|
-
"@thi.ng/arrays": "^2.7.
|
|
38
|
-
"@thi.ng/axidraw": "^1.1.
|
|
39
|
-
"@thi.ng/compare": "^2.2.
|
|
40
|
-
"@thi.ng/defmulti": "^3.0.
|
|
41
|
-
"@thi.ng/geom": "^6.0.
|
|
42
|
-
"@thi.ng/geom-accel": "^3.5.
|
|
43
|
-
"@thi.ng/geom-api": "^3.4.
|
|
44
|
-
"@thi.ng/geom-clip-line": "^2.3.
|
|
45
|
-
"@thi.ng/geom-isec": "^2.1.
|
|
46
|
-
"@thi.ng/transducers": "^8.8.
|
|
47
|
-
"@thi.ng/vectors": "^7.8.
|
|
38
|
+
"@thi.ng/api": "^8.9.12",
|
|
39
|
+
"@thi.ng/arrays": "^2.7.8",
|
|
40
|
+
"@thi.ng/axidraw": "^1.1.40",
|
|
41
|
+
"@thi.ng/compare": "^2.2.8",
|
|
42
|
+
"@thi.ng/defmulti": "^3.0.10",
|
|
43
|
+
"@thi.ng/geom": "^6.0.8",
|
|
44
|
+
"@thi.ng/geom-accel": "^3.5.34",
|
|
45
|
+
"@thi.ng/geom-api": "^3.4.50",
|
|
46
|
+
"@thi.ng/geom-clip-line": "^2.3.50",
|
|
47
|
+
"@thi.ng/geom-isec": "^2.1.92",
|
|
48
|
+
"@thi.ng/transducers": "^8.8.15",
|
|
49
|
+
"@thi.ng/vectors": "^7.8.9"
|
|
48
50
|
},
|
|
49
51
|
"devDependencies": {
|
|
50
52
|
"@microsoft/api-extractor": "^7.38.3",
|
|
53
|
+
"esbuild": "^0.19.8",
|
|
51
54
|
"rimraf": "^5.0.5",
|
|
52
55
|
"tools": "^0.0.1",
|
|
53
56
|
"typedoc": "^0.25.4",
|
|
@@ -119,5 +122,5 @@
|
|
|
119
122
|
"status": "alpha",
|
|
120
123
|
"year": 2022
|
|
121
124
|
},
|
|
122
|
-
"gitHead": "
|
|
125
|
+
"gitHead": "5e7bafedfc3d53bc131469a28de31dd8e5b4a3ff\n"
|
|
123
126
|
}
|
package/sort.js
CHANGED
|
@@ -4,68 +4,42 @@ import { KdTreeSet } from "@thi.ng/geom-accel/kd-tree-set";
|
|
|
4
4
|
import { centroid } from "@thi.ng/geom/centroid";
|
|
5
5
|
import { ZERO2 } from "@thi.ng/vectors/api";
|
|
6
6
|
import { distSq2 } from "@thi.ng/vectors/distsq";
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
* By default is using a
|
|
15
|
-
* [`KdTreeSet`](https://docs.thi.ng/umbrella/geom-accel/classes/KdTreeSet.html)
|
|
16
|
-
* to index all points and then successively perform efficient nearest neighbor
|
|
17
|
-
* searches (always w.r.t the most recent result point).
|
|
18
|
-
*
|
|
19
|
-
* @param accel
|
|
20
|
-
* @param ref
|
|
21
|
-
*/
|
|
22
|
-
export const pointsByNearestNeighbor = (accel = new KdTreeSet(2), ref = ZERO2) => function* (pts) {
|
|
23
|
-
accel.into(pts);
|
|
24
|
-
// const index = new KdTreeSet(2, pts);
|
|
25
|
-
while (accel.size) {
|
|
26
|
-
ref = accel.queryKeys(ref, 1e4, 1)[0];
|
|
27
|
-
accel.remove(ref);
|
|
28
|
-
yield ref;
|
|
29
|
-
}
|
|
7
|
+
const pointsByNearestNeighbor = (accel = new KdTreeSet(2), ref = ZERO2) => function* (pts) {
|
|
8
|
+
accel.into(pts);
|
|
9
|
+
while (accel.size) {
|
|
10
|
+
ref = accel.queryKeys(ref, 1e4, 1)[0];
|
|
11
|
+
accel.remove(ref);
|
|
12
|
+
yield ref;
|
|
13
|
+
}
|
|
30
14
|
};
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
export const pointsByProximity = (ref = ZERO2) => (pts) => {
|
|
38
|
-
return sortByCachedKey(pts.slice(), (p) => distSq2(p, ref), compareNumAsc);
|
|
15
|
+
const pointsByProximity = (ref = ZERO2) => (pts) => {
|
|
16
|
+
return sortByCachedKey(
|
|
17
|
+
pts.slice(),
|
|
18
|
+
(p) => distSq2(p, ref),
|
|
19
|
+
compareNumAsc
|
|
20
|
+
);
|
|
39
21
|
};
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
export const shapesByProximity = (ref = ZERO2) => (shapes) => {
|
|
47
|
-
return sortByCachedKey(shapes.slice(), (s) => distSq2(centroid(s) || ZERO2, ref), compareNumAsc);
|
|
22
|
+
const shapesByProximity = (ref = ZERO2) => (shapes) => {
|
|
23
|
+
return sortByCachedKey(
|
|
24
|
+
shapes.slice(),
|
|
25
|
+
(s) => distSq2(centroid(s) || ZERO2, ref),
|
|
26
|
+
compareNumAsc
|
|
27
|
+
);
|
|
48
28
|
};
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
while (accel.size) {
|
|
66
|
-
const pair = accel.query(ref, 1e4, 1)[0];
|
|
67
|
-
ref = pair[0];
|
|
68
|
-
accel.remove(ref);
|
|
69
|
-
yield pair[1];
|
|
70
|
-
}
|
|
29
|
+
const shapesByNearestNeighbor = (accel, ref = ZERO2) => function* (shapes) {
|
|
30
|
+
accel.into(
|
|
31
|
+
shapes.map((s) => [centroid(s) || [0, 0], s])
|
|
32
|
+
);
|
|
33
|
+
while (accel.size) {
|
|
34
|
+
const pair = accel.query(ref, 1e4, 1)[0];
|
|
35
|
+
ref = pair[0];
|
|
36
|
+
accel.remove(ref);
|
|
37
|
+
yield pair[1];
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
export {
|
|
41
|
+
pointsByNearestNeighbor,
|
|
42
|
+
pointsByProximity,
|
|
43
|
+
shapesByNearestNeighbor,
|
|
44
|
+
shapesByProximity
|
|
71
45
|
};
|