Skip to content

Commit

Permalink
feat(geom): update various shape ctors to accept iterables
Browse files Browse the repository at this point in the history
- update shared APC ctor
- update other shape ctors: BPatch, Group, Path
- add assertions to verify vertex counts in these ctors:
  - BPatch
  - Cubic
  - Line
  - Quad/Quad3
  - Quadratic
  - Triangle
postspectacular committed Aug 28, 2023
1 parent 689bbab commit ae0cf5b
Showing 22 changed files with 93 additions and 39 deletions.
7 changes: 6 additions & 1 deletion packages/geom/src/api/apc.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import type { IClear } from "@thi.ng/api";
import { ensureArray } from "@thi.ng/arrays/ensure-array";
import type { Attribs, PCLike } from "@thi.ng/geom-api";
import type { Vec } from "@thi.ng/vectors";

export abstract class APC implements IClear, PCLike {
constructor(public points: Vec[] = [], public attribs?: Attribs) {}
points: Vec[];

constructor(points?: Iterable<Vec>, public attribs?: Attribs) {
this.points = points ? ensureArray(points) : [];
}

abstract get type(): number | string;

6 changes: 3 additions & 3 deletions packages/geom/src/api/bpatch.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { assert } from "@thi.ng/errors/assert";
import type { Attribs, IHiccupShape } from "@thi.ng/geom-api";
import type { ReadonlyVec, Vec, VecPair } from "@thi.ng/vectors";
import { mixCubic } from "@thi.ng/vectors/mix-cubic";
import { __copyShape } from "../internal/copy.js";
import { __ensureNumVerts } from "../internal/pclike.js";
import { APC } from "./apc.js";

/**
@@ -32,9 +32,9 @@ import { APC } from "./apc.js";
*
*/
export class BPatch extends APC implements IHiccupShape {
constructor(points: Vec[], attribs?: Attribs) {
assert(points.length === 16, "require 16 control points");
constructor(points: Iterable<Vec>, attribs?: Attribs) {
super(points, attribs);
__ensureNumVerts(this.points.length, 16);
}

get type() {
7 changes: 7 additions & 0 deletions packages/geom/src/api/cubic.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import type { Attribs, IHiccupPathSegment } from "@thi.ng/geom-api";
import type { Vec } from "@thi.ng/vectors";
import { __copyShape } from "../internal/copy.js";
import { __ensureNumVerts } from "../internal/pclike.js";
import { APC } from "./apc.js";

export class Cubic extends APC implements IHiccupPathSegment {
constructor(points: Iterable<Vec>, attribs?: Attribs) {
super(points, attribs);
__ensureNumVerts(this.points.length, 4);
}

get type() {
return "cubic";
}
10 changes: 6 additions & 4 deletions packages/geom/src/api/group.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { Fn, IClear } from "@thi.ng/api";
import { ensureArray } from "@thi.ng/arrays/ensure-array";
import { equiv } from "@thi.ng/equiv";
import type { Attribs, IHiccupShape } from "@thi.ng/geom-api";
import { __copyAttribs } from "../internal/copy.js";
@@ -8,10 +9,11 @@ import { __copyAttribs } from "../internal/copy.js";
* groups.
*/
export class Group implements IClear, IHiccupShape {
constructor(
public attribs?: Attribs,
public children: IHiccupShape[] = []
) {}
children: IHiccupShape[];

constructor(public attribs?: Attribs, children?: Iterable<IHiccupShape>) {
this.children = children ? ensureArray(children) : [];
}

get type() {
return "group";
7 changes: 7 additions & 0 deletions packages/geom/src/api/line.ts
Original file line number Diff line number Diff line change
@@ -3,10 +3,17 @@ import type {
IHiccupPathSegment,
IHiccupShape,
} from "@thi.ng/geom-api";
import type { Vec } from "@thi.ng/vectors";
import { __copyShape } from "../internal/copy.js";
import { __ensureNumVerts } from "../internal/pclike.js";
import { APC } from "./apc.js";

export class Line extends APC implements IHiccupShape, IHiccupPathSegment {
constructor(points: Iterable<Vec>, attribs?: Attribs) {
super(points, attribs);
__ensureNumVerts(this.points.length, 2);
}

get type() {
return "line";
}
9 changes: 5 additions & 4 deletions packages/geom/src/api/path.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import type { IClear } from "@thi.ng/api";
import { ensureArray } from "@thi.ng/arrays/ensure-array";
import { equiv } from "@thi.ng/equiv";
import { illegalState } from "@thi.ng/errors/illegal-state";
import type { Attribs, IHiccupShape, PathSegment } from "@thi.ng/geom-api";
import { copy } from "@thi.ng/vectors/copy";
import { __copyAttribs } from "../internal/copy.js";

export class Path implements IClear, IHiccupShape {
segments: PathSegment[];
closed = false;

constructor(
public segments: PathSegment[] = [],
public attribs?: Attribs
) {}
constructor(segments?: Iterable<PathSegment>, public attribs?: Attribs) {
this.segments = segments ? ensureArray(segments) : [];
}

get type() {
return "path";
7 changes: 7 additions & 0 deletions packages/geom/src/api/quad.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import type { Attribs, IHiccupShape } from "@thi.ng/geom-api";
import type { Vec } from "@thi.ng/vectors";
import { __copyShape } from "../internal/copy.js";
import { __ensureNumVerts } from "../internal/pclike.js";
import { APC } from "./apc.js";

export class Quad extends APC implements IHiccupShape {
constructor(points: Iterable<Vec>, attribs?: Attribs) {
super(points, attribs);
__ensureNumVerts(this.points.length, 4);
}

get type() {
return "quad";
}
7 changes: 7 additions & 0 deletions packages/geom/src/api/quad3.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import type { Attribs, IHiccupShape } from "@thi.ng/geom-api";
import type { Vec } from "@thi.ng/vectors";
import { __copyShape } from "../internal/copy.js";
import { __ensureNumVerts } from "../internal/pclike.js";
import { APC } from "./apc.js";

export class Quad3 extends APC implements IHiccupShape {
constructor(points: Iterable<Vec>, attribs?: Attribs) {
super(points, attribs);
__ensureNumVerts(this.points.length, 4);
}

get type() {
return "quad3";
}
7 changes: 7 additions & 0 deletions packages/geom/src/api/quadratic.ts
Original file line number Diff line number Diff line change
@@ -3,10 +3,17 @@ import type {
IHiccupPathSegment,
IHiccupShape,
} from "@thi.ng/geom-api";
import type { Vec } from "@thi.ng/vectors";
import { __copyShape } from "../internal/copy.js";
import { __ensureNumVerts } from "../internal/pclike.js";
import { APC } from "./apc.js";

export class Quadratic extends APC implements IHiccupShape, IHiccupPathSegment {
constructor(points: Iterable<Vec>, attribs?: Attribs) {
super(points, attribs);
__ensureNumVerts(this.points.length, 3);
}

get type() {
return "quadratic";
}
7 changes: 7 additions & 0 deletions packages/geom/src/api/triangle.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import type { Attribs, IHiccupShape } from "@thi.ng/geom-api";
import type { Vec } from "@thi.ng/vectors";
import { __copyShape } from "../internal/copy.js";
import { __ensureNumVerts } from "../internal/pclike.js";
import { APC } from "./apc.js";

export class Triangle extends APC implements IHiccupShape {
constructor(points: Iterable<Vec>, attribs?: Attribs) {
super(points, attribs);
__ensureNumVerts(this.points.length, 3);
}

get type() {
return "tri";
}
2 changes: 1 addition & 1 deletion packages/geom/src/bpatch.ts
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ import type { Vec } from "@thi.ng/vectors";
import { mixBilinear } from "@thi.ng/vectors/mix-bilinear";
import { BPatch } from "./api/bpatch.js";

export const bpatch = (pts: Vec[], attribs?: Attribs) =>
export const bpatch = (pts: Iterable<Vec>, attribs?: Attribs) =>
new BPatch(pts, attribs);

export const bpatchFromQuad = (pts: Vec[], attribs?: Attribs) => {
2 changes: 1 addition & 1 deletion packages/geom/src/cubic.ts
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ import { __copyAttribs } from "./internal/copy.js";
import { __pclike } from "./internal/pclike.js";

export function cubic(a: Vec, b: Vec, c: Vec, d: Vec, attribs?: Attribs): Cubic;
export function cubic(pts: Vec[], attribs?: Attribs): Cubic;
export function cubic(pts: Iterable<Vec>, attribs?: Attribs): Cubic;
export function cubic(...args: any[]) {
return __pclike(Cubic, args);
}
6 changes: 4 additions & 2 deletions packages/geom/src/group.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import type { Attribs, IHiccupShape } from "@thi.ng/geom-api";
import { Group } from "./api/group.js";

export const group = (attribs: Attribs = {}, children?: IHiccupShape[]) =>
new Group(attribs, children);
export const group = (
attribs: Attribs = {},
children?: Iterable<IHiccupShape>
) => new Group(attribs, children);
6 changes: 5 additions & 1 deletion packages/geom/src/internal/pclike.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { __argAttribs } from "./args.js";
import { assert } from "@thi.ng/errors/assert";
import type { PCLikeConstructor } from "@thi.ng/geom-api";
import { __argAttribs } from "./args.js";

export const __pclike = (ctor: PCLikeConstructor, args: any[]) => {
const attr = __argAttribs(args);
return new ctor(args.length === 1 ? args[0] : args, attr);
};

export const __ensureNumVerts = (num: number, expected: number) =>
assert(num === expected, `require ${expected} points`);
2 changes: 1 addition & 1 deletion packages/geom/src/line.ts
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ import { Rect } from "./api/rect.js";
import { __pclike } from "./internal/pclike.js";

export function line(a: Vec, b: Vec, attribs?: Attribs): Line;
export function line(pts: Vec[], attribs?: Attribs): Line;
export function line(pts: Iterable<Vec>, attribs?: Attribs): Line;
export function line(...args: any[]) {
return __pclike(Line, args);
}
24 changes: 11 additions & 13 deletions packages/geom/src/path.ts
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ import { Path } from "./api/path.js";
import { asCubic } from "./as-cubic.js";
import { PathBuilder } from "./path-builder.js";

export const path = (segments: PathSegment[], attribs?: Attribs) =>
export const path = (segments: Iterable<PathSegment>, attribs?: Attribs) =>
new Path(segments, attribs);

export const pathFromCubics = (cubics: Cubic[], attribs?: Attribs) => {
@@ -23,18 +23,16 @@ export const pathFromCubics = (cubics: Cubic[], attribs?: Attribs) => {

export const normalizedPath = (path: Path) =>
new Path(
[
...mapcat(
(s) =>
s.geo
? map<Cubic, PathSegment>(
(c) => ({ type: "c", geo: c }),
asCubic(s.geo)
)
: [{ ...s }],
path.segments
),
],
mapcat(
(s) =>
s.geo
? map<Cubic, PathSegment>(
(c) => ({ type: "c", geo: c }),
asCubic(s.geo)
)
: [{ ...s }],
path.segments
),
path.attribs
);

4 changes: 2 additions & 2 deletions packages/geom/src/points.ts
Original file line number Diff line number Diff line change
@@ -2,8 +2,8 @@ import type { Attribs } from "@thi.ng/geom-api";
import type { Vec } from "@thi.ng/vectors";
import { Points, Points3 } from "./api/points.js";

export const points = (pts?: Vec[], attribs?: Attribs) =>
export const points = (pts?: Iterable<Vec>, attribs?: Attribs) =>
new Points(pts, attribs);

export const points3 = (pts?: Vec[], attribs?: Attribs) =>
export const points3 = (pts?: Iterable<Vec>, attribs?: Attribs) =>
new Points3(pts, attribs);
2 changes: 1 addition & 1 deletion packages/geom/src/polygon.ts
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@ import type { Vec } from "@thi.ng/vectors";
import { cartesian2 } from "@thi.ng/vectors/cartesian";
import { Polygon } from "./api/polygon.js";

export const polygon = (pts?: Vec[], attribs?: Attribs) =>
export const polygon = (pts?: Iterable<Vec>, attribs?: Attribs) =>
new Polygon(pts, attribs);

/**
2 changes: 1 addition & 1 deletion packages/geom/src/polyline.ts
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ import type { ReadonlyVec, Vec } from "@thi.ng/vectors";
import { cartesian2 } from "@thi.ng/vectors/cartesian";
import { Polyline } from "./api/polyline.js";

export const polyline = (pts: Vec[], attribs?: Attribs) =>
export const polyline = (pts: Iterable<Vec>, attribs?: Attribs) =>
new Polyline(pts, attribs);

/**
4 changes: 2 additions & 2 deletions packages/geom/src/quad.ts
Original file line number Diff line number Diff line change
@@ -12,13 +12,13 @@ import { __argAttribs } from "./internal/args.js";
import { __pclike } from "./internal/pclike.js";

export function quad(a: Vec, b: Vec, c: Vec, d: Vec, attribs?: Attribs): Quad;
export function quad(pts: Vec[], attribs?: Attribs): Quad;
export function quad(pts: Iterable<Vec>, attribs?: Attribs): Quad;
export function quad(...args: any[]) {
return __pclike(Quad, args);
}

export function quad3(a: Vec, b: Vec, c: Vec, d: Vec, attribs?: Attribs): Quad;
export function quad3(pts: Vec[], attribs?: Attribs): Quad;
export function quad3(pts: Iterable<Vec>, attribs?: Attribs): Quad;
export function quad3(...args: any[]) {
const attr = __argAttribs(args);
return new Quad3(args.length === 1 ? args[0] : args, attr);
2 changes: 1 addition & 1 deletion packages/geom/src/quadratic.ts
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ import { Quadratic } from "./api/quadratic.js";
import { __pclike } from "./internal/pclike.js";

export function quadratic(a: Vec, b: Vec, c: Vec, attribs?: Attribs): Quadratic;
export function quadratic(pts: Vec[], attribs?: Attribs): Quadratic;
export function quadratic(pts: Iterable<Vec>, attribs?: Attribs): Quadratic;
export function quadratic(...args: any[]) {
return __pclike(Quadratic, args);
}
2 changes: 1 addition & 1 deletion packages/geom/src/triangle.ts
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ import { Triangle } from "./api/triangle.js";
import { __pclike } from "./internal/pclike.js";

export function triangle(a: Vec, b: Vec, c: Vec, attribs?: Attribs): Triangle;
export function triangle(pts: Vec[], attribs?: Attribs): Triangle;
export function triangle(pts: Iterable<Vec>, attribs?: Attribs): Triangle;
export function triangle(...args: any[]) {
return __pclike(Triangle, args);
}

0 comments on commit ae0cf5b

Please sign in to comment.