Skip to content

Commit

Permalink
feat(geom): add splitNearPoint() for line & polyline, update Sampler
Browse files Browse the repository at this point in the history
  • Loading branch information
postspectacular committed Jan 19, 2019
1 parent 499e14b commit 910529d
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 1 deletion.
4 changes: 4 additions & 0 deletions packages/geom3/src/internal/sampler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ export class Sampler {
return [head, tail];
}

splitNear(p: ReadonlyVec) {
return this.splitAt(this.closestT(p));
}

indexAt(t: number) {
const pts = this.points;
const n = pts.length - 1;
Expand Down
38 changes: 37 additions & 1 deletion packages/geom3/src/ops/split-near.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,37 @@
import { defmulti } from "@thi.ng/defmulti";
import { clamp01 } from "@thi.ng/math";
import { ReadonlyVec } from "@thi.ng/vectors3";
import {
Cubic,
IShape,
Line,
Polyline,
Quadratic,
Type
} from "../api";
import { closestCoeff } from "../internal/closest-point";
import { copyPoints } from "../internal/copy-points";
import { dispatch } from "../internal/dispatch";
import { splitCubicNear, splitQuadraticNear } from "../internal/split";
import { Sampler } from "../internal/sampler";
import { splitCubicNear, splitLine, splitQuadraticNear } from "../internal/split";

/**
* Similar to `splitAt`, but instead of taking a normalized parametric
* split position, splits the given curve at the closest point to `p`.
* Returns tuple of split shapes of same type as `shape`.
*
* Implemented for:
*
* - Cubic
* - Line
* - Polyline
* - Quadratic
*
* @see splitAt
*
* @param shape
* @param p
*/
export const splitNearPoint = defmulti<IShape, ReadonlyVec, IShape[]>(dispatch);

splitNearPoint.addAll({
Expand All @@ -18,6 +41,19 @@ splitNearPoint.addAll({
splitCubicNear(p, points[0], points[1], points[2], points[3])
.map((pts) => new Cubic(pts, { ...attribs })),

[Type.LINE]:
($: Line, p) => {
const t = closestCoeff(p, $.points[0], $.points[1]) || 0;
return splitLine($.points[0], $.points[1], clamp01(t))
.map((pts) => new Line(pts, { ...$.attribs }));
},

[Type.POLYLINE]:
($: Polyline, p) =>
new Sampler($.points)
.splitNear(p)
.map((pts) => new Polyline(copyPoints(pts), { ...$.attribs })),

[Type.QUADRATIC]:
({ points, attribs }: Quadratic, p) =>
splitQuadraticNear(p, points[0], points[1], points[2])
Expand Down

0 comments on commit 910529d

Please sign in to comment.