Skip to content

Commit

Permalink
refactor(geom-subdiv-curve): update SUBDIV_DISPLACE, internal refacto…
Browse files Browse the repository at this point in the history
…ring
  • Loading branch information
postspectacular committed May 31, 2024
1 parent 03c5e54 commit 3e84ba8
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 21 deletions.
18 changes: 12 additions & 6 deletions packages/geom-api/src/subdiv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@ import type { ReadonlyVec, Vec } from "@thi.ng/vectors";

export interface SubdivKernel {
/**
* Subdivision function. Called with an array of `size` consecutive
* points of the original curve and can produce any number of result
* points. Additionally is passed the index `i` of the processed
* point and `nump`, the total number of point in the
* curve/polyline. The latter 2 args are useful to implement custom
* behaviors for the start / end points of the curve.
* Subdivision function. Called with an array of {@link SubdivKernel.size}
* consecutive points of the original curve and can produce any number of
* result points. Additionally is passed the index `i` of the processed
* point and `nump`, the total number of point in the curve/polyline. The
* latter 2 args are useful to implement custom behaviors for the start /
* end points of the curve.
*
* @param pts
* @param i
* @param nump
*/
fn: (pts: ReadonlyVec[], i: number, nump: number) => Vec[];
/**
Expand All @@ -16,6 +20,8 @@ export interface SubdivKernel {
* points (e.g. for closed curves / polygons to prepend the last
* point before the first). If omitted, the curve points are
* processed as is.
*
* @param pts
*/
pre?: (pts: ReadonlyVec[]) => Iterable<ReadonlyVec>;
/**
Expand Down
35 changes: 20 additions & 15 deletions packages/geom-subdiv-curve/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,22 @@ import { perpendicularCW } from "@thi.ng/vectors/perpendicular";
import { sub2 } from "@thi.ng/vectors/sub";
import { kernel3 } from "./kernels.js";

/** @internal */
const MIDP = ([a, b]: ReadonlyVec[]) => [a, addmN([], a, b, 0.5)];
/** @internal */
const THIRDS = ([a, b]: ReadonlyVec[]) => [
a,
mixN([], a, b, 1 / 3),
mixN([], a, b, 2 / 3),
];

const wrap2 = (pts: ReadonlyVec[]) => wrapSides(pts, 0, 1);
const wrap3 = (pts: ReadonlyVec[]) => wrapSides(pts, 1, 1);
/** @internal */
const __wrap2 = (pts: ReadonlyVec[]) => wrapSides(pts, 0, 1);
/** @internal */
const __wrap3 = (pts: ReadonlyVec[]) => wrapSides(pts, 1, 1);

const subdivWith =
/** @internal */
const __subdivOpen =
(fn: FnU<ReadonlyVec[]>): SubdivKernel["fn"] =>
(pts, i, n) =>
i < n - 2 ? fn(pts) : [...fn(pts), pts[1]];
Expand All @@ -31,7 +36,7 @@ const subdivWith =
* open curves.
*/
export const SUBDIV_MID_OPEN: SubdivKernel = {
fn: subdivWith(MIDP),
fn: __subdivOpen(MIDP),
size: 2,
};

Expand All @@ -41,7 +46,7 @@ export const SUBDIV_MID_OPEN: SubdivKernel = {
*/
export const SUBDIV_MID_CLOSED: SubdivKernel = {
fn: MIDP,
pre: wrap2,
pre: __wrap2,
size: 2,
};

Expand All @@ -50,7 +55,7 @@ export const SUBDIV_MID_CLOSED: SubdivKernel = {
* open curves.
*/
export const SUBDIV_THIRDS_OPEN: SubdivKernel = {
fn: subdivWith(THIRDS),
fn: __subdivOpen(THIRDS),
size: 2,
};

Expand All @@ -60,7 +65,7 @@ export const SUBDIV_THIRDS_OPEN: SubdivKernel = {
*/
export const SUBDIV_THIRDS_CLOSED: SubdivKernel = {
fn: THIRDS,
pre: wrap2,
pre: __wrap2,
size: 2,
};

Expand All @@ -86,18 +91,16 @@ export const SUBDIV_CHAIKIN_OPEN: SubdivKernel = {
*/
export const SUBDIV_CHAIKIN_CLOSED: SubdivKernel = {
fn: CHAIKIN_MAIN,
pre: wrap3,
pre: __wrap3,
size: 3,
};

const CUBIC_MAIN = kernel3([1 / 8, 3 / 4, 1 / 8], [0, 1 / 2, 1 / 2]);

/**
* Cubic bezier subdivision scheme for closed curves.
*/
export const SUBDIV_CUBIC_CLOSED: SubdivKernel = {
fn: CUBIC_MAIN,
pre: wrap3,
fn: kernel3([1 / 8, 3 / 4, 1 / 8], [0, 1 / 2, 1 / 2]),
pre: __wrap3,
size: 3,
};

Expand All @@ -121,14 +124,16 @@ export const SUBDIV_DISPLACE = (
closed = false
): SubdivKernel => ({
size: 2,
pre: closed ? wrap2 : undefined,
fn: ([a, b]) => {
pre: closed ? __wrap2 : undefined,
fn: ([a, b], i, nump) => {
const num = displace.length;
const delta = sub2([], b, a);
const len = mag2(delta);
const normal = perpendicularCW(null, normalize2([], delta));
return displace.map((x, i) =>
const res = displace.map((x, i) =>
addW3([], a, delta, normal, 1, i / num, x * len)
);
if (!closed && i === nump - 2) res.push(b);
return res;
},
});

0 comments on commit 3e84ba8

Please sign in to comment.