@id-sdk/geom

Geometric (planar) math functions

Usage no npm install needed!

<script type="module">
  import idSdkGeom from 'https://cdn.skypack.dev/@id-sdk/geom';
</script>

README

npm version

@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
Types
  • Vec2: [number, number]
  • SSR: { poly: Vec2, angle: number }

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:

//  +-- 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 }