Skip to content

Commit

Permalink
Merge branch 'feature/geom-complex-paths' into develop
Browse files Browse the repository at this point in the history
* feature/geom-complex-paths: (38 commits)
  refactor(geom): update centroid() for complexpoly
  feat(geom-poly-utils): add complexCenterOfWeight2()
  feat(examples): add rdom-klist example project, update readmes
  feat(geom): add complexPolygonFromPath()
  docs(geom): update readme
  test(geom): add tests
  build(geom): update pkg exports
  refactor(geom-sdf): add/update asSDF() impls for ComplexPoly & Path
  refactor(geom-axidraw): update asAxiDraw() impls
  feat(geom): add centroid() & convexHull() impl for Path
  docs(geom): add/update docstrings
  feat(geom): add pointInside() impl for Polyline
  feat(geom-isec): add pointInSegments() for polylines/polygons
  feat(geom): add closestPoint() impl for Path
  refactor(geom): update/simplify asPath() impls
  feat(geom): update pathFromCubics() to auto-create sub-paths if needed
  feat(geom): add/update asCubic() impls for complex poly & path
  refactor(geom): update area() impl for Path
  feat(geom): add arcLength() for Path, refactor complexpoly impl
  docs: regen readmes (examples)
  ...
  • Loading branch information
postspectacular committed May 6, 2024
2 parents cd458ac + 58ac296 commit 45a9c45
Show file tree
Hide file tree
Showing 66 changed files with 1,673 additions and 358 deletions.
Binary file added assets/examples/geom-complex-poly.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 20 additions & 0 deletions examples/geom-complex-poly/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# geom-complex-poly

![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/geom-complex-poly.png)

[Live demo](http://demo.thi.ng/umbrella/geom-complex-poly/)

## Developing & building

Please refer to the instructions on the wiki:

- [Development](https://github.com/thi-ng/umbrella/wiki/Development-mode-for-examples-using-thi.ng-meta%E2%80%90css)
- [Production build](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions)

## Authors

- Karsten Schmidt

## License

© 2024 Karsten Schmidt // Apache Software License 2.0
7 changes: 7 additions & 0 deletions examples/geom-complex-poly/css/custom.mcss.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"tables": {},
"vars": {},
"decls": [],
"specs": [],
"templates": []
}
2 changes: 2 additions & 0 deletions examples/geom-complex-poly/css/includes.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// list of CSS class names to force-include in generated CSS
// (one class per line, basic wildcards supported)
11 changes: 11 additions & 0 deletions examples/geom-complex-poly/css/style.mcss
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// thi.ng/meta-css stylesheet
// see package readme for more details/usage
// use `yarn css:build` or `yarn css:watch` to transpile to CSS
// also see component-specific *.mcss files in /src folder

// (optional) variable declarations
:root {
// color1=#fff
}

body { system-sans-serif ma3 }
33 changes: 33 additions & 0 deletions examples/geom-complex-poly/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html lang="en">
<head>
<link
rel="icon"
href='data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><text y=".9em" font-size="90">⛱️</text></svg>'
/>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>geom-complex-poly · @thi.ng/umbrella</title>
<link href="/css/style.css" rel="stylesheet" />
<script>
window.goatcounter = { path: (p) => location.host + p };
</script>
<script
data-goatcounter="https://thing.goatcounter.com/count"
async
src="//gc.zgo.at/count.js"
></script>
</head>
<body>
<div id="app"></div>
<div>
<a
class="link"
href="https://github.com/thi-ng/umbrella/tree/develop/examples/geom-complex-poly"
>Source code</a
>
</div>
<script type="module" src="/src/index.ts"></script>
</body>
</html>
47 changes: 47 additions & 0 deletions examples/geom-complex-poly/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"name": "@example/geom-complex-poly",
"version": "0.0.1",
"private": true,
"description": "Shape conversions & operations using polygons with holes",
"repository": "https://github.com/thi-ng/umbrella",
"author": "Karsten Schmidt <k+npm@thi.ng>",
"license": "Apache-2.0",
"scripts": {
"start": "yarn css:build && yarn start:only",
"start:only": "vite --host --open",
"css:watch": "../../node_modules/.bin/metacss develop --bundle --watch --pretty --out-specs css/framework.json --out-css css/style.css --force @css/includes.txt ../../packages/meta-css/specs/*.mcss.json css/*.mcss.json css/*.mcss",
"css:build": "../../node_modules/.bin/metacss develop --bundle --out-specs css/framework.json --out-css css/style.css --force @css/includes.txt ../../packages/meta-css/specs/*.mcss.json css/*.mcss.json css/*.mcss",
"build": "yarn css:build && tsc && vite build --base='./'",
"preview": "vite preview --host --open"
},
"devDependencies": {
"@thi.ng/meta-css": "workspace:^",
"typescript": "^5.4.3",
"vite": "^5.2.6"
},
"dependencies": {
"@thi.ng/canvas": "workspace:^",
"@thi.ng/color": "workspace:^",
"@thi.ng/geom": "workspace:^",
"@thi.ng/geom-accel": "workspace:^",
"@thi.ng/geom-api": "workspace:^",
"@thi.ng/hiccup-canvas": "workspace:^",
"@thi.ng/math": "workspace:^",
"@thi.ng/poisson": "workspace:^",
"@thi.ng/transducers": "workspace:^"
},
"browser": {
"process": false
},
"thi.ng": {
"readme": [
"canvas",
"color",
"geom",
"hiccup-canvas",
"poisson",
"transducers"
],
"screenshot": "examples/geom-complex-poly.png"
}
}
155 changes: 155 additions & 0 deletions examples/geom-complex-poly/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
import { adaptiveCanvas2d } from "@thi.ng/canvas";
import { COSINE_GRADIENTS, cosineColor } from "@thi.ng/color";
import {
SUBDIV_CHAIKIN_CLOSED,
asPath,
asPolygon,
complexPolygon,
group,
pathFromSvg,
pointInside,
points,
proximity,
scatter,
simplify,
star,
subdivCurve,
text,
vertices,
withAttribs,
} from "@thi.ng/geom";
import { KdTreeSet } from "@thi.ng/geom-accel";
import type { IHiccupShape } from "@thi.ng/geom-api";
import { draw } from "@thi.ng/hiccup-canvas";
import { fitClamped } from "@thi.ng/math";
import { samplePoisson } from "@thi.ng/poisson";
import { filter, range2d } from "@thi.ng/transducers";

const W = 300;
const R = W / 2;
const R2 = R / 4;
const COLW = W + 150;

// 8-sided star polygon
const A = star(R, 8, [1, 1 / 2]);

// plus-shaped polygon from SVG path
const B = asPolygon(
pathFromSvg(`M-10,${R2}H10V10H${R2}V-10H10V${-R2}H-10V-10H${-R2}V10H-10z`),
{ num: 1 }
)[0];

// complex polygon with A as outer shell and B as hole
const C = complexPolygon(A, [B]);

// subdivided version for future ref
const D = subdivCurve(C, SUBDIV_CHAIKIN_CLOSED, 3);

// create different shape variations
const SHAPES: [IHiccupShape, string][] = [
[A, "original"],
[C, "with hole"],
[subdivCurve(C, SUBDIV_CHAIKIN_CLOSED, 1), "subdiv x1"],
[subdivCurve(C, SUBDIV_CHAIKIN_CLOSED, 2), "subdiv x2"],
[D, "subdiv x3"],
[subdivCurve(C, SUBDIV_CHAIKIN_CLOSED, 4), "subdiv x4"],
[
asPath(C, {
breakPoints: false,
scale: 1,
}),
"asPath()",
],
[asPath(C, { breakPoints: true }), "asPath()"],
[
points(vertices(C, { dist: 5 }), { size: 2, shape: "circle" }),
"vertices (dist: 5)",
],
[
points(vertices(D, { dist: 5 }), {
size: 2,
shape: "circle",
}),
"subdiv vertices",
],
[
points(vertices(simplify(D, 1)), {
size: 2,
shape: "circle",
}),
"simplified vertices",
],
[
points(
filter(
(p) => pointInside(C, p),
range2d(-200, 200, -200, 200, 5, 5)
),
{
size: 2,
shape: "circle",
}
),
"pointInside()",
],
[
points(scatter(C, 1000), {
size: 2,
shape: "circle",
}),
"scatter()",
],
[
points(
samplePoisson({
density: (p) => fitClamped(proximity(D, p)!, 0, 50, 2, 10),
points: () => scatter(D, 1)![0],
index: new KdTreeSet(2),
max: 2000,
}),
{
size: 2,
shape: "circle",
}
),
"poisson samples",
],
];

// color gradient preset
const GRAD = COSINE_GRADIENTS["blue-magenta-orange"];

// create canvas, compute size for 2-column layout
const { ctx } = adaptiveCanvas2d(
COLW * 2,
Math.ceil(SHAPES.length / 2) * W,
document.body
);

// draw all shapes & labels in 2-column layout
draw(
ctx,
group(
{
fill: "black",
font: "1rem sans-serif",
baseline: "middle",
scale: window.devicePixelRatio,
},
SHAPES.map(([shape, label], i) =>
group(
{
translate: [(i & 1) * COLW + R, (i >> 1) * W + R],
},
[
withAttribs(
shape,
{ fill: cosineColor(GRAD, i / (SHAPES.length - 1)) },
false
),
text([R + 10, 0], label),
]
)
)
)
);
1 change: 1 addition & 0 deletions examples/geom-complex-poly/src/vite-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/// <reference types="vite/client" />
6 changes: 6 additions & 0 deletions examples/geom-complex-poly/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"extends": "../tsconfig.json",
"include": ["src/**/*"],
"compilerOptions": {
}
}
3 changes: 3 additions & 0 deletions examples/geom-complex-poly/vite.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default {
build: { target: "esnext" },
};
2 changes: 1 addition & 1 deletion examples/geom-tessel/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ const tessellation = (t: number, tessel: Tessellator[], tint: Tint) => {
asPolygon(
circle([0, 0], W2),
Math.floor(fit11(Math.sin(t), MIN_RES, MAX_RES))
),
)[0],
tessel
)
);
Expand Down
2 changes: 1 addition & 1 deletion examples/poly-subdiv/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ function* update() {
// https://mastodon.thi.ng/@toxi/110972322869333970
const shapes = threadLast(
// original shape: circle w/ radius=300, converted to polygon with N vertices
[asPolygon(circle(300), 40)],
[asPolygon(circle(300), 40)[0]],
// lazy, iterative & infinite(!) subdivision: `iterate()` produces the
// inductive sequence: f(x+1) = f(f(x)), i.e. the result of the current
// iteration becomes the input for the next iteration...
Expand Down
4 changes: 2 additions & 2 deletions examples/scenegraph/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ const hex = new GeomNode(
[300, 300],
0,
200,
asPolygon(circle(0.5, { fill: "#0ff" }), 6)
asPolygon(circle(0.5, { fill: "#0ff" }), 6)[0]
);

// rotated child node
Expand All @@ -74,7 +74,7 @@ const triangle = new GeomNode(
[0, 0],
PI / 4,
1,
asPolygon(circle(0.5, { fill: "#f0f" }), 3)
asPolygon(circle(0.5, { fill: "#f0f" }), 3)[0]
);

// secondary children
Expand Down
15 changes: 5 additions & 10 deletions examples/svg-resample/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,7 @@ import { fit11 } from "@thi.ng/math";
import { $compile, $replace } from "@thi.ng/rdom";
import { fromRAF } from "@thi.ng/rstream";
import { parse, Type } from "@thi.ng/sax";
import {
comp,
filter,
map,
mapcat,
push,
transduce,
} from "@thi.ng/transducers";
import { comp, filter, map, push, transduce } from "@thi.ng/transducers";
import SVG from "./example.svg";

(async () => {
Expand All @@ -32,7 +25,7 @@ import SVG from "./example.svg";
filter((ev) => ev.type === Type.ELEM_END && ev.tag === "path"),
// pathFromSvg() returns an array of subpaths
// using mapcat() flattens that array
mapcat((ev) => pathFromSvg(ev.attribs!.d))
map((ev) => pathFromSvg(ev.attribs!.d))
),
push<Path>(),
await raw.text()
Expand All @@ -46,7 +39,9 @@ import SVG from "./example.svg";
// - first into a polygon
// - then resample poly using uniform distance and extract vertices
// - wrap in `points` container (aka point cloud)
return paths.map((path) => points(vertices(asPolygon(path), { dist })));
return paths.map((path) =>
points(vertices(asPolygon(path)[0], { dist }))
);
};

// now create reactive requestAnimationFrame() stream which:
Expand Down
1 change: 1 addition & 0 deletions packages/canvas/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ directory are using this package:
|:----------------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------|:-----------------------------------------------------------|:----------------------------------------------------------------------------------------|
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/blurhash.jpg" width="240"/> | Interactive & reactive image blurhash generator | [Demo](https://demo.thi.ng/umbrella/blurhash/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/blurhash) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/canvas-recorder.png" width="240"/> | Self-modifying, animated typographic grid with emergent complex patterns | [Demo](https://demo.thi.ng/umbrella/canvas-recorder/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/canvas-recorder) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/geom-complex-poly.png" width="240"/> | Shape conversions & operations using polygons with holes | [Demo](https://demo.thi.ng/umbrella/geom-complex-poly/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/geom-complex-poly) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/geom/geom-fuzz.png" width="240"/> | geom-fuzz basic shape & fill examples | [Demo](https://demo.thi.ng/umbrella/geom-fuzz-basics/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/geom-fuzz-basics) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/grid-iterators.png" width="240"/> | Visualization of different grid iterator strategies | [Demo](https://demo.thi.ng/umbrella/grid-iterators/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/grid-iterators) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/hiccup-canvas-basics.png" width="240"/> | Basic hiccup-based canvas drawing | [Demo](https://demo.thi.ng/umbrella/hiccup-canvas-basics/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/hiccup-canvas-basics) |
Expand Down
1 change: 1 addition & 0 deletions packages/color/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,7 @@ directory are using this package:
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/commit-heatmap.png" width="240"/> | Heatmap visualization of this mono-repo's commits | | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/commit-heatmap) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/dominant-colors.png" width="240"/> | Color palette generation via dominant color extraction from uploaded images | [Demo](https://demo.thi.ng/umbrella/dominant-colors/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/dominant-colors) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/fiber-basics.png" width="240"/> | Fiber-based cooperative multitasking basics | [Demo](https://demo.thi.ng/umbrella/fiber-basics/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/fiber-basics) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/geom-complex-poly.png" width="240"/> | Shape conversions & operations using polygons with holes | [Demo](https://demo.thi.ng/umbrella/geom-complex-poly/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/geom-complex-poly) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/grid-iterators.png" width="240"/> | Visualization of different grid iterator strategies | [Demo](https://demo.thi.ng/umbrella/grid-iterators/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/grid-iterators) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/hdom-canvas/hdom-canvas-shapes-results.png" width="240"/> | Various hdom-canvas shape drawing examples & SVG conversion / export | [Demo](https://demo.thi.ng/umbrella/hdom-canvas-shapes/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/hdom-canvas-shapes) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/hiccup-canvas-basics.png" width="240"/> | Basic hiccup-based canvas drawing | [Demo](https://demo.thi.ng/umbrella/hiccup-canvas-basics/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/hiccup-canvas-basics) |
Expand Down
Loading

0 comments on commit 45a9c45

Please sign in to comment.