Skip to content

Commit

Permalink
feat(geom): update pathFromCubics() to auto-create sub-paths if needed
Browse files Browse the repository at this point in the history
  • Loading branch information
postspectacular committed May 5, 2024
1 parent 7f9e927 commit 1170e45
Showing 1 changed file with 32 additions and 4 deletions.
36 changes: 32 additions & 4 deletions packages/geom/src/path.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import type { Maybe } from "@thi.ng/api";
import { isNumber } from "@thi.ng/checks/is-number";
import type { Attribs, PathSegment } from "@thi.ng/geom-api";
import { map } from "@thi.ng/transducers/map";
import { mapcat } from "@thi.ng/transducers/mapcat";
import type { Vec } from "@thi.ng/vectors";
import type { ReadonlyVec, Vec } from "@thi.ng/vectors";
import { equals2 } from "@thi.ng/vectors/equals";
import { maddN2 } from "@thi.ng/vectors/maddn";
import type { Cubic } from "./api/cubic.js";
import { Path } from "./api/path.js";
Expand All @@ -15,12 +17,38 @@ export const path = (
attribs?: Attribs
) => new Path(segments, subPaths, attribs);

/**
* Constructs a {@link Path} from given sequence of cubic curves, with optional
* `attribs`.
*
* @remarks
* If no `attribs` are given, those from the first curve will be used.
*
* For each successive curve segment, if the start point of the current curve is
* not the same as the last point of the previous curve, a new sub path will be
* started.
*
* @param cubics
* @param attribs
*/
export const pathFromCubics = (cubics: Cubic[], attribs?: Attribs) => {
const path = new Path([], [], attribs || cubics[0].attribs);
path.segments.push({ type: "m", point: cubics[0].points[0] });
let subPaths: PathSegment[][] = [];
let curr: PathSegment[];
let lastP: Maybe<ReadonlyVec>;
const $beginPath = (c: Cubic) => {
curr = [{ type: "m", point: c.points[0] }];
subPaths.push(curr);
};
for (let c of cubics) {
path.segments.push({ type: "c", geo: c });
if (!(lastP && equals2(lastP, c.points[0]))) $beginPath(c);
curr!.push({ type: "c", geo: c });
lastP = c.points[3];
}
const path = new Path(
subPaths[0],
subPaths.slice(1),
attribs || cubics[0].attribs
);
return path;
};

Expand Down

0 comments on commit 1170e45

Please sign in to comment.