Skip to content

Commit

Permalink
feat(geom-closest-point): add more fns, update pkg
Browse files Browse the repository at this point in the history
  • Loading branch information
postspectacular committed Jan 23, 2019
1 parent 2054574 commit 798de06
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 3 deletions.
4 changes: 3 additions & 1 deletion packages/geom-closest-point/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@thi.ng/geom-closest-point",
"version": "0.0.1",
"description": "Closest point to line helpers",
"description": "Closest point helpers",
"module": "./index.js",
"main": "./lib/index.js",
"umd:main": "./lib/index.umd.js",
Expand Down Expand Up @@ -40,6 +40,8 @@
"geometry",
"line",
"point",
"polygon",
"polyline",
"proximity",
"typescript"
],
Expand Down
72 changes: 70 additions & 2 deletions packages/geom-closest-point/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import {
dist,
distSq,
dot,
empty,
magSq,
mixN,
ReadonlyVec,
set,
sub,
Vec,
dist
Vec
} from "@thi.ng/vectors";

/**
Expand Down Expand Up @@ -84,3 +85,70 @@ export const closestPointSegment =
export const distToSegment =
(p: ReadonlyVec, a: ReadonlyVec, b: ReadonlyVec) =>
dist(p, closestPointSegment(p, a, b) || a);

export const closestPointPolyline =
(p: ReadonlyVec, pts: ReadonlyArray<Vec>, closed = false, out: Vec = []) => {
const tmp = [];
const n = pts.length - 1;
let minD = Infinity, i, j;
if (closed) {
i = n;
j = 0;
} else {
i = 0;
j = 1;
}
for (; j <= n; i = j, j++) {
if (closestPointSegment(p, pts[i], pts[j], tmp)) {
const d = distSq(p, tmp);
if (d < minD) {
minD = d;
set(out, tmp);
}
}
}
return out;
};

/**
* Returns the index of the start point containing the segment in the
* polyline array `points` farthest away from `p` with regards to the
* line segment `a` to `b`. `points` is only checked between indices
* `from` and `to` (not including the latter).
*
* @param a
* @param b
* @param points
* @param from
* @param to
*/
export const farthestPointSegment =
(a: ReadonlyVec, b: ReadonlyVec, points: ReadonlyVec[], from = 0, to = points.length) => {
let maxD = -1;
let maxIdx;
const tmp = empty(a);
for (let i = from; i < to; i++) {
const p = points[i];
const d = distSq(p, closestPointSegment(p, a, b, tmp) || a);
if (d > maxD) {
maxD = d;
maxIdx = i;
}
}
return [maxIdx, Math.sqrt(maxD)];
};

export const closestPointArray =
(p: ReadonlyVec, pts: Vec[]) => {

let minD = Infinity;
let closest: Vec;
for (let i = pts.length; --i >= 0;) {
const d = distSq(pts[i], p);
if (d < minD) {
minD = d;
closest = pts[i];
}
}
return closest;
};

0 comments on commit 798de06

Please sign in to comment.