Skip to content

Commit

Permalink
feat(geom): add ICollate & ICopy impls, re-add/update convexHull2
Browse files Browse the repository at this point in the history
  • Loading branch information
postspectacular committed Sep 30, 2018
1 parent 2ba9931 commit 3b1bf64
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 7 deletions.
24 changes: 21 additions & 3 deletions packages/geom/src/api.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { ICopy } from "@thi.ng/api/api";
import { IDistance, IMix } from "@thi.ng/vectors/api";
import { IDistance, IMix, Vec } from "@thi.ng/vectors/api";

export type SampleableVector<T> = ICopy<T> & IDistance<T> & IMix<T>;
export type SampleableVector<T> =
ICopy<T> &
IDistance<T> &
IMix<T>;

export interface IArea {
/**
Expand Down Expand Up @@ -47,8 +50,23 @@ export interface ICentroid<T> {
centroid(c?: T): T;
}

export interface ICollate {
/**
* Collates all points into a single buffer and remaps existing
* vertices (by default). Points will written from given `start`
* index, using layout defined by `cstride` and `estride`.
*
* @param remap
* @param buf
* @param start
* @param cstride
* @param estride
*/
collate(remap?: boolean, buf?: Vec, start?: number, cstride?: number, estride?: number): this;
}

export interface IEdges<T> {
edges(): Iterable<T>;
edges(opts?: any): Iterable<T>;
}

export interface IToPolygon2 {
Expand Down
35 changes: 34 additions & 1 deletion packages/geom/src/container2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,20 @@ import { IObjectOf } from "@thi.ng/api/api";
import { illegalArgs } from "@thi.ng/errors/illegal-arguments";
import { Mat23 } from "@thi.ng/vectors/mat23";
import { Vec2, vec2 } from "@thi.ng/vectors/vec2";
import { IBounds, ICentroid, IVertices } from "./api";
import {
IBounds,
ICentroid,
ICollate,
IVertices
} from "./api";
import { bounds } from "./func/bounds";
import { convexHull2 } from "./func/convex-hull";
import { Vec } from "@thi.ng/vectors/api";

export class PointContainer2 implements
IBounds<Vec2[]>,
ICentroid<Vec2>,
ICollate,
IVertices<Vec2> {

points: Vec2[];
Expand All @@ -22,6 +30,23 @@ export class PointContainer2 implements
yield* this.vertices();
}

collate(remap = true, buf: Vec, start = 0, cstride = 1, estride = 2) {
if (!remap) {
this.points = this._copy();
} else {
const pts = this.points;
const n = pts.length;
buf = Vec2.intoBuffer(buf || new Array(start + n * estride).fill(0), pts, start, cstride, estride);
for (let i = 0; i < n; i++) {
const p = pts[i];
p.buf = buf;
p.i = start + i * estride;
p.s = cstride;
}
}
return this;
}

vertices() {
return this.points;
}
Expand All @@ -44,6 +69,10 @@ export class PointContainer2 implements
return 0;
}

convextHull() {
return convexHull2(this.points);
}

centroid(c?: Vec2): Vec2 {
const pts = this.points;
const num = pts.length;
Expand Down Expand Up @@ -87,4 +116,8 @@ export class PointContainer2 implements
}
return this;
}

protected _copy() {
return Vec2.mapBuffer(Vec2.intoBuffer([], this.points), this.points.length);
}
}
30 changes: 29 additions & 1 deletion packages/geom/src/container3.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
import { IObjectOf } from "@thi.ng/api/api";
import { illegalArgs } from "@thi.ng/errors/illegal-arguments";
import { Vec } from "@thi.ng/vectors/api";
import { Mat44 } from "@thi.ng/vectors/mat44";
import { Vec3, vec3 } from "@thi.ng/vectors/vec3";
import { IBounds, ICentroid, IVertices } from "./api";
import {
IBounds,
ICentroid,
ICollate,
IVertices
} from "./api";
import { bounds } from "./func/bounds";

export class PointContainer3 implements
IBounds<Vec3[]>,
ICentroid<Vec3>,
ICollate,
IVertices<Vec3> {

points: Vec3[];
Expand All @@ -22,6 +29,23 @@ export class PointContainer3 implements
yield* this.vertices();
}

collate(remap = true, buf: Vec, start = 0, cstride = 1, estride = 3) {
if (!remap) {
this.points = this._copy();
} else {
const pts = this.points;
const n = pts.length;
buf = Vec3.intoBuffer(buf || new Array(start + n * estride).fill(0), pts, start, cstride, estride);
for (let i = 0; i < n; i++) {
const p = pts[i];
p.buf = buf;
p.i = start + i * estride;
p.s = cstride;
}
}
return this;
}

vertices() {
return this.points;
}
Expand Down Expand Up @@ -88,4 +112,8 @@ export class PointContainer3 implements
}
return this;
}

protected _copy() {
return Vec3.mapBuffer(Vec3.intoBuffer([], this.points), this.points.length);
}
}
35 changes: 35 additions & 0 deletions packages/geom/src/func/convex-hull.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Vec2 } from "@thi.ng/vectors/vec2";
import { corner } from "./corner";

/**
* Returns array of points defining the Convex Hull of `pts` using
* Graham Scan method.
*
* https://en.wikipedia.org/wiki/Graham_scan
*
* @param pts
*/
export const convexHull2 = (pts: ReadonlyArray<Vec2>) => {
const num = pts.length;
const res: Vec2[] = [];
let h = 0, i;
pts = pts.slice().sort(Vec2.comparator(0, 1));
const scan = (p: Vec2, thresh: number) => {
while (h >= thresh && corner(res[h - 2], res[h - 1], p) >= 0) {
res.pop();
h--;
}
res[h++] = p;
};
for (i = 0; i < num; i++) {
scan(pts[i], 2);
}
res.pop();
h--;
const h2 = h + 2;
for (i = num - 1; i >= 0; i--) {
scan(pts[i], h2);
}
res.pop();
return res;
}
11 changes: 11 additions & 0 deletions packages/geom/src/func/corner.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { EPS, sign1 } from "@thi.ng/vectors/math";
import { Vec2 } from "@thi.ng/vectors/vec2";

export const corner = (a: Readonly<Vec2>, b: Readonly<Vec2>, c: Readonly<Vec2>) => {
const ax = a.x,
ay = a.y;
return (b.x - ax) * (c.y - ay) - (c.x - ax) * (b.y - ay);
};

export const classify = (a: Readonly<Vec2>, b: Readonly<Vec2>, c: Readonly<Vec2>, eps = EPS) =>
sign1(corner(a, b, c), eps);
4 changes: 2 additions & 2 deletions packages/geom/src/func/edges.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { wrap } from "@thi.ng/transducers/iter/wrap";
import { partition } from "@thi.ng/transducers/xform/partition";

export const edges = <T>(vertices: T[], closed = false) => {
return partition(2, 1, closed ? wrap(vertices, 1, false, true) : vertices);
export const edges = <T>(vertices: ReadonlyArray<T>, closed = false) => {
return partition<T>(2, 1, closed ? wrap(vertices, 1, false, true) : vertices);
};
4 changes: 4 additions & 0 deletions packages/geom/src/poly2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ export class Polygon2 extends PointContainer2 implements
super(points, attribs);
}

copy() {
return new Polygon2(this._copy(), { ...this.attribs });
}

edges() {
return edges(this.vertices(), true);
}
Expand Down
4 changes: 4 additions & 0 deletions packages/geom/src/polyline2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ export class Polyline2 extends PointContainer2 implements
super(points, attribs);
}

copy() {
return new Polyline2(this._copy(), { ...this.attribs });
}

edges() {
return edges(this.vertices());
}
Expand Down

0 comments on commit 3b1bf64

Please sign in to comment.