Math & Geometry
Ripl ships with a focused set of math and geometry utilities used throughout the rendering engine. These cover angle conversion, point operations, bounding boxes, polygon generation, SVG path sampling, and common numeric helpers like clamp, min/max, and extent calculation.
NOTE
For the full API, see the Math & Geometry API Reference.
Demo
The demo below visualizes several geometry utilities: polygon vertex generation, midpoints, waypoints, and bounding boxes.
Points
A Point is a simple [x, y] tuple used throughout Ripl:
import type {
Point,
} from '@ripl/web';
const p: Point = [100, 200];Midpoint and Waypoint
import {
getMidpoint,
getWaypoint,
} from '@ripl/web';
const a: Point = [0, 0];
const b: Point = [100, 100];
getMidpoint(a, b); // [50, 50]
getWaypoint(a, b, 0.25); // [25, 25]
getWaypoint(a, b, 0.75); // [75, 75]Equality and Distance
import {
arePointsEqual,
getHypLength,
} from '@ripl/web';
arePointsEqual([0, 0], [0, 0]); // true
getHypLength(3, 4); // 5Angles
import {
degreesToRadians,
radiansToDegrees,
TAU,
} from '@ripl/web';
degreesToRadians(90); // π/2
radiansToDegrees(TAU); // 360
TAU; // 6.283... (2π)Theta Points
Compute a point at a given angle and distance from a center:
import {
getThetaPoint,
} from '@ripl/web';
getThetaPoint(0, 100, 200, 200); // [300, 200]
getThetaPoint(Math.PI / 2, 100, 200, 200); // [200, 300]Polygons
Generate vertex points for a regular polygon:
import {
getPolygonPoints,
} from '@ripl/web';
const hexagon = getPolygonPoints(6, 200, 200, 80);
// 7 points (6 vertices + closing point)
const triangle = getPolygonPoints(3, 100, 100, 50, false);
// 3 points (no closing point)Bounding Boxes
The Box class represents an axis-aligned bounding box:
import {
Box,
getContainingBox,
isPointInBox,
} from '@ripl/web';
const box = new Box(10, 20, 110, 220);
box.width; // 200
box.height; // 100
isPointInBox([50, 50], box); // true
isPointInBox([0, 0], box); // false
Box.empty(); // Box(0, 0, 0, 0)Containing Box
Compute the smallest box that contains a collection of items:
const boxes = [
new Box(0, 0, 50, 50),
new Box(100, 100, 200, 200),
];
const container = getContainingBox(boxes, box => box);
// Box(0, 0, 200, 200)Numeric Helpers
import {
clamp,
fractional,
getExtent,
getTotal,
max,
maxOf,
min,
minOf,
} from '@ripl/web';
clamp(150, 0, 100); // 100
clamp(-5, 0, 100); // 0
fractional(3.7); // 0.7
min(10, 20, 5); // 5
max(10, 20, 5); // 20
const data = [{ v: 10 }, { v: 50 }, { v: 30 }];
minOf(data, d => d.v); // 10
maxOf(data, d => d.v); // 50
getExtent(data, d => d.v); // [10, 50]
getTotal(data, d => d.v); // 90SVG Path Utilities
Measure and sample points along SVG path strings:
import {
getPathLength,
samplePathPoint,
} from '@ripl/web';
const d = 'M 0,0 L 100,0 L 100,100';
getPathLength(d); // ~200
const point = samplePathPoint(d, 50);
// { x: 50, y: 0, angle: 0 }samplePathPoint returns the position and tangent angle at a given distance along the path — this powers the Text on Path feature.
Border Radius
Normalize a border radius value into a four-corner tuple:
import {
normaliseBorderRadius,
} from '@ripl/web';
normaliseBorderRadius(8); // [8, 8, 8, 8]
normaliseBorderRadius([4, 8, 4, 8]); // [4, 8, 4, 8]