README
@id-sdk/geom
📈 Geometric (planar) math functions
Installing
npm install @id-sdk/geom
This library is distributed in ESM format only. It cannot be require()
'd from CommonJS.
For more, please read Sindre Sorhus’s FAQ.
import * as geom from '@id-sdk/geom';
import { geomEdgeEqual } from '@id-sdk/geom';
Contributing
This project is just getting started! 🌱
We're not able to support external contributors at this time, but check back in a bit when things have matured.
API Reference
Functions
- geomEdgeEqual(a: Vec2, b: Vec2): boolean
- geomRotatePoints(points: Vec2[], angle: number, around: Vec2): Vec2[]
- geomLineIntersection(a: Vec2[], b: Vec2[]): Vec2 | null
- geomPathIntersections(path1: Vec2[], path2: Vec2[]): Vec2[]
- geomPathHasIntersections(path1: Vec2[], path2: Vec2[]): boolean
- geomPointInPolygon(point: Vec2, polygon: Vec2[]): boolean
- geomPolygonContainsPolygon(outer: Vec2[], inner: Vec2[]): boolean
- geomPolygonIntersectsPolygon(outer: Vec2[], inner: Vec2[], checkSegments?: boolean): boolean
- geomGetSmallestSurroundingRectangle(points: Vec2[]): SSR
- geomPathLength(path: Vec2[]): number
- geomViewportNudge(point: Vec2, dimensions: Vec2): Vec2 | null
Types
Functions
# geomEdgeEqual(a: Vec2, b: Vec2): boolean <>
Test whether two given coordinates describe the same edge. Returns true
if equal, false
if unequal.
geomEdgeEqual([1, 2], [1, 2]); // returns true
geomEdgeEqual([1, 2], [2, 1]); // returns true
# geomRotatePoints(points: Vec2[], angle: number, around: Vec2): Vec2[] <>
Rotate all points counterclockwise around a pivot point by given angle (in radians), without modifying the input points array. Returns an array containing the rotated points.
const points = [[1, 0], [1, 1]];
const around = [0, 0];
geomRotatePoints(points, Math.Pi, around); // returns [[-1, 0], [-1, -1]]
# geomLineIntersection(a: Vec2[], b: Vec2[]): Vec2 | null <>
Return the intersection point of 2 line segments. From https://github.com/pgkelley4/line-segments-intersect This uses the vector cross product approach described here: http://stackoverflow.com/a/565282/786339
// b0
// |
// a0 ---*--- a1
// |
// b1
//
const a = [[0, 0], [10, 0]];
const b = [[5, 5], [5, -5]];
geomLineIntersection(a, b); // returns [5, 0]
# geomPathIntersections(path1: Vec2[], path2: Vec2[]): Vec2[] <>
Return all intersection points of 2 paths.
// b0
// | \
// a0 ---*--*--- a1
// | \
// b1 -- b2
//
const a = [[0, 0], [10, 0]];
const b = [[5, 5], [5, -5], [10, -5], [5, 5]];
geomPathIntersections(a, b); // returns [[5, 0], [7.5, 0]]
# geomPathHasIntersections(path1: Vec2[], path2: Vec2[]): boolean <>
Returns true
if paths intersect, false
if not.
// b0
// | \
// a0 ---*--*--- a1
// | \
// b1 -- b2
//
const a = [[0, 0], [10, 0]];
const b = [[5, 5], [5, -5], [10, -5], [5, 5]];
geomPathHasIntersections(a, b); // returns true
# geomPointInPolygon(point: Vec2, polygon: Vec2[]): boolean <>
Returns true
if point is contained in polygon, false
if not.
From https://github.com/substack/point-in-polygon .
Ray-casting algorithm based on http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
// p1 --- p2
// | * |
// p0 --- p3
//
const poly = [[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]];
const point = [0.5, 0.5];
geomPointInPolygon(point, poly); // returns true
# geomPolygonContainsPolygon(outer: Vec2[], inner: Vec2[]): boolean <>
Returns true
if every point of inner polygon is contained within outer polygon, false
if not.
// o1 -------- o2
// | i1 -- i2 |
// | | | |
// | i0 -- i3 |
// o0 -------- o3
//
const outer = [[0, 0], [0, 3], [3, 3], [3, 0], [0, 0]];
const inner = [[1, 1], [1, 2], [2, 2], [2, 1], [1, 1]];
geomPolygonContainsPolygon(outer, inner); // returns true
# geomPolygonIntersectsPolygon(outer: Vec2[], inner: Vec2[], checkSegments?: boolean): boolean <>
Returns true
if any part of inner polygon intersects outer polygon, false
if not.
Optionally, pass true to checkSegments
option to test each segment (stricter but slower).
// i1 -- i2
// o1 -+------+-- o2
// | | | |
// | | | |
// o0 -+------+-- o3
// i0 -- i3
//
const outer = [[0, 0], [0, 3], [3, 3], [3, 0], [0, 0]];
const inner = [[1, -1], [1, 4], [2, 4], [2, -1], [1, -1]];
geomPolygonIntersectsPolygon(outer, inner, false); // returns false (lax test - points only)
geomPolygonIntersectsPolygon(outer, inner, true); // returns true (strict test - points and segments)
# geomGetSmallestSurroundingRectangle(points: Vec2[]): SSR | null <>
Return the Smallest Surrounding Rectangle for a given set of points, or null
for a denerate point set.
See:
- http://gis.stackexchange.com/questions/22895/finding-minimum-area-rectangle-for-given-points
- http://gis.stackexchange.com/questions/3739/generalisation-strategies-for-building-outlines/3756#3756
// +-- p1 ------ p3
// | |
// p0 ------ p2 --+
//
const points = [[0, -1], [5, 1], [10, -1], [15, 1]];
const ssr = geomGetSmallestSurroundingRectangle(points);
// ssr.poly == [[0, -1], [0, 1], [15, 1], [15, -1], [0, -1]]
// ssr.angle == 0
# geomPathLength(path: Vec2[]): number <>
Return the length of the given path.
// p2
// /
// p0 -- p1
//
const path = [[0, 0], [1, 0], [5, 3]];
geomPathLength(path); // returns 6
# geomViewportNudge(point: Vec2, dimensions: Vec2): Vec2 | null <>
If the given point is at the edge of the padded viewport, return a vector that will nudge the viewport in that direction
Types
# Vec2
An array of two numbers.
[number, number]
# SSR
Smallest Surrounding Rectangle.
An Object containing poly
and angle
properties. Used as the return value for geomGetSmallestSurroundingRectangle().
{ poly: Vec2, angle: number }