Skip to content

Commit

Permalink
feat(geom): add new shape factories & impls
Browse files Browse the repository at this point in the history
- add AABB, Plane, Sphere factories
- add closestPoint() impls
  • Loading branch information
postspectacular committed Apr 14, 2019
1 parent 90e8b50 commit 1a5ead1
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 20 deletions.
47 changes: 36 additions & 11 deletions packages/geom/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,15 @@ import {
PCLike,
Type
} from "@thi.ng/geom-api";
import { pointAt as arcPointAt, pointAtTheta as arcPointAtTheta } from "@thi.ng/geom-arc";
import {
pointAt as arcPointAt,
pointAtTheta as arcPointAtTheta
} from "@thi.ng/geom-arc";
import { add2, add3, copyVectors, maddN2, set, Vec } from "@thi.ng/vectors";
add2,
add3,
copyVectors,
maddN2,
set,
Vec
} from "@thi.ng/vectors";

export abstract class APC implements PCLike {
points: Vec[];
Expand All @@ -41,11 +45,12 @@ export class AABB implements AABBLike {

constructor(
pos: Vec = [0, 0, 0],
size: Vec = [1, 1, 1],
size: number | Vec = 1,
attribs?: Attribs
) {
this.pos = pos;
this.size = size;
this.size = isNumber(size) ? [size, size, size] : size;
this.attribs = attribs;
this.attribs = attribs;
}

Expand Down Expand Up @@ -345,6 +350,30 @@ export class Path implements IHiccupShape {
}
}

export class Plane implements IHiccupShape {
normal: Vec;
w: number;
attribs: Attribs;

constructor(normal: Vec = [0, 1, 0], w = 0, attribs?: Attribs) {
this.normal = normal;
this.w = w;
this.attribs = attribs;
}

get type() {
return Type.PLANE;
}

copy() {
return new Plane(set([], this.normal), this.w, { ...this.attribs });
}

toHiccup() {
return ["plane", this.attribs, this.normal, this.w];
}
}

export class Points extends APC implements IHiccupShape {
get type() {
return Type.POINTS;
Expand Down Expand Up @@ -468,11 +497,7 @@ export class Rect implements AABBLike, IHiccupShape {
size: Vec;
attribs: Attribs;

constructor(
pos: Vec = [0, 0],
size: number | Vec = [1, 1],
attribs?: Attribs
) {
constructor(pos: Vec = [0, 0], size: number | Vec = 1, attribs?: Attribs) {
this.pos = pos;
this.size = isNumber(size) ? [size, size] : size;
this.attribs = attribs;
Expand Down
41 changes: 41 additions & 0 deletions packages/geom/src/ctors/aabb.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Attribs } from "@thi.ng/geom-api";
import { SQRT2_2 } from "@thi.ng/math";
import {
ReadonlyVec,
sub3,
subN3,
Vec
} from "@thi.ng/vectors";
import { AABB, Sphere } from "../api";
import { argsVV } from "../internal/args";

export function aabb(pos: Vec, size: number | Vec, attribs?: Attribs): AABB;
export function aabb(size: number | Vec, attribs?: Attribs): AABB;
export function aabb(attribs?: Attribs): AABB;
export function aabb(...args: any[]) {
return new AABB(...argsVV(args));
}

export const aabbFromMinMax = (min: Vec, max: Vec, attribs?: Attribs) =>
new AABB(min, sub3([], max, min), attribs);

/**
* Returns square inscribed in given circle instance. The circle can also be
* given as centroid & radius.
*
* @param circle
*/
export function inscribedAABB(sphere: Sphere): AABB;
export function inscribedAABB(pos: ReadonlyVec, r: number): AABB;
export function inscribedAABB(...args: any[]) {
let pos: ReadonlyVec, r: number;
if (args.length === 1) {
const c: Sphere = args[0];
pos = c.pos;
r = c.r;
} else {
[pos, r] = args;
}
r *= SQRT2_2;
return aabb(subN3([], pos, r), r * 2);
}
20 changes: 20 additions & 0 deletions packages/geom/src/ctors/plane.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Attribs } from "@thi.ng/geom-api";
import {
dot3,
normalize,
ReadonlyVec,
Vec
} from "@thi.ng/vectors";
import { Plane } from "../api";

export const plane = (normal: Vec, w: number, attribs?: Attribs) =>
new Plane(normalize(null, normal), w, attribs);

export const planeWithPoint = (
normal: Vec,
p: ReadonlyVec,
attribs?: Attribs
) => {
normal = normalize(null, normal);
return new Plane(normal, -dot3(normal, p), attribs);
};
23 changes: 23 additions & 0 deletions packages/geom/src/ctors/sphere.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Attribs } from "@thi.ng/geom-api";
import {
dist,
mixN3,
ReadonlyVec,
Vec
} from "@thi.ng/vectors";
import { Sphere } from "../api";
import { argsVN } from "../internal/args";

export function sphere(pos: Vec, r: number, attribs?: Attribs): Sphere;
export function sphere(pos: Vec, attribs?: Attribs): Sphere;
export function sphere(r: number, attribs?: Attribs): Sphere;
export function sphere(attribs?: Attribs): Sphere;
export function sphere(...args: any[]) {
return new Sphere(...argsVN(args));
}

export const sphereFrom2Points = (
a: ReadonlyVec,
b: ReadonlyVec,
attribs?: Attribs
) => new Sphere(mixN3([], a, b, 0.5), dist(a, b) / 2, attribs);
2 changes: 2 additions & 0 deletions packages/geom/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
export * from "./api";

export * from "./ctors/aabb";
export * from "./ctors/arc";
export * from "./ctors/circle";
export * from "./ctors/cubic";
export * from "./ctors/ellipse";
export * from "./ctors/group";
export * from "./ctors/line";
export * from "./ctors/path";
export * from "./ctors/plane";
export * from "./ctors/points";
export * from "./ctors/polygon";
export * from "./ctors/polyline";
Expand Down
31 changes: 25 additions & 6 deletions packages/geom/src/ops/closest-point.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,45 @@ import { defmulti, MultiFn2O } from "@thi.ng/defmulti";
import { IShape, PCLike, Type } from "@thi.ng/geom-api";
import { closestPoint as closestPointArc } from "@thi.ng/geom-arc";
import {
closestPointAABB,
closestPointArray,
closestPointCircle,
closestPointPolyline,
closestPointRect,
closestPointSegment
} from "@thi.ng/geom-closest-point";
import { closestPointCubic, closestPointQuadratic } from "@thi.ng/geom-splines";
import { add, normalize, ReadonlyVec, set, sub, Vec } from "@thi.ng/vectors";
import {
add2,
add3,
ReadonlyVec,
set,
Vec
} from "@thi.ng/vectors";
import {
AABB,
Arc,
Circle,
Cubic,
Line,
Quadratic,
Rect
} from "../api";
import { dispatch } from "../internal/dispatch";
import { vertices } from "./vertices";
import { Arc, Circle, Cubic, Line, Quadratic } from "../api";

export const closestPoint: MultiFn2O<IShape, ReadonlyVec, Vec, Vec> = defmulti(
dispatch
);

closestPoint.addAll({
[Type.AABB]: ($: AABB, p, out = []) =>
closestPointAABB(p, $.pos, add3([], $.pos, $.size), out),

[Type.ARC]: ($: Arc, p, out = []) =>
closestPointArc(p, $.pos, $.r, $.axis, $.start, $.end, out),

[Type.CIRCLE]: ($: Circle, p, out = []) =>
add(null, normalize(null, sub(out, p, $.pos), $.r), $.pos),
closestPointCircle(p, $.pos, $.r, out),

[Type.CUBIC]: ({ points }: Cubic, p, out = []) =>
closestPointCubic(p, points[0], points[1], points[2], points[3], out),
Expand All @@ -41,8 +60,8 @@ closestPoint.addAll({
[Type.QUADRATIC]: ({ points }: Quadratic, p, out = []) =>
closestPointQuadratic(p, points[0], points[1], points[2], out),

[Type.RECT]: ($, p, out = []) =>
closestPointPolyline(p, vertices($), true, out)
[Type.RECT]: ($: Rect, p, out = []) =>
closestPointRect(p, $.pos, add2([], $.pos, $.size), out)
});

closestPoint.isa(Type.QUAD, Type.POLYGON);
Expand Down
11 changes: 8 additions & 3 deletions packages/geom/src/ops/unmap-point.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { defmulti, MultiFn2O } from "@thi.ng/defmulti";
import { IShape, Type } from "@thi.ng/geom-api";
import { madd, mixBilinear, ReadonlyVec, Vec } from "@thi.ng/vectors";
import {
madd,
mixBilinear,
ReadonlyVec,
Vec
} from "@thi.ng/vectors";
import { Quad, Rect } from "../api";
import { dispatch } from "../internal/dispatch";

Expand Down Expand Up @@ -36,8 +41,8 @@ unmapPoint.addAll({
uv[1]
),

[Type.RECT]: ($: Rect, uv: ReadonlyVec, out = []) =>
madd(out, $.pos, $.size, uv)
[Type.RECT]: ($: Rect, uvw: ReadonlyVec, out = []) =>
madd(out, $.pos, $.size, uvw)
});

unmapPoint.isa(Type.AABB, Type.RECT);
Expand Down

0 comments on commit 1a5ead1

Please sign in to comment.