@thi.ng/axidraw 0.5.8 → 1.0.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.
- package/CHANGELOG.md +33 -1
- package/README.md +41 -7
- package/api.d.ts +10 -11
- package/api.js +0 -9
- package/axidraw.d.ts +10 -1
- package/axidraw.js +55 -20
- package/commands.d.ts +67 -0
- package/commands.js +80 -0
- package/dip.d.ts +60 -0
- package/dip.js +45 -0
- package/index.d.ts +3 -1
- package/index.js +3 -1
- package/package.json +13 -7
- package/polyline.d.ts +1 -14
- package/polyline.js +8 -25
- package/{utils.d.ts → registration.d.ts} +2 -2
- package/registration.js +36 -0
- package/serial.d.ts +2 -0
- package/serial.js +6 -0
- package/utils.js +0 -34
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
-
- **Last updated**: 2023-03-
|
|
3
|
+
- **Last updated**: 2023-03-19T14:07:45Z
|
|
4
4
|
- **Generator**: [thi.ng/monopub](https://thi.ng/monopub)
|
|
5
5
|
|
|
6
6
|
All notable changes to this project will be documented in this file.
|
|
@@ -9,6 +9,38 @@ See [Conventional Commits](https://conventionalcommits.org/) for commit guidelin
|
|
|
9
9
|
**Note:** Unlisted _patch_ versions only involve non-code or otherwise excluded changes
|
|
10
10
|
and/or version bumps of transitive dependencies.
|
|
11
11
|
|
|
12
|
+
# [1.0.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/axidraw@1.0.0) (2023-03-19)
|
|
13
|
+
|
|
14
|
+
#### 🛑 Breaking changes
|
|
15
|
+
|
|
16
|
+
- add/update command presets ([610f873](https://github.com/thi-ng/umbrella/commit/610f873))
|
|
17
|
+
- BREAKING CHANGE: update DrawCommands and cmd presets
|
|
18
|
+
- update MoveXYCommand to use `"M"`
|
|
19
|
+
- add MoveRelCommand (using `"m"`)
|
|
20
|
+
- add/update AxiDraw.moveTo()/moveRelative()
|
|
21
|
+
- migrate command presets to commands.ts
|
|
22
|
+
- refactor parametric command type presets as functions:
|
|
23
|
+
- PEN(), UP(), DOWN(), MOVE(), MOVE_REL(), WAIT(), COMMENT()
|
|
24
|
+
- add DIP() command sequence gen
|
|
25
|
+
|
|
26
|
+
#### 🚀 Features
|
|
27
|
+
|
|
28
|
+
- add command fns, add COMMENT cmd ([0d64b55](https://github.com/thi-ng/umbrella/commit/0d64b55))
|
|
29
|
+
- add MOVE(), WAIT(), COMMENT()
|
|
30
|
+
- add CommentCommand
|
|
31
|
+
- update AxiDraw.draw() to log comments
|
|
32
|
+
- add disconnect() ([af93177](https://github.com/thi-ng/umbrella/commit/af93177))
|
|
33
|
+
- add disconnect() for ISerial & AxiDraw
|
|
34
|
+
- update MockSerial impl
|
|
35
|
+
- update commands, docs & pkg exports ([1324cb8](https://github.com/thi-ng/umbrella/commit/1324cb8))
|
|
36
|
+
- update dip(), update imports. restructure /src ([b108760](https://github.com/thi-ng/umbrella/commit/b108760))
|
|
37
|
+
- add DipOpts, extend dip() functionality
|
|
38
|
+
- move dip() to own file dip.ts
|
|
39
|
+
- move complete() to commands.ts
|
|
40
|
+
- move registrationMark() to own file registration.ts
|
|
41
|
+
- update all imports
|
|
42
|
+
- update pkg exports map
|
|
43
|
+
|
|
12
44
|
## [0.5.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/axidraw@0.5.0) (2023-02-05)
|
|
13
45
|
|
|
14
46
|
#### 🚀 Features
|
package/README.md
CHANGED
|
@@ -25,6 +25,8 @@ This project is part of the
|
|
|
25
25
|
- [Example usage](#example-usage)
|
|
26
26
|
- [Basics](#basics)
|
|
27
27
|
- [geom-axidraw example](#geom-axidraw-example)
|
|
28
|
+
- [Available draw commands](#available-draw-commands)
|
|
29
|
+
- [Command sequence generators](#command-sequence-generators)
|
|
28
30
|
- [Authors](#authors)
|
|
29
31
|
- [License](#license)
|
|
30
32
|
|
|
@@ -164,7 +166,7 @@ For Node.js REPL:
|
|
|
164
166
|
const axidraw = await import("@thi.ng/axidraw");
|
|
165
167
|
```
|
|
166
168
|
|
|
167
|
-
Package sizes (brotli'd, pre-treeshake): ESM: 2.
|
|
169
|
+
Package sizes (brotli'd, pre-treeshake): ESM: 2.46 KB
|
|
168
170
|
|
|
169
171
|
## Dependencies
|
|
170
172
|
|
|
@@ -259,14 +261,46 @@ import { map, range } from "@thi.ng/transducers";
|
|
|
259
261
|
|
|
260
262
|
Other selected toots/tweets:
|
|
261
263
|
|
|
262
|
-
- https://mastodon.thi.ng/@toxi/109490174709589253
|
|
263
|
-
- https://mastodon.thi.ng/@toxi/109473655772673067
|
|
264
|
-
- https://mastodon.thi.ng/@toxi/109474947869078797
|
|
265
|
-
- https://mastodon.thi.ng/@toxi/109483553358349473
|
|
266
|
-
- https://mastodon.thi.ng/@toxi/109570540391689321
|
|
267
|
-
- https://mastodon.thi.ng/@toxi/109586780630493994
|
|
264
|
+
- [Project announcement](https://mastodon.thi.ng/@toxi/109490174709589253)
|
|
265
|
+
- [Geometry conversion basics](https://mastodon.thi.ng/@toxi/109473655772673067)
|
|
266
|
+
- [Shape group conversion and stippling](https://mastodon.thi.ng/@toxi/109474947869078797)
|
|
267
|
+
- [Per-shape & on-the-fly polyline clipping](https://mastodon.thi.ng/@toxi/109483553358349473)
|
|
268
|
+
- [Bitmap-to-vector conversions & shape sorting](https://mastodon.thi.ng/@toxi/109570540391689321)
|
|
269
|
+
- [Multi-color plotting](https://mastodon.thi.ng/@toxi/109586780630493994)
|
|
270
|
+
- [Using water color & paintbrush](https://mastodon.thi.ng/@toxi/110044424626641749)
|
|
268
271
|
- more to come...
|
|
269
272
|
|
|
273
|
+
### Available draw commands
|
|
274
|
+
|
|
275
|
+
All
|
|
276
|
+
[`DrawCommand`s](https://docs.thi.ng/umbrella/axidraw/types/DrawCommand.html)
|
|
277
|
+
are expressed as S-expression-like, [thi.ng/hiccup]()-style elements, aka JS
|
|
278
|
+
arrays/tuples of `[command, ...args]`. The following commands are supported. All
|
|
279
|
+
also as predefined constants or factory functions for the parametric ones:
|
|
280
|
+
|
|
281
|
+
| Command | Preset/factory |
|
|
282
|
+
|-----------------------------------|-------------------------------------------------------------------------------------------------------------------------------------|
|
|
283
|
+
| `["comment", msg]` | [`COMMENT`](https://docs.thi.ng/umbrella/axidraw/functions/COMMENT.html) |
|
|
284
|
+
| `["d", delay?]` / `["u", delay?]` | [`DOWN`](https://docs.thi.ng/umbrella/axidraw/functions/DOWN.html) / [`UP`](https://docs.thi.ng/umbrella/axidraw/functions/UP.html) |
|
|
285
|
+
| `["home"]` | `HOME` |
|
|
286
|
+
| `["m", [x,y], speed?]` | [`MOVE_REL`](https://docs.thi.ng/umbrella/axidraw/functions/MOVE_REL.html) |
|
|
287
|
+
| `["M", [x,y], speed?]` | [`MOVE`](https://docs.thi.ng/umbrella/axidraw/functions/MOVE.html) |
|
|
288
|
+
| `["on"]` / `["off"]` | `ON` / `OFF` |
|
|
289
|
+
| `["pen", down, up]` | [`PEN`](https://docs.thi.ng/umbrella/axidraw/functions/PEN.html) |
|
|
290
|
+
| `["reset"]` | `RESET` |
|
|
291
|
+
| `["start"]` | `START` |
|
|
292
|
+
| `["stop"]` | `STOP` |
|
|
293
|
+
| `["w", delay]` | [`WAIT`](https://docs.thi.ng/umbrella/axidraw/functions/WAIT.html) |
|
|
294
|
+
|
|
295
|
+
#### Command sequence generators
|
|
296
|
+
|
|
297
|
+
Additionally, the following command sequence generators are provided (see their docs for code examples):
|
|
298
|
+
|
|
299
|
+
- [`complete`](https://docs.thi.ng/umbrella/axidraw/functions/complete.html)
|
|
300
|
+
- [`dip`](https://docs.thi.ng/umbrella/axidraw/functions/dip.html)
|
|
301
|
+
- [`polyline`](https://docs.thi.ng/umbrella/axidraw/functions/polyline.html)
|
|
302
|
+
- [`registrationMark`](https://docs.thi.ng/umbrella/axidraw/functions/registrationMark.html)
|
|
303
|
+
|
|
270
304
|
## Authors
|
|
271
305
|
|
|
272
306
|
- [Karsten Schmidt](https://thi.ng)
|
package/api.d.ts
CHANGED
|
@@ -23,10 +23,17 @@ export type PenUpDownCommand = ["u" | "d", number?, number?];
|
|
|
23
23
|
* Move to abs pos (in worldspace coords, default mm), optional speed factor
|
|
24
24
|
* (default: 1)
|
|
25
25
|
*/
|
|
26
|
-
export type MoveXYCommand = ["
|
|
26
|
+
export type MoveXYCommand = ["M", ReadonlyVec, number?];
|
|
27
|
+
/**
|
|
28
|
+
* Move to **relative** pos (based on curr plotter position, im worldspace
|
|
29
|
+
* units, default mm), optional speed factor (default: 1)
|
|
30
|
+
*/
|
|
31
|
+
export type MoveRelCommand = ["m", ReadonlyVec, number?];
|
|
27
32
|
/** Explicit delay (in ms) */
|
|
28
33
|
export type WaitCommand = ["w", number];
|
|
29
|
-
|
|
34
|
+
/** Ignored, but will be logged (if logging enabled) */
|
|
35
|
+
export type CommentCommand = ["comment", string];
|
|
36
|
+
export type DrawCommand = StartCommand | StopCommand | HomeCommand | ResetCommand | MotorCommand | PenConfigCommand | PenUpDownCommand | MoveXYCommand | MoveRelCommand | WaitCommand | CommentCommand;
|
|
30
37
|
/**
|
|
31
38
|
* Global plotter drawing configuration. Also see {@link DEFAULT_OPTS}.
|
|
32
39
|
*/
|
|
@@ -137,15 +144,6 @@ export interface AxiDrawOpts {
|
|
|
137
144
|
*/
|
|
138
145
|
sigint: boolean;
|
|
139
146
|
}
|
|
140
|
-
export declare const START: StartCommand;
|
|
141
|
-
export declare const STOP: StopCommand;
|
|
142
|
-
export declare const HOME: HomeCommand;
|
|
143
|
-
export declare const RESET: ResetCommand;
|
|
144
|
-
export declare const PEN: PenConfigCommand;
|
|
145
|
-
export declare const UP: PenUpDownCommand;
|
|
146
|
-
export declare const DOWN: PenUpDownCommand;
|
|
147
|
-
export declare const ON: MotorCommand;
|
|
148
|
-
export declare const OFF: MotorCommand;
|
|
149
147
|
/**
|
|
150
148
|
* FSM state enum for (interactive) control for processing of drawing commands.
|
|
151
149
|
* See {@link AxiDraw.draw} and {@link AxiDrawControl} for details.
|
|
@@ -245,6 +243,7 @@ export interface SerialConnection {
|
|
|
245
243
|
ctor(path: string, baudRate: number): ISerial;
|
|
246
244
|
}
|
|
247
245
|
export interface ISerial {
|
|
246
|
+
close(): void;
|
|
248
247
|
/**
|
|
249
248
|
* Writes given string to the port.
|
|
250
249
|
*
|
package/api.js
CHANGED
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
export const START = ["start"];
|
|
2
|
-
export const STOP = ["stop"];
|
|
3
|
-
export const HOME = ["home"];
|
|
4
|
-
export const RESET = ["reset"];
|
|
5
|
-
export const PEN = ["pen"];
|
|
6
|
-
export const UP = ["u"];
|
|
7
|
-
export const DOWN = ["d"];
|
|
8
|
-
export const ON = ["on"];
|
|
9
|
-
export const OFF = ["off"];
|
|
10
1
|
/**
|
|
11
2
|
* FSM state enum for (interactive) control for processing of drawing commands.
|
|
12
3
|
* See {@link AxiDraw.draw} and {@link AxiDrawControl} for details.
|
package/axidraw.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { IReset } from "@thi.ng/api";
|
|
2
|
-
import { ReadonlyVec, Vec } from "@thi.ng/vectors";
|
|
2
|
+
import { ReadonlyVec, Vec } from "@thi.ng/vectors/api";
|
|
3
3
|
import { AxiDrawOpts, DrawCommand, ISerial, Metrics } from "./api.js";
|
|
4
4
|
export declare const DEFAULT_OPTS: AxiDrawOpts;
|
|
5
5
|
export declare class AxiDraw implements IReset {
|
|
@@ -25,6 +25,7 @@ export declare class AxiDraw implements IReset {
|
|
|
25
25
|
* @param path
|
|
26
26
|
*/
|
|
27
27
|
connect(path?: string | RegExp): Promise<void>;
|
|
28
|
+
disconnect(): void;
|
|
28
29
|
/**
|
|
29
30
|
* Async function. Converts sequence of {@link DrawCommand}s into actual EBB
|
|
30
31
|
* commands and sends them via configured serial port to the AxiDraw. If
|
|
@@ -85,12 +86,20 @@ export declare class AxiDraw implements IReset {
|
|
|
85
86
|
* @param tempo
|
|
86
87
|
*/
|
|
87
88
|
moveTo(p: ReadonlyVec, tempo?: number): number[];
|
|
89
|
+
/**
|
|
90
|
+
* Similar to {@link AxiDraw.moveTo}, but using **relative** coordinates.
|
|
91
|
+
*
|
|
92
|
+
* @param delta
|
|
93
|
+
* @param tempo
|
|
94
|
+
*/
|
|
95
|
+
moveRelative(delta: ReadonlyVec, tempo?: number): number[];
|
|
88
96
|
/**
|
|
89
97
|
* Syntax sugar for {@link AxiDraw.moveTo}([0, 0]).
|
|
90
98
|
*/
|
|
91
99
|
home(): number[];
|
|
92
100
|
protected onSignal(): Promise<void>;
|
|
93
101
|
protected send(msg: string): void;
|
|
102
|
+
protected sendMove(tempo?: number): number[];
|
|
94
103
|
/**
|
|
95
104
|
* Sends pen up/down config
|
|
96
105
|
*
|
package/axidraw.js
CHANGED
|
@@ -1,12 +1,21 @@
|
|
|
1
|
-
import { isString } from "@thi.ng/checks";
|
|
2
|
-
import { delayed } from "@thi.ng/compose";
|
|
3
|
-
import { formatDuration } from "@thi.ng/date";
|
|
4
|
-
import { assert
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
1
|
+
import { isString } from "@thi.ng/checks/is-string";
|
|
2
|
+
import { delayed } from "@thi.ng/compose/delayed";
|
|
3
|
+
import { formatDuration } from "@thi.ng/date/format";
|
|
4
|
+
import { assert } from "@thi.ng/errors/assert";
|
|
5
|
+
import { ioerror } from "@thi.ng/errors/io";
|
|
6
|
+
import { unsupported } from "@thi.ng/errors/unsupported";
|
|
7
|
+
import { ConsoleLogger } from "@thi.ng/logger/console";
|
|
8
|
+
import { abs2 } from "@thi.ng/vectors/abs";
|
|
9
|
+
import { ZERO2 } from "@thi.ng/vectors/api";
|
|
10
|
+
import { maddN2 } from "@thi.ng/vectors/maddn";
|
|
11
|
+
import { mag } from "@thi.ng/vectors/mag";
|
|
12
|
+
import { mulN2 } from "@thi.ng/vectors/muln";
|
|
13
|
+
import { set2 } from "@thi.ng/vectors/set";
|
|
14
|
+
import { zero } from "@thi.ng/vectors/setn";
|
|
15
|
+
import { sub2 } from "@thi.ng/vectors/sub";
|
|
16
|
+
import { AxiDrawState, } from "./api.js";
|
|
17
|
+
import { complete, HOME, OFF, ON, PEN, UP } from "./commands.js";
|
|
8
18
|
import { AxiDrawControl } from "./control.js";
|
|
9
|
-
import { complete } from "./polyline.js";
|
|
10
19
|
import { SERIAL_PORT } from "./serial.js";
|
|
11
20
|
export const DEFAULT_OPTS = {
|
|
12
21
|
serial: SERIAL_PORT,
|
|
@@ -22,8 +31,8 @@ export const DEFAULT_OPTS = {
|
|
|
22
31
|
delayUp: 150,
|
|
23
32
|
delayDown: 150,
|
|
24
33
|
preDelay: 0,
|
|
25
|
-
start: [ON, PEN, UP],
|
|
26
|
-
stop: [UP, HOME, OFF],
|
|
34
|
+
start: [ON, PEN(), UP()],
|
|
35
|
+
stop: [UP(), HOME, OFF],
|
|
27
36
|
sigint: true,
|
|
28
37
|
};
|
|
29
38
|
export class AxiDraw {
|
|
@@ -70,6 +79,9 @@ export class AxiDraw {
|
|
|
70
79
|
}
|
|
71
80
|
ioerror(`no matching device for ${path}`);
|
|
72
81
|
}
|
|
82
|
+
disconnect() {
|
|
83
|
+
this.serial.close();
|
|
84
|
+
}
|
|
73
85
|
/**
|
|
74
86
|
* Async function. Converts sequence of {@link DrawCommand}s into actual EBB
|
|
75
87
|
* commands and sends them via configured serial port to the AxiDraw. If
|
|
@@ -176,10 +188,17 @@ export class AxiDraw {
|
|
|
176
188
|
case "w":
|
|
177
189
|
wait = a;
|
|
178
190
|
break;
|
|
179
|
-
case "
|
|
191
|
+
case "M":
|
|
180
192
|
[wait, dist] = this.moveTo(a, b);
|
|
181
193
|
$recordDist(dist);
|
|
182
194
|
break;
|
|
195
|
+
case "m":
|
|
196
|
+
[wait, dist] = this.moveRelative(a, b);
|
|
197
|
+
$recordDist(dist);
|
|
198
|
+
break;
|
|
199
|
+
case "comment":
|
|
200
|
+
logger.info(`comment: ${a}`);
|
|
201
|
+
break;
|
|
183
202
|
default:
|
|
184
203
|
unsupported(`unknown command: ${$cmd}`);
|
|
185
204
|
}
|
|
@@ -258,17 +277,23 @@ export class AxiDraw {
|
|
|
258
277
|
* @param p
|
|
259
278
|
* @param tempo
|
|
260
279
|
*/
|
|
261
|
-
moveTo(p, tempo
|
|
262
|
-
const {
|
|
280
|
+
moveTo(p, tempo) {
|
|
281
|
+
const { targetPos, opts } = this;
|
|
263
282
|
// apply scale factor: worldspace units -> motor steps
|
|
264
283
|
mulN2(targetPos, p, opts.stepsPerInch / opts.unitsPerInch);
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
284
|
+
return this.sendMove(tempo);
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Similar to {@link AxiDraw.moveTo}, but using **relative** coordinates.
|
|
288
|
+
*
|
|
289
|
+
* @param delta
|
|
290
|
+
* @param tempo
|
|
291
|
+
*/
|
|
292
|
+
moveRelative(delta, tempo) {
|
|
293
|
+
const { pos, targetPos, opts } = this;
|
|
294
|
+
// apply scale factor: worldspace units -> motor steps
|
|
295
|
+
maddN2(targetPos, delta, opts.stepsPerInch / opts.unitsPerInch, pos);
|
|
296
|
+
return this.sendMove(tempo);
|
|
272
297
|
}
|
|
273
298
|
/**
|
|
274
299
|
* Syntax sugar for {@link AxiDraw.moveTo}([0, 0]).
|
|
@@ -287,6 +312,16 @@ export class AxiDraw {
|
|
|
287
312
|
this.opts.logger.debug(msg);
|
|
288
313
|
this.serial.write(msg);
|
|
289
314
|
}
|
|
315
|
+
sendMove(tempo = 1) {
|
|
316
|
+
const { pos, targetPos, opts, isPenDown } = this;
|
|
317
|
+
const delta = sub2([], targetPos, pos);
|
|
318
|
+
set2(pos, targetPos);
|
|
319
|
+
const maxAxis = Math.max(...abs2([], delta));
|
|
320
|
+
const duration = (1000 * maxAxis) /
|
|
321
|
+
((isPenDown ? opts.speedDown : opts.speedUp) * tempo);
|
|
322
|
+
this.send(`XM,${duration | 0},${delta[0] | 0},${delta[1] | 0}\r`);
|
|
323
|
+
return [duration, (mag(delta) * opts.unitsPerInch) / opts.stepsPerInch];
|
|
324
|
+
}
|
|
290
325
|
/**
|
|
291
326
|
* Sends pen up/down config
|
|
292
327
|
*
|
package/commands.d.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { ReadonlyVec } from "@thi.ng/vectors";
|
|
2
|
+
import type { CommentCommand, DrawCommand, HomeCommand, MotorCommand, MoveRelCommand, MoveXYCommand, PenConfigCommand, PenUpDownCommand, ResetCommand, StartCommand, StopCommand, WaitCommand } from "./api.js";
|
|
3
|
+
export declare const START: StartCommand;
|
|
4
|
+
export declare const STOP: StopCommand;
|
|
5
|
+
export declare const HOME: HomeCommand;
|
|
6
|
+
export declare const RESET: ResetCommand;
|
|
7
|
+
/**
|
|
8
|
+
* Creates a {@link PenConfigCommand} using provided down/up positions.
|
|
9
|
+
*
|
|
10
|
+
* @param posDown
|
|
11
|
+
* @param posUp
|
|
12
|
+
*/
|
|
13
|
+
export declare const PEN: (posDown?: number, posUp?: number) => PenConfigCommand;
|
|
14
|
+
/**
|
|
15
|
+
* Creates a {@link PenUpDownCommand} to move the pen up.
|
|
16
|
+
*
|
|
17
|
+
* @param delay
|
|
18
|
+
*/
|
|
19
|
+
export declare const UP: (delay?: number) => PenUpDownCommand;
|
|
20
|
+
/**
|
|
21
|
+
* Creates a {@link PenUpDownCommand} to move the pen down.
|
|
22
|
+
*
|
|
23
|
+
* @param delay
|
|
24
|
+
*/
|
|
25
|
+
export declare const DOWN: (delay?: number) => PenUpDownCommand;
|
|
26
|
+
export declare const ON: MotorCommand;
|
|
27
|
+
export declare const OFF: MotorCommand;
|
|
28
|
+
/**
|
|
29
|
+
* Creates a {@link MoveXYCommand} command (absolute coordinates).
|
|
30
|
+
*
|
|
31
|
+
* @param pos
|
|
32
|
+
* @param speed
|
|
33
|
+
*/
|
|
34
|
+
export declare const MOVE: (pos: ReadonlyVec, speed?: number) => MoveXYCommand;
|
|
35
|
+
/**
|
|
36
|
+
* Creates a {@link MoveRelCommand} command (relative coordinates).
|
|
37
|
+
*
|
|
38
|
+
* @param delta
|
|
39
|
+
* @param speed
|
|
40
|
+
*/
|
|
41
|
+
export declare const MOVE_REL: (delta: ReadonlyVec, speed?: number) => MoveRelCommand;
|
|
42
|
+
/**
|
|
43
|
+
* Creates a {@link WaitCommand}. Default delay is 1000 ms.
|
|
44
|
+
*
|
|
45
|
+
* @param delay
|
|
46
|
+
*/
|
|
47
|
+
export declare const WAIT: (delay?: number) => WaitCommand;
|
|
48
|
+
/**
|
|
49
|
+
* Creates a {@link CommentCommand}.
|
|
50
|
+
*
|
|
51
|
+
* @param msg
|
|
52
|
+
*/
|
|
53
|
+
export declare const COMMENT: (msg: string) => CommentCommand;
|
|
54
|
+
/**
|
|
55
|
+
* Syntax sugar. Takes an iterable of draw commands, adds {@link START} as
|
|
56
|
+
* prefix and {@link STOP} as suffix. I.e. it creates a "complete" drawing...
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```ts
|
|
60
|
+
* [...complete([ MOVE([0, 0]) ])]
|
|
61
|
+
* // [ ["start"], ["M", [0, 0]], ["stop"] ]
|
|
62
|
+
* ```
|
|
63
|
+
*
|
|
64
|
+
* @param commands
|
|
65
|
+
*/
|
|
66
|
+
export declare function complete(commands: Iterable<DrawCommand>): Generator<DrawCommand, void, undefined>;
|
|
67
|
+
//# sourceMappingURL=commands.d.ts.map
|
package/commands.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
export const START = ["start"];
|
|
2
|
+
export const STOP = ["stop"];
|
|
3
|
+
export const HOME = ["home"];
|
|
4
|
+
export const RESET = ["reset"];
|
|
5
|
+
/**
|
|
6
|
+
* Creates a {@link PenConfigCommand} using provided down/up positions.
|
|
7
|
+
*
|
|
8
|
+
* @param posDown
|
|
9
|
+
* @param posUp
|
|
10
|
+
*/
|
|
11
|
+
export const PEN = (posDown, posUp) => [
|
|
12
|
+
"pen",
|
|
13
|
+
posDown,
|
|
14
|
+
posUp,
|
|
15
|
+
];
|
|
16
|
+
/**
|
|
17
|
+
* Creates a {@link PenUpDownCommand} to move the pen up.
|
|
18
|
+
*
|
|
19
|
+
* @param delay
|
|
20
|
+
*/
|
|
21
|
+
export const UP = (delay) => ["u", delay];
|
|
22
|
+
/**
|
|
23
|
+
* Creates a {@link PenUpDownCommand} to move the pen down.
|
|
24
|
+
*
|
|
25
|
+
* @param delay
|
|
26
|
+
*/
|
|
27
|
+
export const DOWN = (delay) => ["d", delay];
|
|
28
|
+
export const ON = ["on"];
|
|
29
|
+
export const OFF = ["off"];
|
|
30
|
+
/**
|
|
31
|
+
* Creates a {@link MoveXYCommand} command (absolute coordinates).
|
|
32
|
+
*
|
|
33
|
+
* @param pos
|
|
34
|
+
* @param speed
|
|
35
|
+
*/
|
|
36
|
+
export const MOVE = (pos, speed = 1) => [
|
|
37
|
+
"M",
|
|
38
|
+
pos,
|
|
39
|
+
speed,
|
|
40
|
+
];
|
|
41
|
+
/**
|
|
42
|
+
* Creates a {@link MoveRelCommand} command (relative coordinates).
|
|
43
|
+
*
|
|
44
|
+
* @param delta
|
|
45
|
+
* @param speed
|
|
46
|
+
*/
|
|
47
|
+
export const MOVE_REL = (delta, speed = 1) => [
|
|
48
|
+
"m",
|
|
49
|
+
delta,
|
|
50
|
+
speed,
|
|
51
|
+
];
|
|
52
|
+
/**
|
|
53
|
+
* Creates a {@link WaitCommand}. Default delay is 1000 ms.
|
|
54
|
+
*
|
|
55
|
+
* @param delay
|
|
56
|
+
*/
|
|
57
|
+
export const WAIT = (delay = 1000) => ["w", delay];
|
|
58
|
+
/**
|
|
59
|
+
* Creates a {@link CommentCommand}.
|
|
60
|
+
*
|
|
61
|
+
* @param msg
|
|
62
|
+
*/
|
|
63
|
+
export const COMMENT = (msg) => ["comment", msg];
|
|
64
|
+
/**
|
|
65
|
+
* Syntax sugar. Takes an iterable of draw commands, adds {@link START} as
|
|
66
|
+
* prefix and {@link STOP} as suffix. I.e. it creates a "complete" drawing...
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```ts
|
|
70
|
+
* [...complete([ MOVE([0, 0]) ])]
|
|
71
|
+
* // [ ["start"], ["M", [0, 0]], ["stop"] ]
|
|
72
|
+
* ```
|
|
73
|
+
*
|
|
74
|
+
* @param commands
|
|
75
|
+
*/
|
|
76
|
+
export function* complete(commands) {
|
|
77
|
+
yield START;
|
|
78
|
+
yield* commands;
|
|
79
|
+
yield STOP;
|
|
80
|
+
}
|
package/dip.d.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { Fn0 } from "@thi.ng/api";
|
|
2
|
+
import type { DrawCommand } from "./api.js";
|
|
3
|
+
export interface DipOpts {
|
|
4
|
+
/**
|
|
5
|
+
* Delay for emitted {@link DOWN} commands. If omitted, uses globally
|
|
6
|
+
* configured default.
|
|
7
|
+
*/
|
|
8
|
+
up: number;
|
|
9
|
+
/**
|
|
10
|
+
* Delay for emitted {@link UP} commands. If omitted, uses globally
|
|
11
|
+
* configured default.
|
|
12
|
+
*/
|
|
13
|
+
down: number;
|
|
14
|
+
/**
|
|
15
|
+
* No-arg function to inject custom commands between each down - up command.
|
|
16
|
+
* See example in {@link DIP} docs.
|
|
17
|
+
*/
|
|
18
|
+
commands: Fn0<Iterable<DrawCommand>>;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Yields a **sequence** of `n` repetitions of {@link DOWN}, {@link UP}
|
|
22
|
+
* commands, optionally interspersed with other user provided
|
|
23
|
+
* {@link DrawCommand}s, e.g. for dipping & moving a brush a few times into a
|
|
24
|
+
* paint reservoir to refill.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* // simple 2x up/down
|
|
29
|
+
* [...DIP(2)]
|
|
30
|
+
* // [
|
|
31
|
+
* // [ "d", undefined ],
|
|
32
|
+
* // [ "u", undefined ],
|
|
33
|
+
* // [ "d", undefined ],
|
|
34
|
+
* // [ "u", undefined ],
|
|
35
|
+
* // ]
|
|
36
|
+
*
|
|
37
|
+
* // 3x dipping with custom up/down delays, each time at a random position
|
|
38
|
+
* [...DIP(3, {
|
|
39
|
+
* down: 300,
|
|
40
|
+
* up: 400,
|
|
41
|
+
* commands: () => [ MOVE([Math.random()* 5, Math.random()* 5]) ]
|
|
42
|
+
* })]
|
|
43
|
+
* // [
|
|
44
|
+
* // [ "d", 300 ],
|
|
45
|
+
* // [ "M", [ 3.996, 1.707 ], 1 ],
|
|
46
|
+
* // [ "u", 400 ],
|
|
47
|
+
* // [ "d", 300 ],
|
|
48
|
+
* // [ "M", [ 4.747, 4.925 ], 1 ],
|
|
49
|
+
* // [ "u", 400 ],
|
|
50
|
+
* // [ "d", 300 ],
|
|
51
|
+
* // [ "M", [ 1.751, 0.670 ], 1 ],
|
|
52
|
+
* // [ "u", 400 ]
|
|
53
|
+
* // ]
|
|
54
|
+
* ```
|
|
55
|
+
*
|
|
56
|
+
* @param n
|
|
57
|
+
* @param opts
|
|
58
|
+
*/
|
|
59
|
+
export declare const dip: (n: number, opts?: Partial<DipOpts>) => IterableIterator<DrawCommand>;
|
|
60
|
+
//# sourceMappingURL=dip.d.ts.map
|
package/dip.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { flatten1 } from "@thi.ng/transducers/flatten1";
|
|
2
|
+
import { repeatedly } from "@thi.ng/transducers/repeatedly";
|
|
3
|
+
import { DOWN, UP } from "./commands.js";
|
|
4
|
+
/**
|
|
5
|
+
* Yields a **sequence** of `n` repetitions of {@link DOWN}, {@link UP}
|
|
6
|
+
* commands, optionally interspersed with other user provided
|
|
7
|
+
* {@link DrawCommand}s, e.g. for dipping & moving a brush a few times into a
|
|
8
|
+
* paint reservoir to refill.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* // simple 2x up/down
|
|
13
|
+
* [...DIP(2)]
|
|
14
|
+
* // [
|
|
15
|
+
* // [ "d", undefined ],
|
|
16
|
+
* // [ "u", undefined ],
|
|
17
|
+
* // [ "d", undefined ],
|
|
18
|
+
* // [ "u", undefined ],
|
|
19
|
+
* // ]
|
|
20
|
+
*
|
|
21
|
+
* // 3x dipping with custom up/down delays, each time at a random position
|
|
22
|
+
* [...DIP(3, {
|
|
23
|
+
* down: 300,
|
|
24
|
+
* up: 400,
|
|
25
|
+
* commands: () => [ MOVE([Math.random()* 5, Math.random()* 5]) ]
|
|
26
|
+
* })]
|
|
27
|
+
* // [
|
|
28
|
+
* // [ "d", 300 ],
|
|
29
|
+
* // [ "M", [ 3.996, 1.707 ], 1 ],
|
|
30
|
+
* // [ "u", 400 ],
|
|
31
|
+
* // [ "d", 300 ],
|
|
32
|
+
* // [ "M", [ 4.747, 4.925 ], 1 ],
|
|
33
|
+
* // [ "u", 400 ],
|
|
34
|
+
* // [ "d", 300 ],
|
|
35
|
+
* // [ "M", [ 1.751, 0.670 ], 1 ],
|
|
36
|
+
* // [ "u", 400 ]
|
|
37
|
+
* // ]
|
|
38
|
+
* ```
|
|
39
|
+
*
|
|
40
|
+
* @param n
|
|
41
|
+
* @param opts
|
|
42
|
+
*/
|
|
43
|
+
export const dip = (n, opts = {}) => flatten1(repeatedly(opts.commands
|
|
44
|
+
? () => [DOWN(opts.down), ...opts.commands(), UP(opts.up)]
|
|
45
|
+
: () => [DOWN(opts.down), UP(opts.up)], n));
|
package/index.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export * from "./api.js";
|
|
2
2
|
export * from "./axidraw.js";
|
|
3
|
+
export * from "./commands.js";
|
|
3
4
|
export * from "./control.js";
|
|
5
|
+
export * from "./dip.js";
|
|
4
6
|
export * from "./polyline.js";
|
|
7
|
+
export * from "./registration.js";
|
|
5
8
|
export * from "./serial.js";
|
|
6
|
-
export * from "./utils.js";
|
|
7
9
|
//# sourceMappingURL=index.d.ts.map
|
package/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export * from "./api.js";
|
|
2
2
|
export * from "./axidraw.js";
|
|
3
|
+
export * from "./commands.js";
|
|
3
4
|
export * from "./control.js";
|
|
5
|
+
export * from "./dip.js";
|
|
4
6
|
export * from "./polyline.js";
|
|
7
|
+
export * from "./registration.js";
|
|
5
8
|
export * from "./serial.js";
|
|
6
|
-
export * from "./utils.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thi.ng/axidraw",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "Minimal AxiDraw plotter/drawing machine controller for Node.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -40,8 +40,8 @@
|
|
|
40
40
|
"@thi.ng/date": "^2.4.8",
|
|
41
41
|
"@thi.ng/errors": "^2.2.13",
|
|
42
42
|
"@thi.ng/logger": "^1.4.11",
|
|
43
|
-
"@thi.ng/transducers": "^8.
|
|
44
|
-
"@thi.ng/vectors": "^7.6.
|
|
43
|
+
"@thi.ng/transducers": "^8.4.0",
|
|
44
|
+
"@thi.ng/vectors": "^7.6.9",
|
|
45
45
|
"serialport": "^10.5.0"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
@@ -87,22 +87,28 @@
|
|
|
87
87
|
"./axidraw": {
|
|
88
88
|
"default": "./axidraw.js"
|
|
89
89
|
},
|
|
90
|
+
"./commands": {
|
|
91
|
+
"default": "./commands.js"
|
|
92
|
+
},
|
|
90
93
|
"./control": {
|
|
91
94
|
"default": "./control.js"
|
|
92
95
|
},
|
|
96
|
+
"./dip": {
|
|
97
|
+
"default": "./dip.js"
|
|
98
|
+
},
|
|
93
99
|
"./polyline": {
|
|
94
100
|
"default": "./polyline.js"
|
|
95
101
|
},
|
|
102
|
+
"./registration": {
|
|
103
|
+
"default": "./registration.js"
|
|
104
|
+
},
|
|
96
105
|
"./serial": {
|
|
97
106
|
"default": "./serial.js"
|
|
98
|
-
},
|
|
99
|
-
"./utils": {
|
|
100
|
-
"default": "./utils.js"
|
|
101
107
|
}
|
|
102
108
|
},
|
|
103
109
|
"thi.ng": {
|
|
104
110
|
"status": "alpha",
|
|
105
111
|
"year": 2022
|
|
106
112
|
},
|
|
107
|
-
"gitHead": "
|
|
113
|
+
"gitHead": "1359645f3af8a7d0d43fe7944ea5cd865832f8ee\n"
|
|
108
114
|
}
|
package/polyline.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ReadonlyVec } from "@thi.ng/vectors";
|
|
2
|
-
import { DrawCommand, PolylineOpts } from "./api.js";
|
|
2
|
+
import type { DrawCommand, PolylineOpts } from "./api.js";
|
|
3
3
|
/**
|
|
4
4
|
* Takes an array of 2D points and yields an iterable of {@link DrawCommand}s.
|
|
5
5
|
* The drawing behavior can be customized via additional {@link PolylineOpts}
|
|
@@ -13,17 +13,4 @@ import { DrawCommand, PolylineOpts } from "./api.js";
|
|
|
13
13
|
* @param opts
|
|
14
14
|
*/
|
|
15
15
|
export declare function polyline(pts: ReadonlyVec[], opts: Partial<PolylineOpts>): IterableIterator<DrawCommand>;
|
|
16
|
-
/**
|
|
17
|
-
* Syntax sugar. Takes an iterable of draw commands, adds {@link START} as
|
|
18
|
-
* prefix and {@link STOP} as suffix. I.e. it creates a "complete" drawing...
|
|
19
|
-
*
|
|
20
|
-
* @example
|
|
21
|
-
* ```ts
|
|
22
|
-
* [...complete([ ["m", [0, 0]] ])]
|
|
23
|
-
* // [ ["start"], ["m", [0, 0]], ["stop"] ]
|
|
24
|
-
* ```
|
|
25
|
-
*
|
|
26
|
-
* @param commands
|
|
27
|
-
*/
|
|
28
|
-
export declare function complete(commands: Iterable<DrawCommand>): Generator<DrawCommand, void, undefined>;
|
|
29
16
|
//# sourceMappingURL=polyline.d.ts.map
|
package/polyline.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DOWN,
|
|
1
|
+
import { DOWN, MOVE, PEN, UP } from "./commands.js";
|
|
2
2
|
/**
|
|
3
3
|
* Takes an array of 2D points and yields an iterable of {@link DrawCommand}s.
|
|
4
4
|
* The drawing behavior can be customized via additional {@link PolylineOpts}
|
|
@@ -21,34 +21,17 @@ export function* polyline(pts, opts) {
|
|
|
21
21
|
};
|
|
22
22
|
if (onlyGeo) {
|
|
23
23
|
for (let p of pts)
|
|
24
|
-
yield
|
|
24
|
+
yield MOVE(p, speed);
|
|
25
25
|
return;
|
|
26
26
|
}
|
|
27
|
-
yield
|
|
27
|
+
yield MOVE(pts[0]);
|
|
28
28
|
if (down !== undefined)
|
|
29
|
-
yield
|
|
30
|
-
yield delayDown
|
|
29
|
+
yield PEN(down);
|
|
30
|
+
yield DOWN(delayDown);
|
|
31
31
|
for (let i = 1, n = pts.length; i < n; i++)
|
|
32
|
-
yield
|
|
33
|
-
yield delayUp
|
|
32
|
+
yield MOVE(pts[i], speed);
|
|
33
|
+
yield UP(delayUp);
|
|
34
34
|
// reset pen to configured defaults
|
|
35
35
|
if (down !== undefined)
|
|
36
|
-
yield
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Syntax sugar. Takes an iterable of draw commands, adds {@link START} as
|
|
40
|
-
* prefix and {@link STOP} as suffix. I.e. it creates a "complete" drawing...
|
|
41
|
-
*
|
|
42
|
-
* @example
|
|
43
|
-
* ```ts
|
|
44
|
-
* [...complete([ ["m", [0, 0]] ])]
|
|
45
|
-
* // [ ["start"], ["m", [0, 0]], ["stop"] ]
|
|
46
|
-
* ```
|
|
47
|
-
*
|
|
48
|
-
* @param commands
|
|
49
|
-
*/
|
|
50
|
-
export function* complete(commands) {
|
|
51
|
-
yield START;
|
|
52
|
-
yield* commands;
|
|
53
|
-
yield STOP;
|
|
36
|
+
yield PEN();
|
|
54
37
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ReadonlyVec } from "@thi.ng/vectors";
|
|
1
|
+
import type { ReadonlyVec } from "@thi.ng/vectors";
|
|
2
2
|
import type { DrawCommand } from "./api.js";
|
|
3
3
|
/**
|
|
4
4
|
* Generates a {@link DrawCommand} sequence to draw a registration mark
|
|
@@ -14,4 +14,4 @@ import type { DrawCommand } from "./api.js";
|
|
|
14
14
|
* @param r
|
|
15
15
|
*/
|
|
16
16
|
export declare const registrationMark: ([x, y]: ReadonlyVec, size?: number, r?: number) => DrawCommand[];
|
|
17
|
-
//# sourceMappingURL=
|
|
17
|
+
//# sourceMappingURL=registration.d.ts.map
|
package/registration.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { map } from "@thi.ng/transducers/map";
|
|
2
|
+
import { normRange } from "@thi.ng/transducers/norm-range";
|
|
3
|
+
import { cartesian2 } from "@thi.ng/vectors/cartesian";
|
|
4
|
+
import { DOWN, MOVE, UP } from "./commands.js";
|
|
5
|
+
/**
|
|
6
|
+
* Generates a {@link DrawCommand} sequence to draw a registration mark
|
|
7
|
+
* (crosshair + circle) centered around `pos`.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* axi.draw(registrationMark([20, 20]))
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* @param pos
|
|
15
|
+
* @param size
|
|
16
|
+
* @param r
|
|
17
|
+
*/
|
|
18
|
+
export const registrationMark = ([x, y], size = 5, r = size * 0.75) => [
|
|
19
|
+
// crosshair
|
|
20
|
+
// horizontal
|
|
21
|
+
MOVE([x - size, y]),
|
|
22
|
+
DOWN(),
|
|
23
|
+
MOVE([x + size, y]),
|
|
24
|
+
UP(),
|
|
25
|
+
// vertical
|
|
26
|
+
MOVE([x, y - size]),
|
|
27
|
+
DOWN(),
|
|
28
|
+
MOVE([x, y + size]),
|
|
29
|
+
UP(),
|
|
30
|
+
// circle
|
|
31
|
+
MOVE([x + r, y]),
|
|
32
|
+
DOWN(),
|
|
33
|
+
...map((t) => MOVE(cartesian2([], [r, t * Math.PI * 2], [x, y])), normRange(40)),
|
|
34
|
+
UP(),
|
|
35
|
+
MOVE([x, y]),
|
|
36
|
+
];
|
package/serial.d.ts
CHANGED
|
@@ -14,10 +14,12 @@ export declare const MOCK_SERIAL: SerialConnection;
|
|
|
14
14
|
*/
|
|
15
15
|
export declare class MockSerial implements ISerial {
|
|
16
16
|
sent: string[];
|
|
17
|
+
isClosed: boolean;
|
|
17
18
|
/**
|
|
18
19
|
* Clears internal log of "sent" message.
|
|
19
20
|
*/
|
|
20
21
|
clear(): void;
|
|
22
|
+
close(): void;
|
|
21
23
|
/**
|
|
22
24
|
* Appends
|
|
23
25
|
* @param msg
|
package/serial.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { illegalState } from "@thi.ng/errors/illegal-state";
|
|
1
2
|
import { SerialPort } from "serialport";
|
|
2
3
|
/**
|
|
3
4
|
* Default connection using the actual serial port.
|
|
@@ -21,6 +22,7 @@ export const MOCK_SERIAL = {
|
|
|
21
22
|
export class MockSerial {
|
|
22
23
|
constructor() {
|
|
23
24
|
this.sent = [];
|
|
25
|
+
this.isClosed = false;
|
|
24
26
|
}
|
|
25
27
|
/**
|
|
26
28
|
* Clears internal log of "sent" message.
|
|
@@ -28,11 +30,15 @@ export class MockSerial {
|
|
|
28
30
|
clear() {
|
|
29
31
|
this.sent = [];
|
|
30
32
|
}
|
|
33
|
+
close() {
|
|
34
|
+
this.isClosed = true;
|
|
35
|
+
}
|
|
31
36
|
/**
|
|
32
37
|
* Appends
|
|
33
38
|
* @param msg
|
|
34
39
|
*/
|
|
35
40
|
write(msg) {
|
|
41
|
+
this.isClosed && illegalState("connection already closed");
|
|
36
42
|
this.sent.push(msg);
|
|
37
43
|
}
|
|
38
44
|
}
|
package/utils.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { map, normRange } from "@thi.ng/transducers";
|
|
2
|
-
import { cartesian2 } from "@thi.ng/vectors";
|
|
3
|
-
/**
|
|
4
|
-
* Generates a {@link DrawCommand} sequence to draw a registration mark
|
|
5
|
-
* (crosshair + circle) centered around `pos`.
|
|
6
|
-
*
|
|
7
|
-
* @example
|
|
8
|
-
* ```ts
|
|
9
|
-
* axi.draw(registrationMark([20, 20]))
|
|
10
|
-
* ```
|
|
11
|
-
*
|
|
12
|
-
* @param pos
|
|
13
|
-
* @param size
|
|
14
|
-
* @param r
|
|
15
|
-
*/
|
|
16
|
-
export const registrationMark = ([x, y], size = 5, r = size * 0.75) => [
|
|
17
|
-
// crosshair
|
|
18
|
-
// horizontal
|
|
19
|
-
["m", [x - size, y]],
|
|
20
|
-
["d"],
|
|
21
|
-
["m", [x + size, y]],
|
|
22
|
-
["u"],
|
|
23
|
-
// vertical
|
|
24
|
-
["m", [x, y - size]],
|
|
25
|
-
["d"],
|
|
26
|
-
["m", [x, y + size]],
|
|
27
|
-
["u"],
|
|
28
|
-
// circle
|
|
29
|
-
["m", [x + r, y]],
|
|
30
|
-
["d"],
|
|
31
|
-
...map((t) => ["m", cartesian2([], [r, t * Math.PI * 2], [x, y])], normRange(40)),
|
|
32
|
-
["u"],
|
|
33
|
-
["m", [x, y]],
|
|
34
|
-
];
|