@thi.ng/geom-sdf 0.1.0 → 0.2.1
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 +30 -1
- package/README.md +100 -10
- package/api.d.ts +94 -4
- package/as-polygons.d.ts +26 -0
- package/as-polygons.js +39 -0
- package/as-sdf.d.ts +8 -0
- package/as-sdf.js +59 -20
- package/bounds.d.ts +30 -0
- package/bounds.js +31 -0
- package/dist.d.ts +91 -4
- package/dist.js +144 -57
- package/domain.d.ts +34 -0
- package/domain.js +63 -0
- package/index.d.ts +2 -0
- package/index.js +2 -0
- package/ops.d.ts +19 -7
- package/ops.js +74 -22
- package/package.json +21 -4
- package/sample.d.ts +15 -5
- package/sample.js +14 -19
- package/shapes.d.ts +25 -1
- package/shapes.js +59 -11
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thi.ng/geom-sdf",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "2D Signed Distance Field creation from @thi.ng/geom shapes, conversions, sampling, combinators",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -38,9 +38,11 @@
|
|
|
38
38
|
"@thi.ng/checks": "^3.2.1",
|
|
39
39
|
"@thi.ng/defmulti": "^2.1.7",
|
|
40
40
|
"@thi.ng/errors": "^2.1.7",
|
|
41
|
-
"@thi.ng/geom": "^3.
|
|
42
|
-
"@thi.ng/geom-api": "^3.
|
|
41
|
+
"@thi.ng/geom": "^3.4.0",
|
|
42
|
+
"@thi.ng/geom-api": "^3.3.0",
|
|
43
43
|
"@thi.ng/geom-isoline": "^2.1.14",
|
|
44
|
+
"@thi.ng/geom-poly-utils": "^2.3.1",
|
|
45
|
+
"@thi.ng/geom-resample": "^2.1.17",
|
|
44
46
|
"@thi.ng/math": "^5.3.3",
|
|
45
47
|
"@thi.ng/transducers": "^8.3.5",
|
|
46
48
|
"@thi.ng/vectors": "^7.5.6"
|
|
@@ -89,12 +91,21 @@
|
|
|
89
91
|
"./api": {
|
|
90
92
|
"default": "./api.js"
|
|
91
93
|
},
|
|
94
|
+
"./as-polygons": {
|
|
95
|
+
"default": "./as-polygons.js"
|
|
96
|
+
},
|
|
92
97
|
"./as-sdf": {
|
|
93
98
|
"default": "./as-sdf.js"
|
|
94
99
|
},
|
|
100
|
+
"./bounds": {
|
|
101
|
+
"default": "./bounds.js"
|
|
102
|
+
},
|
|
95
103
|
"./dist": {
|
|
96
104
|
"default": "./dist.js"
|
|
97
105
|
},
|
|
106
|
+
"./domain": {
|
|
107
|
+
"default": "./domain.js"
|
|
108
|
+
},
|
|
98
109
|
"./ops": {
|
|
99
110
|
"default": "./ops.js"
|
|
100
111
|
},
|
|
@@ -107,8 +118,14 @@
|
|
|
107
118
|
},
|
|
108
119
|
"thi.ng": {
|
|
109
120
|
"parent": "@thi.ng/geom",
|
|
121
|
+
"related": [
|
|
122
|
+
"distance-transform",
|
|
123
|
+
"geom-isoline",
|
|
124
|
+
"pixel",
|
|
125
|
+
"shader-ast-stdlib"
|
|
126
|
+
],
|
|
110
127
|
"status": "alpha",
|
|
111
128
|
"year": 2022
|
|
112
129
|
},
|
|
113
|
-
"gitHead": "
|
|
130
|
+
"gitHead": "207404f1e1fcfd3596780322d9218156aeaac3dd\n"
|
|
114
131
|
}
|
package/sample.d.ts
CHANGED
|
@@ -1,8 +1,18 @@
|
|
|
1
|
-
import type { NumericArray } from "@thi.ng/api";
|
|
2
|
-
import type { Polygon } from "@thi.ng/geom";
|
|
1
|
+
import type { Fn, NumericArray } from "@thi.ng/api";
|
|
3
2
|
import type { AABBLike } from "@thi.ng/geom-api";
|
|
4
|
-
import { ReadonlyVec } from "@thi.ng/vectors";
|
|
3
|
+
import type { ReadonlyVec, Vec } from "@thi.ng/vectors";
|
|
5
4
|
import type { SDFn } from "./api.js";
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Samples and discretizes the given SDF within the given bounding rect and
|
|
7
|
+
* resolution. The optional `domain` fn can be used to apply modifiers to each
|
|
8
|
+
* sample position. If `buf` is provided, writes results into it, else creates a
|
|
9
|
+
* new buffer automatically. Returns buffer.
|
|
10
|
+
*
|
|
11
|
+
* @param sdf
|
|
12
|
+
* @param bounds
|
|
13
|
+
* @param res
|
|
14
|
+
* @param domain
|
|
15
|
+
* @param buf
|
|
16
|
+
*/
|
|
17
|
+
export declare const sample2d: (sdf: SDFn, { pos: [px, py], size: [width, height] }: AABBLike, [resX, resY]: ReadonlyVec, domain?: Fn<ReadonlyVec, Vec>, buf?: NumericArray) => NumericArray;
|
|
8
18
|
//# sourceMappingURL=sample.d.ts.map
|
package/sample.js
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
|
-
import { isFunction } from "@thi.ng/checks/is-function";
|
|
2
1
|
import { assert } from "@thi.ng/errors/assert";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Samples and discretizes the given SDF within the given bounding rect and
|
|
4
|
+
* resolution. The optional `domain` fn can be used to apply modifiers to each
|
|
5
|
+
* sample position. If `buf` is provided, writes results into it, else creates a
|
|
6
|
+
* new buffer automatically. Returns buffer.
|
|
7
|
+
*
|
|
8
|
+
* @param sdf
|
|
9
|
+
* @param bounds
|
|
10
|
+
* @param res
|
|
11
|
+
* @param domain
|
|
12
|
+
* @param buf
|
|
13
|
+
*/
|
|
14
|
+
export const sample2d = (sdf, { pos: [px, py], size: [width, height] }, [resX, resY], domain, buf) => {
|
|
12
15
|
if (buf) {
|
|
13
16
|
assert(buf.length >= resX * resY, "insufficient buffer size");
|
|
14
17
|
}
|
|
@@ -22,16 +25,8 @@ export const sample2d = (sdf, { pos: [px, py], size: [width, height] }, [resX, r
|
|
|
22
25
|
p[1] = py + y * dy;
|
|
23
26
|
for (let x = 0; x < resX; x++, i++) {
|
|
24
27
|
p[0] = px + x * dx;
|
|
25
|
-
buf[i] = sdf(p);
|
|
28
|
+
buf[i] = sdf(domain ? domain(p) : p);
|
|
26
29
|
}
|
|
27
30
|
}
|
|
28
31
|
return buf;
|
|
29
32
|
};
|
|
30
|
-
export const asPolygons = (sdf, bounds, res, isoLevels = [0]) => {
|
|
31
|
-
const $sdf = isFunction(sdf) ? sample2d(sdf, bounds, res) : sdf;
|
|
32
|
-
const { pos, size } = bounds;
|
|
33
|
-
const [resX, resY] = res;
|
|
34
|
-
setBorder($sdf, resX, resY, 1e6);
|
|
35
|
-
const scale = div2([], size, [resX - 1, resY - 1]);
|
|
36
|
-
return transduce(comp(mapcat((iso) => isolines($sdf, resX, resY, iso, scale)), map((pts) => polygon(pts.map((p) => add2(null, p, pos))))), push(), isoLevels);
|
|
37
|
-
};
|
package/shapes.d.ts
CHANGED
|
@@ -2,8 +2,18 @@ import { ReadonlyVec } from "@thi.ng/vectors";
|
|
|
2
2
|
import type { SDFAttribs, SDFn } from "./api.js";
|
|
3
3
|
/** @internal */
|
|
4
4
|
export declare const DEFAULT_ATTRIBS: SDFAttribs;
|
|
5
|
+
/**
|
|
6
|
+
* Applies any SDF modifiers specified via {@link SDFAttribs} to the given
|
|
7
|
+
* distance function. Returns a possibly updated distance function.
|
|
8
|
+
*
|
|
9
|
+
* @remarks
|
|
10
|
+
* Order of application is: abs, offset, flip
|
|
11
|
+
*
|
|
12
|
+
* @param fn
|
|
13
|
+
* @param attribs
|
|
14
|
+
*/
|
|
5
15
|
export declare const withSDFAttribs: (fn: SDFn, attribs?: Partial<SDFAttribs>) => SDFn;
|
|
6
|
-
export declare const arc2: (apert: ReadonlyVec, ra: number, rb: number, attribs?: Partial<SDFAttribs>) => SDFn;
|
|
16
|
+
export declare const arc2: (center: ReadonlyVec, apert: ReadonlyVec, ra: number, rb: number, attribs?: Partial<SDFAttribs>) => SDFn;
|
|
7
17
|
export declare const box2: (center: ReadonlyVec, size: ReadonlyVec, attribs?: Partial<SDFAttribs>) => SDFn;
|
|
8
18
|
export declare const circle2: (center: ReadonlyVec, radius: number, attribs?: Partial<SDFAttribs>) => SDFn;
|
|
9
19
|
export declare const ellipse2: (center: ReadonlyVec, radii: ReadonlyVec, attribs?: Partial<SDFAttribs>) => SDFn;
|
|
@@ -11,5 +21,19 @@ export declare const line2: (a: ReadonlyVec, b: ReadonlyVec, attribs?: Partial<S
|
|
|
11
21
|
export declare const points2: (pts: ReadonlyVec[], attribs?: Partial<SDFAttribs>) => SDFn;
|
|
12
22
|
export declare const polygon2: (pts: ReadonlyVec[], attribs?: Partial<SDFAttribs>) => SDFn;
|
|
13
23
|
export declare const polyline2: (pts: ReadonlyVec[], attribs?: Partial<SDFAttribs>) => SDFn;
|
|
24
|
+
/**
|
|
25
|
+
* SDF for a single quadratic bezier segment. Similar to {@link line2}, by
|
|
26
|
+
* default only computes the _unsigned_ distance to the segment. To obtain the
|
|
27
|
+
* signed distance (for the "interior" region, if any), set the `abs` attribute
|
|
28
|
+
* explicitly to `false`.
|
|
29
|
+
*
|
|
30
|
+
* @remarks
|
|
31
|
+
* See {@link SDFAttribs.abs} for details.
|
|
32
|
+
*
|
|
33
|
+
* @param a
|
|
34
|
+
* @param b
|
|
35
|
+
* @param c
|
|
36
|
+
* @param attribs
|
|
37
|
+
*/
|
|
14
38
|
export declare const quadratic2: (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, attribs?: Partial<SDFAttribs>) => SDFn;
|
|
15
39
|
//# sourceMappingURL=shapes.d.ts.map
|
package/shapes.js
CHANGED
|
@@ -1,33 +1,81 @@
|
|
|
1
|
+
import { isFunction } from "@thi.ng/checks/is-function";
|
|
1
2
|
import { distSq2 } from "@thi.ng/vectors";
|
|
2
3
|
import { sub2 } from "@thi.ng/vectors/sub";
|
|
4
|
+
import { withBoundingCircle } from "./bounds.js";
|
|
3
5
|
import { distArc2, distBox2, distCircle2, distEllipse2, distPolygon2, distPolyline2, distQuadratic2, distSegment2, } from "./dist.js";
|
|
4
|
-
import { abs as $abs, flip as $flip,
|
|
6
|
+
import { abs as $abs, flip as $flip, offset as $offset } from "./ops.js";
|
|
5
7
|
/** @internal */
|
|
6
8
|
export const DEFAULT_ATTRIBS = {
|
|
7
9
|
abs: false,
|
|
10
|
+
bounds: false,
|
|
11
|
+
chamfer: 0,
|
|
8
12
|
combine: "union",
|
|
9
13
|
flip: false,
|
|
14
|
+
offset: 0,
|
|
10
15
|
round: 0,
|
|
11
16
|
smooth: 0,
|
|
12
17
|
};
|
|
18
|
+
/**
|
|
19
|
+
* Applies any SDF modifiers specified via {@link SDFAttribs} to the given
|
|
20
|
+
* distance function. Returns a possibly updated distance function.
|
|
21
|
+
*
|
|
22
|
+
* @remarks
|
|
23
|
+
* Order of application is: abs, offset, flip
|
|
24
|
+
*
|
|
25
|
+
* @param fn
|
|
26
|
+
* @param attribs
|
|
27
|
+
*/
|
|
13
28
|
export const withSDFAttribs = (fn, attribs) => {
|
|
14
29
|
if (attribs) {
|
|
15
|
-
const { abs, flip,
|
|
30
|
+
const { abs, flip, offset } = { ...DEFAULT_ATTRIBS, ...attribs };
|
|
16
31
|
if (abs)
|
|
17
32
|
fn = $abs(fn);
|
|
18
|
-
if (
|
|
19
|
-
fn = $
|
|
33
|
+
if (isFunction(offset) || offset > 0)
|
|
34
|
+
fn = $offset(fn, offset);
|
|
20
35
|
if (flip)
|
|
21
36
|
fn = $flip(fn);
|
|
22
37
|
}
|
|
23
38
|
return fn;
|
|
24
39
|
};
|
|
25
|
-
export const arc2 = (apert, ra, rb, attribs
|
|
40
|
+
export const arc2 = (center, apert, ra, rb, attribs = {}) => {
|
|
41
|
+
const sdf = withSDFAttribs((p) => distArc2(sub2([], p, center), apert, ra, rb), attribs);
|
|
42
|
+
return attribs.bounds ? withBoundingCircle(sdf, center, ra + rb) : sdf;
|
|
43
|
+
};
|
|
26
44
|
export const box2 = (center, size, attribs) => withSDFAttribs((p) => distBox2(sub2([], p, center), size), attribs);
|
|
27
45
|
export const circle2 = (center, radius, attribs) => withSDFAttribs((p) => distCircle2(sub2([], p, center), radius), attribs);
|
|
28
|
-
export const ellipse2 = (center, radii, attribs
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
46
|
+
export const ellipse2 = (center, radii, attribs = {}) => {
|
|
47
|
+
const sdf = withSDFAttribs((p) => distEllipse2(sub2([], p, center), radii), attribs);
|
|
48
|
+
return attribs.bounds
|
|
49
|
+
? withBoundingCircle(sdf, center, Math.max(...radii))
|
|
50
|
+
: sdf;
|
|
51
|
+
};
|
|
52
|
+
export const line2 = (a, b, attribs) => withSDFAttribs((p) => distSegment2(p, a, b), attribs);
|
|
53
|
+
export const points2 = (pts, attribs = {}) => {
|
|
54
|
+
const sdf = withSDFAttribs((p) => pts.reduce((acc, q) => Math.min(acc, distSq2(p, q)), Infinity), attribs);
|
|
55
|
+
return attribs.bounds ? withBoundingCircle(sdf, pts) : sdf;
|
|
56
|
+
};
|
|
57
|
+
export const polygon2 = (pts, attribs = {}) => {
|
|
58
|
+
const sdf = withSDFAttribs((p) => distPolygon2(p, pts), attribs);
|
|
59
|
+
return attribs.bounds ? withBoundingCircle(sdf, pts) : sdf;
|
|
60
|
+
};
|
|
61
|
+
export const polyline2 = (pts, attribs = {}) => {
|
|
62
|
+
const sdf = withSDFAttribs((p) => distPolyline2(p, pts), attribs);
|
|
63
|
+
return attribs.bounds ? withBoundingCircle(sdf, pts) : sdf;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* SDF for a single quadratic bezier segment. Similar to {@link line2}, by
|
|
67
|
+
* default only computes the _unsigned_ distance to the segment. To obtain the
|
|
68
|
+
* signed distance (for the "interior" region, if any), set the `abs` attribute
|
|
69
|
+
* explicitly to `false`.
|
|
70
|
+
*
|
|
71
|
+
* @remarks
|
|
72
|
+
* See {@link SDFAttribs.abs} for details.
|
|
73
|
+
*
|
|
74
|
+
* @param a
|
|
75
|
+
* @param b
|
|
76
|
+
* @param c
|
|
77
|
+
* @param attribs
|
|
78
|
+
*/
|
|
79
|
+
export const quadratic2 = (a, b, c, attribs) => withSDFAttribs(!attribs || attribs.abs !== false
|
|
80
|
+
? (p) => distQuadratic2(p, a, b, c)
|
|
81
|
+
: (p) => distQuadratic2(p, a, b, c, true), { ...attribs, abs: false });
|