Skip to content

Instantly share code, notes, and snippets.

@postspectacular
Created July 18, 2024 15:38
Show Gist options
  • Save postspectacular/690439517fc2822ca63389b7cb33f18f to your computer and use it in GitHub Desktop.
Save postspectacular/690439517fc2822ca63389b7cb33f18f to your computer and use it in GitHub Desktop.
Hatched polygons with https://thi.ng/umbrella
import {
asSvg,
bounds,
circleFrom2Points,
group,
GroupAttribs,
line,
Polygon,
starWithCentroid,
svgDoc,
} from "@thi.ng/geom";
import { clipLinePoly } from "@thi.ng/geom-clip-line";
import { TAU } from "@thi.ng/math";
import {
add2,
cartesian2,
maddN2,
normalize2,
perpendicularCW,
sub2,
} from "@thi.ng/vectors";
import { writeFileSync } from "fs";
/**
* Creates a group of hatch lines for given polygon. The direction of the hatch
* lines is defined by `theta` (in radians) and their density/distance by
* `step`.
*
* @param attribs
* @param shape
* @param theta
* @param step
*/
const hatch = (attribs: GroupAttribs, shape: Polygon, theta = 0, step = 1) => {
const res = group(attribs);
const b = bounds(shape)!;
if (!b) return res;
// bounding circle of bounding box
const bc = circleFrom2Points(b.min(), b.max());
// hatch dir
const dir = cartesian2(null, [bc.r, theta]);
// hatch normal (ray direction)
const norm = normalize2(null, perpendicularCW([], dir));
// ray start point
const start = maddN2([], norm, -bc.r, bc.pos);
for (let d = 0, maxD = bc.r * 2; d <= maxD; d += step) {
// next point on ray
const m = maddN2([], norm, d, start);
// intersect line segment with poly
const segments = clipLinePoly(
sub2([], m, dir),
add2([], m, dir),
poly.points
);
if (!segments) continue;
// add segments to group
for (let s of segments) res.add(line(s));
}
return res;
};
const poly = starWithCentroid([50, 50], 50, 6, [0.5, 1]);
const geo = group({}, [
poly,
hatch({ stroke: "#f00" }, poly, 0),
hatch({ stroke: "#0f0" }, poly, (1 / 3) * TAU),
hatch({ stroke: "#09f" }, poly, (2 / 3) * TAU),
]);
writeFileSync("export/hatching.svg", asSvg(svgDoc({ weight: 0.1 }, geo)));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment