@thi.ng/geom-isec
Advanced tools
Comparing version 2.1.120 to 3.0.0
# Change Log | ||
- **Last updated**: 2024-03-13T14:04:31Z | ||
- **Last updated**: 2024-03-21T16:11:49Z | ||
- **Generator**: [thi.ng/monopub](https://thi.ng/monopub) | ||
@@ -12,2 +12,24 @@ | ||
# [3.0.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/geom-isec@3.0.0) (2024-03-21) | ||
#### 🛑 Breaking changes | ||
- update pointInCircumCircle() arg order ([0a06976](https://github.com/thi-ng/umbrella/commit/0a06976)) | ||
- BREAKING CHANGE: update pointInCircumCircle() arg order to align with rest of pkg | ||
- swap query point `p` arg from last to first arg | ||
- add docs | ||
#### 🚀 Features | ||
- update intersectRayPolylineAll() & intersectRayCircle() ([cb18d3b](https://github.com/thi-ng/umbrella/commit/cb18d3b)) | ||
- add alpha/beta to result | ||
- update line-line & ray intersection fns ([a45502b](https://github.com/thi-ng/umbrella/commit/a45502b)) | ||
- update `IntersectionResult.isec` to always return arrays (if there're intersections) | ||
- `intersectLineLine()` | ||
- `intersectRayCircle()` | ||
- `intersectRayPlane()` | ||
- update `intersectRayPolyline()` & `intersectRayPolylineAll()` | ||
- add/fix `.inside` result flag | ||
- update `.isec` | ||
### [2.1.86](https://github.com/thi-ng/umbrella/tree/@thi.ng/geom-isec@2.1.86) (2023-11-09) | ||
@@ -14,0 +36,0 @@ |
@@ -23,3 +23,3 @@ import { | ||
type: isec ? IntersectionType.COINCIDENT : IntersectionType.COINCIDENT_NO_INTERSECT, | ||
isec | ||
isec: isec ? [isec] : isec | ||
}; | ||
@@ -34,3 +34,3 @@ } | ||
type: eps < alpha && alpha < ieps && eps < beta && beta < ieps ? IntersectionType.INTERSECT : IntersectionType.INTERSECT_OUTSIDE, | ||
isec: mixN2([], a, b, alpha), | ||
isec: [mixN2([], a, b, alpha)], | ||
alpha, | ||
@@ -37,0 +37,0 @@ beta, |
{ | ||
"name": "@thi.ng/geom-isec", | ||
"version": "2.1.120", | ||
"version": "3.0.0", | ||
"description": "2D/3D shape intersection checks", | ||
@@ -40,6 +40,6 @@ "type": "module", | ||
"@thi.ng/api": "^8.9.30", | ||
"@thi.ng/geom-api": "^3.4.78", | ||
"@thi.ng/geom-closest-point": "^2.1.116", | ||
"@thi.ng/geom-api": "^4.0.0", | ||
"@thi.ng/geom-closest-point": "^2.1.117", | ||
"@thi.ng/math": "^5.10.7", | ||
"@thi.ng/vectors": "^7.10.20" | ||
"@thi.ng/vectors": "^7.10.21" | ||
}, | ||
@@ -124,3 +124,3 @@ "devDependencies": { | ||
}, | ||
"gitHead": "4b3d4ab6ce373ca817ad780f679572169a9ed733\n" | ||
"gitHead": "da965520b2f3f8c259a791e8e8864308be2ba0be\n" | ||
} |
import type { Fn3, FnN7, FnU4, FnU5 } from "@thi.ng/api"; | ||
import type { MultiVecOpImpl, ReadonlyVec } from "@thi.ng/vectors"; | ||
/** | ||
* Returns true if point `p` lies on the line segment `a`, `b`, using `eps` as | ||
* tolerance. | ||
* | ||
* @param p | ||
* @param a | ||
* @param b | ||
* @param eps | ||
*/ | ||
export declare const pointInSegment: (p: ReadonlyVec, a: ReadonlyVec, b: ReadonlyVec, eps?: number) => boolean; | ||
/** | ||
* Returns true if point `p` is inside the circle defined by `pos` and `r`. | ||
* | ||
* @param p | ||
* @param pos | ||
* @param r | ||
*/ | ||
export declare const pointInCircle: (p: ReadonlyVec, pos: ReadonlyVec, r: number) => boolean; | ||
export declare const pointInSphere: (p: ReadonlyVec, pos: ReadonlyVec, r: number) => boolean; | ||
/** | ||
* Returns classifier for `p` regarding the circle defined by `pos` and `r`. | ||
* Returns -1 if point is outside, 0 if on the boundary (using `eps` as | ||
* tolerance) or +1 if inside the circle. | ||
* | ||
* @remarks | ||
* Also see {@link pointInCircle}, {@link pointIn3Circle}. | ||
* | ||
* @param p | ||
* @param pos | ||
* @param r | ||
* @param eps | ||
*/ | ||
export declare const classifyPointInCircle: (p: ReadonlyVec, pos: ReadonlyVec, r: number, eps?: number) => 0 | 1 | -1; | ||
@@ -27,5 +56,5 @@ /** | ||
/** | ||
* Returns positive value if `p` lies inside the sphere passing through a,b,c,d. | ||
* Returns negative value if `p` is outside and zero if all 5 points are | ||
* cospherical. | ||
* Returns positive value if `p` lies inside the sphere passing through `a`, | ||
* `b`, `c`, `d`. Returns a negative value if `p` is outside and zero if all 5 | ||
* points are cospherical. | ||
* | ||
@@ -45,6 +74,54 @@ * @remarks | ||
export declare const pointIn4Sphere: FnU5<ReadonlyVec, number>; | ||
/** | ||
* Returns true if point `p` is in the circumcircle of triangle defined by `a`, | ||
* `b`, `c`. | ||
* | ||
* @param p | ||
* @param a | ||
* @param b | ||
* @param c | ||
*/ | ||
export declare const pointInCircumCircle: FnU4<ReadonlyVec, boolean>; | ||
/** | ||
* Returns true if point `p` is in the triangle defined by `a`, `b`, `c`. | ||
* @param p | ||
* @param a | ||
* @param b | ||
* @param c | ||
*/ | ||
export declare const pointInTriangle2: FnU4<ReadonlyVec, boolean>; | ||
/** | ||
* Returns a classifier for given point `p` with respect to the triangle defined | ||
* by `a`, `b`, `c`. Returns -1 if point is outside the triangle, 0 if on the | ||
* boundary (using `eps` as tolerance) or +1 if the point is inside. | ||
* | ||
* @remarks | ||
* Also see {@link pointInTriangle2} | ||
* | ||
* @param p | ||
* @param a | ||
* @param b | ||
* @param c | ||
* @param eps | ||
*/ | ||
export declare const classifyPointInTriangle2: (p: ReadonlyVec, a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, eps?: number) => 0 | 1 | -1; | ||
/** | ||
* Returns true if point `p` is inside the polygon boundary defined by `pts`. | ||
* | ||
* @param p | ||
* @param pts | ||
*/ | ||
export declare const pointInPolygon2: (p: ReadonlyVec, pts: ReadonlyVec[]) => number; | ||
/** | ||
* Helper function for {@link pointInPolygon2} to check point against a single | ||
* edge of the polygon boundary. | ||
* | ||
* @param px | ||
* @param py | ||
* @param ax | ||
* @param ay | ||
* @param bx | ||
* @param by | ||
* @param inside | ||
*/ | ||
export declare const classifyPointPolyPair: FnN7; | ||
@@ -51,0 +128,0 @@ export declare const pointInBox: MultiVecOpImpl<Fn3<ReadonlyVec, ReadonlyVec, ReadonlyVec, boolean>>; |
@@ -62,3 +62,3 @@ import { closestT } from "@thi.ng/geom-closest-point/line"; | ||
}; | ||
const pointInCircumCircle = (a, b, c, d) => magSq(a) * signedArea2(b, c, d) - magSq(b) * signedArea2(a, c, d) + magSq(c) * signedArea2(a, b, d) - magSq(d) * signedArea2(a, b, c) > 0; | ||
const pointInCircumCircle = (p, a, b, c) => magSq(a) * signedArea2(b, c, p) - magSq(b) * signedArea2(a, c, p) + magSq(c) * signedArea2(a, b, p) - magSq(p) * signedArea2(a, b, c) > 0; | ||
const pointInTriangle2 = (p, a, b, c) => { | ||
@@ -65,0 +65,0 @@ const s = clockwise2(a, b, c) ? 1 : -1; |
@@ -18,4 +18,16 @@ import { | ||
const b = w - d; | ||
const isec = a >= 0 ? b >= 0 ? a > b ? [maddN(delta, dir, b, rpos), maddN([], dir, a, rpos)] : [maddN(delta, dir, a, rpos), maddN([], dir, b, rpos)] : [maddN(delta, dir, a, rpos)] : b >= 0 ? [maddN(delta, dir, b, rpos)] : void 0; | ||
return isec ? { type: IntersectionType.INTERSECT, isec } : NONE; | ||
const isec = a >= 0 ? b >= 0 ? a > b ? ( | ||
// prettier-ignore | ||
[false, b, a, [maddN(delta, dir, b, rpos), maddN([], dir, a, rpos)]] | ||
) : ( | ||
// prettier-ignore | ||
[false, a, b, [maddN(delta, dir, a, rpos), maddN([], dir, b, rpos)]] | ||
) : [true, a, void 0, [maddN(delta, dir, a, rpos)]] : b >= 0 ? [true, b, void 0, [maddN(delta, dir, b, rpos)]] : void 0; | ||
return isec ? { | ||
type: IntersectionType.INTERSECT, | ||
inside: isec[0], | ||
alpha: isec[1], | ||
beta: isec[2], | ||
isec: isec[3] | ||
} : NONE; | ||
}; | ||
@@ -22,0 +34,0 @@ export { |
@@ -0,1 +1,2 @@ | ||
import { IntersectionType } from "@thi.ng/geom-api/isec"; | ||
import type { ReadonlyVec } from "@thi.ng/vectors"; | ||
@@ -12,3 +13,7 @@ /** | ||
*/ | ||
export declare const intersectRayLine: (rpos: ReadonlyVec, dir: ReadonlyVec, a: ReadonlyVec, b: ReadonlyVec, minD?: number, maxD?: number) => import("@thi.ng/geom-api/isec").IntersectionResult; | ||
export declare const intersectRayLine: (rpos: ReadonlyVec, dir: ReadonlyVec, a: ReadonlyVec, b: ReadonlyVec, minD?: number, maxD?: number) => import("@thi.ng/geom-api/isec").IntersectionResult | { | ||
type: IntersectionType; | ||
isec: import("@thi.ng/vectors").Vec; | ||
alpha: number; | ||
}; | ||
//# sourceMappingURL=ray-line.d.ts.map |
@@ -0,3 +1,4 @@ | ||
import { type IntersectionResult } from "@thi.ng/geom-api/isec"; | ||
import type { ReadonlyVec } from "@thi.ng/vectors"; | ||
export declare const intersectRayPlane: (rpos: ReadonlyVec, dir: ReadonlyVec, normal: ReadonlyVec, w: number, eps?: number) => import("@thi.ng/geom-api/isec").IntersectionResult; | ||
export declare const intersectRayPlane: (rpos: ReadonlyVec, dir: ReadonlyVec, normal: ReadonlyVec, w: number, eps?: number) => IntersectionResult; | ||
//# sourceMappingURL=ray-plane.d.ts.map |
@@ -1,2 +0,4 @@ | ||
import { IntersectionType } from "@thi.ng/geom-api/isec"; | ||
import { | ||
IntersectionType | ||
} from "@thi.ng/geom-api/isec"; | ||
import { sign } from "@thi.ng/math/abs"; | ||
@@ -18,3 +20,3 @@ import { EPS } from "@thi.ng/math/api"; | ||
type: IntersectionType.INTERSECT, | ||
isec: maddN(isec, dir, alpha, rpos), | ||
isec: [maddN(isec, dir, alpha, rpos)], | ||
alpha | ||
@@ -25,3 +27,3 @@ }; | ||
type: IntersectionType.COINCIDENT, | ||
isec: copy(rpos) | ||
isec: [copy(rpos)] | ||
} : NONE; | ||
@@ -28,0 +30,0 @@ }; |
@@ -6,2 +6,3 @@ import { | ||
import { NONE } from "./api.js"; | ||
import { classifyPointPolyPair } from "./point.js"; | ||
import { intersectRayLine } from "./ray-line.js"; | ||
@@ -11,7 +12,20 @@ const startPoints = (pts, closed) => closed ? [pts[pts.length - 1], pts[0]] : [pts[0], pts[1]]; | ||
const n = pts.length - 1; | ||
const [x, y] = rpos; | ||
let alpha = maxD; | ||
let cross = 0; | ||
let [i, j] = startPoints(pts, closed); | ||
for (let k = 0; k <= n; i = j, j = pts[++k]) { | ||
const d = intersectRayLine(rpos, dir, i, j, minD, maxD).alpha; | ||
let inside = 0; | ||
let [a, b] = startPoints(pts, closed); | ||
for (let i = 0; i <= n; a = b, b = pts[++i]) { | ||
if (closed) { | ||
inside = classifyPointPolyPair( | ||
x, | ||
y, | ||
a[0], | ||
a[1], | ||
b[0], | ||
b[1], | ||
inside | ||
); | ||
} | ||
const d = intersectRayLine(rpos, dir, a, b, minD, maxD).alpha; | ||
if (d !== void 0) { | ||
@@ -25,4 +39,4 @@ cross++; | ||
type: IntersectionType.INTERSECT, | ||
isec: maddN2([], dir, alpha, rpos), | ||
inside: !(cross & 1), | ||
isec: [maddN2([], dir, alpha, rpos)], | ||
inside: !!inside, | ||
alpha | ||
@@ -33,6 +47,19 @@ } : NONE; | ||
const n = pts.length - 1; | ||
let [i, j] = startPoints(pts, closed); | ||
const res = []; | ||
for (let k = 0; k <= n; i = j, j = pts[++k]) { | ||
const d = intersectRayLine(rpos, dir, i, j, minD, maxD).alpha; | ||
const [x, y] = rpos; | ||
let [a, b] = startPoints(pts, closed); | ||
let inside = 0; | ||
for (let i = 0; i <= n; a = b, b = pts[++i]) { | ||
if (closed) { | ||
inside = classifyPointPolyPair( | ||
x, | ||
y, | ||
a[0], | ||
a[1], | ||
b[0], | ||
b[1], | ||
inside | ||
); | ||
} | ||
const d = intersectRayLine(rpos, dir, a, b, minD, maxD).alpha; | ||
if (d !== void 0) { | ||
@@ -42,6 +69,13 @@ res.push([d, maddN2([], dir, d, rpos)]); | ||
} | ||
return res.length ? { | ||
type: IntersectionType.INTERSECT, | ||
isec: res.sort((a, b) => a[0] - b[0]).map((x) => x[1]) | ||
} : NONE; | ||
if (res.length) { | ||
res.sort((a2, b2) => a2[0] - b2[0]); | ||
return { | ||
type: IntersectionType.INTERSECT, | ||
isec: res.map((x2) => x2[1]), | ||
alpha: res[0][0], | ||
beta: res[res.length - 1][0], | ||
inside: !!inside | ||
}; | ||
} | ||
return NONE; | ||
}; | ||
@@ -48,0 +82,0 @@ export { |
@@ -78,3 +78,3 @@ <!-- This file is generated - DO NOT EDIT! --> | ||
Package sizes (brotli'd, pre-treeshake): ESM: 2.83 KB | ||
Package sizes (brotli'd, pre-treeshake): ESM: 2.92 KB | ||
@@ -81,0 +81,0 @@ ## Dependencies |
55498
883
+ Added@thi.ng/geom-api@4.0.10(transitive)
- Removed@thi.ng/geom-api@3.4.78(transitive)
Updated@thi.ng/geom-api@^4.0.0
Updated@thi.ng/vectors@^7.10.21