UNPKG

ixfx

Version:

Bundle of ixfx libraries

1,592 lines (1,591 loc) 219 kB
import { H as Result } from "./index-DldIQ_ah.js"; import { C as ISetMutable, c as TraversableTree } from "./index-CvH8hp8B.js"; import { z as RandomSource } from "./index-BtKPbZx1.js"; import { _ as TrackedValueOpts, h as TimestampedObject, n as TrackedValueMap, r as ObjectTracker, v as TrimReason } from "./index-CS8xRat2.js"; //#region ../packages/geometry/src/point/point-type.d.ts /** * A point, consisting of x, y and maybe z fields. */ type Point = { readonly x: number; readonly y: number; readonly z?: number; }; type Point3d = Point & { readonly z: number; }; /** * Placeholder point: `{ x: NaN, y: NaN }` * Use `isPlaceholder` to check if a point is a placeholder. * Use `Placeholder3d` get a point with `z` property. */ declare const Placeholder$3: Point; /** * Placeholder point: `{x: NaN, y:NaN, z:NaN }` * Use `isPlaceholder` to check if a point is a placeholder. * Use `Placeholder` to get a point without `z` property. */ declare const Placeholder3d: Point3d; //#endregion //#region ../packages/geometry/src/point/abs.d.ts declare function abs(pt: Point3d): Point3d; declare function abs(pt: Point): Point; //#endregion //#region ../packages/geometry/src/point/angle.d.ts /** * Returns the angle in radians between `a` and `b`. * * Eg if `a` is the origin, and `b` is another point, * in degrees one would get 0 to -180 when `b` was above `a`. * -180 would be `b` in line with `a`. * Same for under `a`. * * Providing a third point `c` gives the interior angle, where `b` is the middle point. * * See also {@link angleRadianCircle} which returns coordinates on 0..Math.Pi*2 * range. This avoids negative numbers. * * @example Calculate angle between a middle of canvas and the cursor * ```js * const canvasEl = document.querySelector('canvas'); * const middle = { x: canvasEl.width/2, y: canvasEl.height /2 } * * canvasEl.addEventListener(`pointermove`, event => { * const cursor = { * x: event.offsetX, * y: event.offsetY * } * const a = G.Points.angleRadian(middle, cursor); *}); * ``` * @param a * @param b * @param c * @returns */ declare const angleRadian$1: (a: Point, b?: Point, c?: Point) => number; /** * Returns the angle between point(s) using a radian circle system. * ``` * 90deg * Pi/2 * | * Pi ---+--- 0 * 180 | * 3PI/2 * 270deg * ``` * @param a * @param b * @param c * @returns */ declare const angleRadianCircle: (a: Point, b?: Point, c?: Point) => number; /** * Return the angle of a wedge, defined by a, b and C points, where 'b' * could be thought of as the origin or pivot. * * @param a * @param b * @param c * @returns */ declare const angleRadianThreePoint: (a: Point, b: Point, c: Point) => number; //#endregion //#region ../packages/geometry/src/point/apply.d.ts type PointApplyFn = (v: number, field: `x` | `y`) => number; type Point3dApplyFn = (v: number, field: `x` | `y` | `z`) => number; declare function apply$2(pt: Point3d, fn: Point3dApplyFn): Point3d; declare function apply$2(pt: Point, fn: PointApplyFn): Point; //#endregion //#region ../packages/geometry/src/point/averager.d.ts type PointAverager = (point: Point) => Point; type PointAveragerKinds = `moving-average-light`; type PointAverageKinds = `mean`; /** * Averages a set of points, by default as a 'mean'. * * List of points has to all have Z property or none of them -- it's not * possible to mix 2D and 3D points. * @param points * @returns */ declare const average$1: (points: Iterable<Point>, kind?: PointAverageKinds) => Point; /** * Keeps track of average x, y and z values. * * When calling, you have to specify the averaging technique. At the moment * only 'moving-average-light' is supported. This uses @ixfx/numbers.movingAverageLight * under-the-hood. * * ```js * // Create averager * const averager = Points.averager(`moving-average-light`); * * // Call function with a point to add it to average * // and return the current average. * averager(somePoint); // Yields current average {x,y,z?} * ``` * * @param kind Averaging strategy * @param opts Scaling parameter. Higher means more smoothing, lower means less (minimum: 1). Default: 3 * @returns */ declare function averager(kind: `moving-average-light`, opts: Partial<{ scaling: number; }>): PointAverager; //#endregion //#region ../packages/geometry/src/rect/rect-types.d.ts /** * Rectangle as array: `[width, height]` */ type RectArray = readonly [width: number, height: number]; /** * Positioned rectangle as array: `[x, y, width, height]` */ type RectPositionedArray = readonly [x: number, y: number, width: number, height: number]; type Rect = { readonly width: number; readonly height: number; }; type Rect3d = Rect & { readonly depth: number; }; type RectPositioned = Point & Rect; type Rect3dPositioned = Point3d & Rect3d; //#endregion //#region ../packages/geometry/src/point/bbox.d.ts /** * Returns the minimum rectangle that can enclose all provided points * @param points * @returns */ declare const bbox$5: (...points: ReadonlyArray<Point>) => RectPositioned; declare const bbox3d: (...points: ReadonlyArray<Point3d>) => Rect3dPositioned; //#endregion //#region ../packages/geometry/src/point/centroid.d.ts /** * Calculates the [centroid](https://en.wikipedia.org/wiki/Centroid#Of_a_finite_set_of_points) of a set of points * Undefined values are skipped over. Calculation and return value is 2D. * * ```js * // Find centroid of a list of points * const c1 = centroid(p1, p2, p3, ...); * * // Find centroid of an array of points * const c2 = centroid(...pointsArray); * ``` * @param points * @returns A single point */ declare const centroid$1: (...points: readonly (Point | undefined)[]) => Point; //#endregion //#region ../packages/geometry/src/point/clamp.d.ts declare function clamp(a: Point, min?: number, max?: number): Point; declare function clamp(a: Point3d, min?: number, max?: number): Point3d; //#endregion //#region ../packages/geometry/src/point/compare.d.ts /** * Returns -2 if both x & y of a is less than b * Returns -1 if either x/y of a is less than b * * Returns 2 if both x & y of a is greater than b * Returns 1 if either x/y of a is greater than b's x/y * * Returns 0 if x/y of a and b are equal * @param a * @param b */ declare function compare(a: Point, b: Point): number; /** * Compares points row-wise. * * A point is considered less if has a lower `y` value, or if `y` values are equal, a lower `x` value. * * Returns 0 if points are equal, -1 if a is less than b, 1 if a is greater than b. * * This can be used for sorting points in a row-wise manner, for example: * ```js * arrayOfPoints.sort(Points.compareRowwise); * ``` * @param a * @param b */ declare function compareRowwise(a: Point, b: Point): number; /** * Returns a rectangle from two points, where it's uncertain if * a/b ought to be top-left or bottom-right. * * To resolve this, we use Points.compareRowwise to determine which point is top-left and which is bottom-right. * @param a * @param b */ declare function getAsBounds(a: Point, b: Point): { topLeft: Point; bottomRight: Point; }; /** * Compares points based on x value. Y value is ignored. * * Return values: * 0: If a.x === b.x * 1: a is to the right of b (ie. a.x > b.x) * -1: a is to the left of b (ie. a.x < b.x) * * @example Sorting by x * ```js * arrayOfPoints.sort(Points.compareByX); * ``` * * @param a * @param b * @returns */ declare function compareByX(a: Point, b: Point): number; /** * Compares points based on Y value. X value is ignored. * * Return values: * 0: If a.y === b.y * 1: A is below B (ie. a.y > b.y) * -1: A is above B (ie. a.y < b.y) * * @example Sorting by Y * ```js * arrayOfPoints.sort(Points.compareByY); * ``` * @param a * @param b * @returns */ declare function compareByY(a: Point, b: Point): number; /** * Compares points based on Z value. XY values are ignored. * * Return values: * 0: If a.z === b.z * 1: A is below B (ie. a.z > b.z) * -1: A is above B (ie. a.z < b.z) * * @example Sorting by Y * ```js * arrayOfPoints.sort(Points.compareByZ); * ``` * @param a * @param b * @returns */ declare function compareByZ(a: Point3d, b: Point3d): number; //#endregion //#region ../packages/geometry/src/point/convex-hull.d.ts /** * Simple convex hull impementation. Returns a set of points which * enclose `pts`. * * For more power, see something like [Hull.js](https://github.com/AndriiHeonia/hull) * @param pts * @returns */ declare const convexHull: (...pts: ReadonlyArray<Point>) => ReadonlyArray<Point>; //#endregion //#region ../packages/geometry/src/point/distance.d.ts declare function distance$2(a: Point, b?: Point): number; declare function distance$2(a: Point, x: number, y: number): number; /** * As {@link distance} but always compares by x,y only. * @param a * @param xOrB * @param y * @returns */ declare function distance2d(a: Point, xOrB?: Point | number, y?: number): number; //#endregion //#region ../packages/geometry/src/circle/circle-type.d.ts /** * A circle */ type Circle = { readonly radius: number; }; type CircleToSvg = { (circleOrRadius: Circle | number, sweep: boolean, origin: Point): readonly string[]; (circle: CirclePositioned, sweep: boolean): readonly string[]; }; /** * A {@link Circle} with position */ type CirclePositioned = Point & Circle; type CircleRandomPointOpts = { /** * Algorithm to calculate random values. * Default: 'uniform' */ readonly strategy: `naive` | `uniform`; /** * Random number source. * Default: Math.random */ readonly randomSource: () => number; /** * Margin within shape to start generating random points * Default: 0 */ readonly margin: number; }; //#endregion //#region ../packages/geometry/src/line/line-type.d.ts /** * A line, which consists of an `a` and `b` {@link Point}. */ type Line = { readonly a: Point; readonly b: Point; }; /** * A PolyLine, consisting of more than one line. */ type PolyLine = readonly Line[]; //#endregion //#region ../packages/geometry/src/shape/shape-type.d.ts type ShapePositioned = CirclePositioned | RectPositioned; type ContainsResult = `none` | `contained`; type Sphere = Point3d & { readonly radius: number; }; type PointCalculableShape = PolyLine | Line | RectPositioned | Point | CirclePositioned; //#endregion //#region ../packages/geometry/src/shape/arrow.d.ts type ArrowOpts = { readonly arrowSize?: number; readonly tailLength?: number; readonly tailThickness?: number; readonly angleRadian?: number; }; /** * Returns the points forming an arrow. * * @example Create an arrow anchored by its tip at 100,100 * ```js * const opts = { * tailLength: 10, * arrowSize: 20, * tailThickness: 5, * angleRadian: degreeToRadian(45) * } * const arrow = Shapes.arrow({x:100, y:100}, `tip`, opts); // Yields an array of points * * // Eg: draw points * Drawing.connectedPoints(ctx, arrow, {strokeStyle: `red`, loop: true}); * ``` * * @param origin Origin of arrow * @param from Does origin describe the tip, tail or middle? * @param opts Options for arrow * @returns */ declare const arrow: (origin: Point, from: `tip` | `tail` | `middle`, opts?: ArrowOpts) => ReadonlyArray<Point>; //#endregion //#region ../packages/geometry/src/triangle/triangle-type.d.ts type Triangle = { readonly a: Point; readonly b: Point; readonly c: Point; }; type BarycentricCoord = { readonly a: number; readonly b: number; readonly c: number; }; //#endregion //#region ../packages/geometry/src/shape/etc.d.ts type ShapeRandomPointOpts = { readonly randomSource: RandomSource; }; /** * Returns a random point within a shape. * `shape` can be {@link Circles.CirclePositioned} or {@link Rects.RectPositioned} * @param shape * @param opts * @returns */ declare const randomPoint$2: (shape: ShapePositioned, opts?: Partial<ShapeRandomPointOpts>) => Point; /** * Returns the center of a shape * Shape can be: rectangle, triangle, circle * @param shape * @returns */ declare const center$2: (shape?: Rect | Triangle | Circle) => Point; //#endregion //#region ../packages/geometry/src/shape/is-intersecting.d.ts /** * Returns the intersection result between a and b. * `a` can be a {@link Circles.CirclePositioned} or {@link Rects.RectPositioned} * `b` can be as above or a {@link Point}. * @param a * @param b */ declare function isIntersecting$2(a: ShapePositioned, b: ShapePositioned | Point): boolean; //#endregion //#region ../packages/geometry/src/shape/starburst.d.ts /** * Generates a starburst shape, returning an array of points. By default, initial point is top and horizontally-centred. * * ``` * // Generate a starburst with four spikes * const pts = starburst(4, 100, 200); * ``` * * `points` of two produces a lozenge shape. * `points` of three produces a triangle shape. * `points` of five is the familiar 'star' shape. * * Note that the path will need to be closed back to the first point to enclose the shape. * * @example Create starburst and draw it. Note use of 'loop' flag to close the path * ``` * const points = starburst(4, 100, 200); * Drawing.connectedPoints(ctx, pts, {loop: true, fillStyle: `orange`, strokeStyle: `red`}); * ``` * * Options: * * initialAngleRadian: angle offset to begin from. This overrides the `-Math.PI/2` default. * * @param points Number of points in the starburst. Defaults to five, which produces a typical star * @param innerRadius Inner radius. A proportionally smaller inner radius makes for sharper spikes. If unspecified, 50% of the outer radius is used. * @param outerRadius Outer radius. Maximum radius of a spike to origin * @param opts Options * @param origin Origin, or `{ x:0, y:0 }` by default. */ declare const starburst: (outerRadius: number, points?: number, innerRadius?: number, origin?: Point, opts?: { readonly initialAngleRadian?: number; }) => readonly Point[]; declare namespace index_d_exports$13 { export { ArrowOpts, ContainsResult, PointCalculableShape, ShapePositioned, ShapeRandomPointOpts, Sphere, arrow, center$2 as center, isIntersecting$2 as isIntersecting, randomPoint$2 as randomPoint, starburst }; } //#endregion //#region ../packages/geometry/src/point/distance-to-center.d.ts /** * Returns the distance from point `a` to the center of `shape`. * @param a Point * @param shape Point, or a positioned Rect or Circle. * @returns */ declare const distanceToCenter: (a: Point, shape: PointCalculableShape) => number; //#endregion //#region ../packages/geometry/src/point/distance-to-exterior.d.ts /** * Returns the distance from point `a` to the exterior of `shape`. * * @example Distance from point to rectangle * ``` * const distance = distanceToExterior( * {x: 50, y: 50}, * {x: 100, y: 100, width: 20, height: 20} * ); * ``` * * @example Find closest shape to point * ``` * import {minIndex} from '../data/arrays.js'; * const shapes = [ some shapes... ]; // Shapes to compare against * const pt = { x: 10, y: 10 }; // Comparison point * const distances = shapes.map(v => distanceToExterior(pt, v)); * const closest = shapes[minIndex(...distances)]; * ``` * @param a Point * @param shape Point, or a positioned Rect or Circle. * @returns */ declare const distanceToExterior: (a: Point, shape: PointCalculableShape) => number; //#endregion //#region ../packages/geometry/src/point/divider.d.ts declare function divide$4(a: Point, b: Point): Point; declare function divide$4(a: Point3d, b: Point3d): Point3d; declare function divide$4(a: Point, x: number, y: number): Point; declare function divide$4(a: Point3d, x: number, y: number, z: number): Point3d; declare function divide$4(ax: number, ay: number, bx: number, by: number): Point; declare function divide$4(ax: number, ay: number, az: number, bx: number, by: number, bz: number): Point3d; /** * Returns a function that divides a point: * ```js * const f = divider(100, 200); * f(50,100); // Yields: { x: 0.5, y: 0.5 } * ``` * * Input values can be Point, separate x,y and optional z values or an array: * ```js * const f = divider({ x: 100, y: 100 }); * const f = divider( 100, 100 ); * const f = divider([ 100, 100 ]); * ``` * * Likewise the returned function an take these as inputs: * ```js * f({ x: 100, y: 100}); * f( 100, 100 ); * f([ 100, 100 ]); * ``` * * Function throws if divisor has 0 for any coordinate (since we can't divide by 0) * @param a Divisor point, array of points or x * @param b Divisor y value * @param c Divisor z value * @returns */ declare function divider(a: Point3d | Point | number | number[], b?: number, c?: number): (aa: Point3d | Point | number | number[], bb?: number, cc?: number) => Point; //#endregion //#region ../packages/geometry/src/point/dot-product.d.ts declare const dotProduct$2: (...pts: readonly Point[]) => number; /** * Returns the cross-product: * ``` * ax * by - ay * bx * ``` * @param a * @param b * @returns */ declare function cross(a: Point, b: Point): number; /** * Returns the cross-product: * ``` * ax * by - ay * bx * ``` * @param ax * @param ay * @param bx * @param by * @returns */ declare function crossProductRaw(ax: number, ay: number, bx: number, by: number): number; //#endregion //#region ../packages/geometry/src/point/empty.d.ts /** * An empty point of `{ x: 0, y: 0 }`. * * Use `isEmpty` to check if a point is empty. * Use `Empty3d` to get an empty point with `z`. */ declare const Empty$3: Point; /** * Returns { x:1, y:1 } */ declare const Unit: Point; /** * An empty Point of `{ x: 0, y: 0, z: 0}` * Use `isEmpty` to check if a point is empty. * Use `Empty` to get an empty point without `z`. */ declare const Empty3d: Point3d; /** * Returns { x:1,y:1,z:1 } */ declare const Unit3d: Point3d; //#endregion //#region ../packages/geometry/src/point/find-minimum.d.ts declare function findMinimum(comparer: (a: Point, b: Point) => Point, ...points: ReadonlyArray<Point>): Point; declare function findMinimum(comparer: (a: Point3d, b: Point3d) => Point3d, ...points: ReadonlyArray<Point3d>): Point3d; //#endregion //#region ../packages/geometry/src/point/from.d.ts declare function from(x: number, y: number, z: number): Point3d; declare function from(x: number, y: number): Point; declare function from(array: [x: number, y: number, z: number]): Point3d; declare function from(array: [x: number, y: number]): Point; /** * Parses a point as a string, in the form 'x,y' or 'x,y,z'. * eg '10,15' will be returned as `{ x: 10, y: 15 }`. * * Throws an error if `str` is not a string. * * ```js * Points.fromString(`10,15`); // { x:10, y:15 } * Points.fromString(`a,10`); // { x:NaN, y:10 } * ``` * * Use {@link Points.isNaN} to check if returned point has NaN for either coordinate. * @param string_ */ declare const fromString: (string_: string) => Point; /** * Returns an array of points from an array of numbers. * * Array can be a continuous series of x, y values: * ``` * [1,2,3,4] would yield: [{x:1, y:2}, {x:3, y:4}] * ``` * * Or it can be an array of arrays: * ``` * [[1,2], [3,4]] would yield: [{x:1, y:2}, {x:3, y:4}] * ``` * @param coords * @returns */ declare const fromNumbers$2: (...coords: readonly (readonly number[])[] | readonly number[]) => readonly Point[]; //#endregion //#region ../packages/geometry/src/point/get-point-parameter.d.ts declare function getTwoPointParameters(a: Point, b: Point): [a: Point, b: Point]; declare function getTwoPointParameters(a: Point3d, b: Point3d): [a: Point3d, b: Point3d]; declare function getTwoPointParameters(a: Point, x: number, y: number): [a: Point, b: Point]; declare function getTwoPointParameters(a: Point3d, x: number, y: number, z: number): [a: Point3d, b: Point3d]; declare function getTwoPointParameters(ax: number, ay: number, bx: number, by: number): [a: Point, b: Point]; declare function getTwoPointParameters(ax: number, ay: number, az: number, bx: number, by: number, bz: number): [a: Point3d, b: Point3d]; /** * Returns a Point form of either a point, x,y params or x,y,z params. * If parameters are undefined, an empty point is returned (0, 0) * @ignore * @param a * @param b * @returns */ declare function getPointParameter$1(a?: Point3d | Point | number | Array<number> | ReadonlyArray<number>, b?: number | boolean, c?: number): Point | Point3d; //#endregion //#region ../packages/geometry/src/point/guard.d.ts /** * Returns true if xy (and z, if present) are _null_. * @param p * @returns True if all props are null */ declare function isNull(p: Point): boolean; /*** * Returns true if either x, y, z isNaN. */ declare function isNaN$1(p: Point): boolean; declare function pointTest(p: Point, name?: string, extraInfo?: string): Result<Point, string>; /** * Throws an error if point is invalid * @param p * @param name */ declare function guard$5(p: Point, name?: string, info?: string): void; /** * Throws if parameter is not a valid point, or either x or y is 0 * @param pt * @returns Throws an error if not a valid point or zero. */ declare function guardNonZeroPoint(pt: Point | Point3d, name?: string): boolean; /** * Returns _true_ if `p` has x & y properties. * Returns _false_ if `p` is undefined, null or does not contain properties. * Use {@link isPoint3d} to check further check for `z`. * @param p * @returns True if `p` has x & y props */ declare function isPoint(p: number | unknown): p is Point; /** * Returns _true_ if `p` has x, y, & z properties. * Returns _false_ if `p` is undefined, null or does not contain properties. * @param p * @returns _True_ if `p` has x, y, & z props */ declare function isPoint3d(p: Point | unknown): p is Point3d; /** * Returns true if both xy (and z, if present) are 0. * Use `Points.Empty` to return an empty point. * @param p * @returns _True_ is all props are 0 */ declare function isEmpty$3(p: Point): boolean; /** * Returns true if point is a placeholder, where xy (and z, if present) * are `NaN`. * * Use Points.Placeholder to return a placeholder point. * @param p * @returns True if all props are NaN */ declare function isPlaceholder$3(p: Point): boolean; //#endregion //#region ../packages/geometry/src/point/interpolate.d.ts /** * Returns a relative point between two points. * * ```js * interpolate(0.5, { x:0, y:0 }, { x:10, y:10 }); // Halfway { x, y } * ``` * * Alias for Lines.interpolate(amount, a, b); * * If you find yourself calling `interpolate` repeatedly with the same points, consider using {@link interpolator} to create a function that bakes in the points. * @param amount Relative amount, 0-1 * @param a * @param b * @param allowOverflow If true, length of line can be exceeded for `amount` of below 0 and above `1`. * @returns {@link Point} Point */ declare function interpolate$4(amount: number, a: Point, b: Point, allowOverflow?: boolean): Point; /** * Returns a function that interpolates between two points. If you just want to interpolate between two points, use {@link interpolate}. * * ```js * const i = interpolator({ x:0, y:0 }, { x:10, y:10 }); * i(0.5); // Halfway { x, y } * ``` * * If you find yourself not needing to reuse the function because you're always calling `interpolator` with different point values all the time, use {@link interpolate} instead. * @param a * @param b * @param allowOverflow * @returns Function to interpolate */ declare const interpolator$2: (a: Point, b: Point, allowOverflow?: boolean) => (amount: number) => Point; //#endregion //#region ../packages/geometry/src/point/invert.d.ts /** * Inverts one or more axis of a point * ```js * invert({x:10, y:10}); // Yields: {x:-10, y:-10} * invert({x:10, y:10}, `x`); // Yields: {x:-10, y:10} * ``` * @param pt Point to invert * @param what Which axis. If unspecified, both axies are inverted * @returns */ declare const invert$1: (pt: Point | Point3d, what?: `both` | `x` | `y` | `z`) => Point; //#endregion //#region ../packages/geometry/src/point/is-equal.d.ts /** * Returns _true_ if the points have identical values * * ```js * const a = {x: 10, y: 10}; * const b = {x: 10, y: 10;}; * a === b // False, because a and be are different objects * isEqual(a, b) // True, because a and b are same value * ``` * @param p Points * @returns _True_ if points are equal */ declare const isEqual$6: (...p: ReadonlyArray<Point>) => boolean; //#endregion //#region ../packages/geometry/src/point/magnitude.d.ts /** * Clamps the magnitude of a point. * This is useful when using a Point as a vector, to limit forces. * @param pt * @param max Maximum magnitude (1 by default) * @param min Minimum magnitude (0 by default) * @returns */ declare const clampMagnitude$2: (pt: Point, max?: number, min?: number) => Point; //#endregion //#region ../packages/geometry/src/point/most.d.ts /** * Returns the left-most of the provided points. * * Same as: * ```js * findMinimum((a, b) => { * if (a.x <= b.x) return a; * return b; *}, ...points) * ``` * * @param points * @returns */ declare const leftmost: (...points: ReadonlyArray<Point>) => Point; /** * Returns the right-most of the provided points. * * Same as: * ```js * findMinimum((a, b) => { * if (a.x >= b.x) return a; * return b; *}, ...points) * ``` * * @param points * @returns */ declare const rightmost: (...points: ReadonlyArray<Point>) => Point; //#endregion //#region ../packages/geometry/src/point/multiply.d.ts declare function multiply$4(a: Point, b: Point): Point; declare function multiply$4(a: Point3d, b: Point3d): Point3d; declare function multiply$4(a: Point, x: number, y: number): Point; declare function multiply$4(a: Point3d, x: number, y: number, z: number): Point3d; declare function multiply$4(ax: number, ay: number, bx: number, by: number): Point; declare function multiply$4(ax: number, ay: number, az: number, bx: number, by: number, bz: number): Point3d; /** * Multiplies all components by `v`. * Existing properties of `pt` are maintained. * * ```js * multiplyScalar({ x:2, y:4 }, 2); * // Yields: { x:4, y:8 } * ``` * @param pt Point * @param v Value to multiply by * @returns */ declare const multiplyScalar$2: (pt: Point | Point3d, v: number) => Point | Point3d; //#endregion //#region ../packages/geometry/src/point/normalise.d.ts /** * Normalise point as a unit vector. * * ```js * normalise({x:10, y:20}); * normalise(10, 20); * ``` * @param ptOrX Point, or x value * @param y y value if first param is x * @returns */ declare const normalise$2: (ptOrX: Point | number, y?: number) => Point; //#endregion //#region ../packages/geometry/src/point/normalise-by-rect.d.ts /** * Normalises a point by a given width and height * * ```js * normaliseByRect({ x: 10, y: 10 }, 20, 40 }); // { x: 0.5, y: 0.2 } * ``` * @param point Point * @param width Width * @param height Height */ declare function normaliseByRect$1(point: Point, width: number, height: number): Point; /** * Normalises a point by a given rect's width and height * * ```js * normaliseByRect({ x: 10, y: 10, width: 20, height: 40 }); // { x: 0.5, y: 0.2 } * ``` * @param pt * @param rect */ declare function normaliseByRect$1(pt: Point, rect: Rect): Point; /** * Normalises x,y by width and height so it is on a 0..1 scale * * ```js * normaliseByRect(10, 10, 20, 40); // { x: 0.5, y: 0.2 } * ``` * @param x * @param y * @param width * @param height */ declare function normaliseByRect$1(x: number, y: number, width: number, height: number): Point; //#endregion //#region ../packages/geometry/src/point/pipeline.d.ts /** * Runs a sequential series of functions on `pt`. The output from one feeding into the next. * * ```js * const p = Points.pipelineApply(somePoint, Points.normalise, Points.invert); * ``` * * If you want to make a reusable pipeline of functions, consider {@link pipeline} instead. * @param point * @param pipelineFns * @returns */ declare const pipelineApply: (point: Point, ...pipelineFns: readonly ((pt: Point) => Point)[]) => Point; /** * Returns a pipeline function that takes a point to be transformed through a series of functions * ```js * // Create pipeline * const p = Points.pipeline(Points.normalise, Points.invert); * * // Now run it on `somePoint`. * // First we normalised, and then invert * const changedPoint = p(somePoint); * ``` * * If you don't want to create a pipeline, use {@link pipelineApply}. * @param pipeline Pipeline of functions * @returns */ declare const pipeline: (...pipeline: readonly ((pt: Point) => Point)[]) => (pt: Point) => Point; //#endregion //#region ../packages/geometry/src/point/point-relation-types.d.ts type PointRelation = (a: Point | number, b?: number) => PointRelationResult; type PointRelationResult = { /** * Angle from start */ readonly angle: number; /** * Distance from start */ readonly distanceFromStart: number; /** * Distance from last compared point */ readonly distanceFromLast: number; /** * Center point from start */ readonly centroid: Point; /** * Average of all points seen * This is calculated by summing x,y and dividing by total points */ readonly average: Point; /** * Speed. Distance/millisecond from one sample to the next. */ readonly speed: number; }; //#endregion //#region ../packages/geometry/src/polar/types.d.ts /** * Converts to Cartesian coordiantes */ type PolarToCartesian = { (point: Coord, origin?: Point): Point; (distance: number, angleRadians: number, origin?: Point): Point; }; /** * A polar ray allows you to express a line in polar coordinates * rather than two x,y points. * * It consists of an angle (in radians) with a given offset and length. * This way of defining a line makes some manipulations really easy, for example, to * make a set of lines that radiate out from a point in a circular direction, and then animate * them inwards and outwards. * * An alternative is {@link PolarLine} which defines a line as two {@link Coord}s with a common origin. * * Properties * * angleRadian: Angle of line * * offset: distance from the polar origin (default: 0) * * length: length of ray * * origin: Start Cartesian coordinate of line */ type PolarRay = Readonly<{ /** * Angle of ray in radian */ angleRadian: number; /** * Starting point of a ray, defined as an * offset from the polar origin. */ offset?: number; /** * Length of ray */ length: number; /** * Optional origin point of ray (ie. start) */ origin?: Point; }>; type PolarRayWithOrigin = PolarRay & Readonly<{ origin: Point; }>; /** * Expresses a line as two angles and offset from a * common origin. * * Alternatives: * * {@link PolarRay}: Defines a line along a single ray * * {@link Line}: Defines a line by two Cartesian (x,y) pairs */ type PolarLine = Readonly<{ a: Coord; b: Coord; }>; /** * Polar coordinate, made up of a distance and angle in radians. * Most computations involving PolarCoord require an `origin` as well. */ type Coord = Readonly<{ distance: number; angleRadian: number; }>; //#endregion //#region ../packages/geometry/src/polar/angles.d.ts /** * Returns a rotated coordinate * @param c Coordinate * @param amountRadian Amount to rotate, in radians * @returns */ declare const rotate$3: (c: Coord, amountRadian: number) => Coord; /** * Inverts the direction of coordinate. Ie if pointing north, will point south. * @param p * @returns */ declare const invert: (p: Coord) => Coord; /** * Returns true if PolarCoords have same magnitude but opposite direction * @param a * @param b * @returns */ declare const isOpposite: (a: Coord, b: Coord) => boolean; /** * Returns true if Coords have the same direction, regardless of magnitude * @param a * @param b * @returns */ declare const isParallel$1: (a: Coord, b: Coord) => boolean; /** * Returns true if coords are opposite direction, regardless of magnitude * @param a * @param b * @returns */ declare const isAntiParallel: (a: Coord, b: Coord) => boolean; /** * Returns a rotated coordinate * @param c Coordinate * @param amountDeg Amount to rotate, in degrees * @returns */ declare const rotateDegrees: (c: Coord, amountDeg: number) => Coord; //#endregion //#region ../packages/geometry/src/polar/conversions.d.ts /** * Converts a polar coordinate to a Line. * * ```js * const line = toLine({ angleRadian: Math.Pi, distance: 0.5 }, { x: 0.2, y: 0.1 }); * // Yields { a: { x, y}, b: { x, y } } * ``` * * The 'start' parameter is taken to be the origin of the Polar coordinate. * @param c * @param start * @returns */ declare const toLine$1: (c: Coord, start: Point) => Line; /** * Converts to Cartesian coordinate from polar. * * ```js * * const origin = { x: 50, y: 50}; // Polar origin * // Yields: { x, y } * const polar = Polar.toCartesian({ distance: 10, angleRadian: 0 }, origin); * ``` * * Distance and angle can be provided as numbers intead: * * ``` * // Yields: { x, y } * const polar = Polar.toCartesian(10, 0, origin); * ``` * * @param a * @param b * @param c * @returns */ declare const toCartesian$2: PolarToCartesian; type FromCartesianOptions = { /** * Rounding to apply to distance and angle calculations */ digits: number; /** * If false, returns angle on half-circle basis * such that negative angles are possible (0..PI..-PI). * By default uses (0..2*PI) range. */ fullCircle: boolean; }; /** * Converts a Cartesian coordinate to polar * * ```js * * // Yields: { angleRadian, distance } * const polar = Polar.fromCartesian({x: 50, y: 50}, origin); * ``` * * Any additional properties of `point` are copied to object. * * Options: * * fullCircle: If _true_ (default) returns values on 0..2PI range. If _false_, 0....PI..-PI range. * * digits: Rounding to apply * @param point Point * @param origin Origin. If unspecified, {x:0,y:0} is used * @param options Options * @returns */ declare const fromCartesian: (point: Point, origin?: Point, options?: Partial<FromCartesianOptions>) => Coord; /** * Returns a human-friendly string representation `(distance, angleDeg)`. * If `precision` is supplied, this will be the number of significant digits. * @param p * @returns */ declare const toString$5: (p: Coord, digits?: number) => string; declare const toPoint: (v: Coord, origin?: Point) => Point; type ToPolarLineOptions = FromCartesianOptions & { orderBy: `none` | `angle-min` | `angle-max` | `distance`; }; declare function toPolarLine(line: Line, origin: Point, opts?: Partial<ToPolarLineOptions>): PolarLine; declare function toPolarLine(lines: Line[] | readonly Line[], origin: Point, opts?: Partial<ToPolarLineOptions>): PolarLine[]; /** * Returns a string representation of a PolarLine * @param line * @param digits * @returns */ declare function polarLineToString(line: PolarLine, digits?: number): string; declare function lineToCartesian(line: PolarLine, origin: Point): Line; declare function lineToCartesian(lines: PolarLine[], origin: Point): Line[]; //#endregion //#region ../packages/geometry/src/polar/guard.d.ts /** * Returns true if `p` seems to be a {@link Polar.Coord} (ie has both distance & angleRadian fields) * @param p * @returns True if `p` seems to be a PolarCoord */ declare const isPolarCoord: (p: unknown) => p is Coord; /** * Throws an error if Coord is invalid * @param p * @param name */ declare const guard$4: (p: Coord, name?: string) => void; //#endregion //#region ../packages/geometry/src/polar/math.d.ts declare const normalise$1: (c: Coord) => Coord; /** * Clamps the magnitude of a vector * @param v * @param max * @param min * @returns */ declare const clampMagnitude$1: (v: Coord, max?: number, min?: number) => Coord; /** * Calculate dot product of two PolarCoords. * * Eg, power is the dot product of force and velocity * * Dot products are also useful for comparing similarity of * angle between two unit PolarCoords. * @param a * @param b * @returns */ declare const dotProduct$1: (a: Coord, b: Coord) => number; /** * Multiplies the magnitude of a coord by `amt`. * Direction is unchanged. * @param v * @param amt * @returns */ declare const multiply$3: (v: Coord, amt: number) => Coord; /** * Divides the magnitude of a coord by `amt`. * Direction is unchanged. * @param v * @param amt * @returns */ declare const divide$3: (v: Coord, amt: number) => Coord; /** * Returns _true_ if `check` is between `start` and `end` angles. * @param start * @param end * @param check * @returns */ declare const between: (check: { angleRadian: number; }, start: { angleRadian: number; }, end: { angleRadian: number; }) => boolean; declare namespace ray_d_exports { export { fromLine, isParallel, toCartesian$1 as toCartesian, toString$4 as toString }; } declare function toCartesian$1(rays: PolarRay[], origin?: Point): Line[]; declare function toCartesian$1(ray: PolarRay, origin?: Point): Line; declare const isParallel: (a: PolarRay, b: PolarRay) => boolean; /** * Returns a string representation of the ray, useful for debugging. * * ```js * "PolarRay(angle: ... offset: ... len: ... origin: ...)" * ``` * @param ray * @returns */ declare const toString$4: (ray: PolarRay) => string; declare function fromLine(line: Line[] | PolyLine, origin?: Point): PolarRay[]; declare function fromLine(line: Line, origin?: Point): PolarRay; //#endregion //#region ../packages/geometry/src/polar/spiral.d.ts declare function spiral(smoothness: number, zoom: number): IterableIterator<Coord & { readonly step: number; }>; /** * Produces an Archimedian spiral with manual stepping. * @param step Step number. Typically 0, 1, 2 ... * @param smoothness 0.1 pretty rounded, at around 5 it starts breaking down * @param zoom At smoothness 0.1, zoom starting at 1 is OK * @returns */ declare const spiralRaw: (step: number, smoothness: number, zoom: number) => Coord; //#endregion //#region ../packages/geometry/src/polar/intersects.d.ts type IntersectionDistanceCompute = { compute: (angleRadian: number) => Generator<{ distance: number; line: PolarLine; }>; visibilityPolygon: (feather: number) => Coord[]; }; /** * Returns a generator function that checks for intersections with a static set of lines. * The generator yields values of `{ distance: number, line: PolarLine }`. Lines which have no * intersecton are not returned. * * ```js * const c = intersectionDistanceCompute(line1, line2, line3); * * // Get all results for angle 0.2 as an array * const computed = [...c.compute(0.2)] * * // Sort array by distance (ascending) * computed.sort((a, b) => a.distance - b.distance); * ``` * @param lines * @returns */ declare const intersectionDistanceCompute: (...lines: PolarLine[]) => IntersectionDistanceCompute; /** * Returns the distance at which a line from `angleRadian` hits `line`. Returns `Infinity` * if there's no intersection. * * Calculations assume that all angles etc are in relation to a common origin point. * If repeatedly comparing against the same line (or set of lines), use {@link intersectionDistanceCompute} for * improved performance. * * @param angleRadian * @param line * @returns */ declare const intersectionDistance: (angleRadian: number, line: PolarLine) => number; declare namespace index_d_exports$12 { export { Coord, FromCartesianOptions, IntersectionDistanceCompute, PolarLine, PolarRay, PolarRayWithOrigin, PolarToCartesian, ray_d_exports as Ray, ToPolarLineOptions, between, clampMagnitude$1 as clampMagnitude, divide$3 as divide, dotProduct$1 as dotProduct, fromCartesian, guard$4 as guard, intersectionDistance, intersectionDistanceCompute, invert, isAntiParallel, isOpposite, isParallel$1 as isParallel, isPolarCoord, lineToCartesian, multiply$3 as multiply, normalise$1 as normalise, polarLineToString, rotate$3 as rotate, rotateDegrees, spiral, spiralRaw, toCartesian$2 as toCartesian, toLine$1 as toLine, toPoint, toPolarLine, toString$5 as toString }; } //#endregion //#region ../packages/geometry/src/point/point-tracker.d.ts /** * Information about seen points */ type PointTrack = PointRelationResult & {}; /** * Results of point tracking */ type PointTrackerResults = Readonly<{ /** * Relation of last point to previous point */ fromLast: PointTrack; /** * Relation of last point to 'initial' point. * This will be the oldest point in the buffer of the tracker. */ fromInitial: PointTrack; /** * Relation of last point to a 'mark' point, * which is manually set. * * Will give _undefined_ if `.mark()` has not been called on tracker. */ fromMark: PointTrack | undefined; values: readonly Point[]; }>; /** * A tracked point. Mutable. Useful for monitoring how * it changes over time. Eg. when a pointerdown event happens, to record the start position and then * track the pointer as it moves until pointerup. * * See also * * [Playground](https://clinth.github.io/ixfx-play/data/point-tracker/index.html) * * {@link PointsTracker}: Track several points, useful for multi-touch. * * [ixfx Guide to Point Tracker](https://ixfx.fun/geometry/tracking/) * * ```js * // Create a tracker on a pointerdown * const t = new PointTracker(); * * // ...and later, tell it when a point is seen (eg. pointermove) * const nfo = t.seen({x: evt.x, y:evt.y}); * // nfo gives us some details on the relation between the seen point, the start, and points inbetween * // nfo.angle, nfo.centroid, nfo.speed etc. * ``` * * Compute based on last seen point * ```js * t.angleFromStart(); * t.distanceFromStart(); * t.x / t.y * t.length; // Total length of accumulated points * t.elapsed; // Total duration since start * t.lastResult; // The PointSeenInfo for last seen point * ``` * * Housekeeping * ```js * t.reset(); // Reset tracker * ``` * * By default, the tracker only keeps track of the initial point and * does not store intermediate 'seen' points. To use the tracker as a buffer, * set `storeIntermediate` option to _true_. * * ```js * // Keep only the last 10 points * const t = new PointTracker({ * sampleLimit: 10 * }); * * // Store all 'seen' points * const t = new PointTracker({ * storeIntermediate: true * }); * * // In this case, the whole tracker is automatically * // reset after 10 samples * const t = new PointTracker({ * resetAfterSamples: 10 * }) * ``` * * When using a buffer limited by `sampleLimit`, the 'initial' point will be the oldest in the * buffer, not actually the very first point seen. */ declare class PointTracker<TPoint extends Point = Point> extends ObjectTracker<TPoint, PointTrackerResults> { initialRelation: PointRelation | undefined; markRelation: PointRelation | undefined; lastResult: PointTrackerResults | undefined; constructor(opts?: TrackedValueOpts); /** * Notification that buffer has been knocked down to `sampleLimit`. * * This will reset the `initialRelation`, which will use the new oldest value. */ onTrimmed(_reason: TrimReason): void; /** * @ignore */ onReset(): void; /** * Makes a 'mark' in the tracker, allowing you to compare values * to this point. */ mark(): void; /** * Tracks a point, returning data on its relation to the * initial point and the last received point. * * @param _p Point */ computeResults(_p: TimestampedObject<Point>[]): PointTrackerResults; /** * Returns a polyline representation of stored points. * Returns an empty array if points were not saved, or there's only one. */ get line(): PolyLine; /** * Returns a vector of the initial/last points of the tracker. * Returns as a polar coordinate */ get vectorPolar(): Coord; /** * Returns a vector of the initial/last points of the tracker. * Returns as a Cartesian coordinate */ get vectorCartesian(): Point; /** * Returns a line from initial point to last point. * * If there are less than two points, Lines.Empty is returned */ get lineStartEnd(): Line; /** * Returns distance from latest point to initial point. * If there are less than two points, zero is returned. * * This is the direct distance from initial to last, * not the accumulated length. Use {@link lengthTotal} for that. * @param force2d If _true_ distance is calculated only in 2d * @returns Distance */ distanceFromStart(force2d?: boolean): number; /** * Returns the speed (over milliseconds) based on accumulated travel distance. * * If there's no initial point, 0 is returned. * @param force2d If _true_, speed is calculated with x,y only * @returns */ speedFromStart(force2d?: boolean): number; speedFromLast(force2d?: boolean): number; /** * Difference between last point and the initial point, calculated * as a simple subtraction of x,y & z. * * `Points.Placeholder` is returned if there's only one point so far. */ difference(): Point | Point3d; /** * Returns angle (in radians) from latest point to the initial point * If there are less than two points, undefined is return. * @returns Angle in radians */ angleFromStart(): number | undefined; /** * Returns the total distance from accumulated points. * Returns 0 if points were not saved, or there's only one. * * Use {@link lengthAverage} to get the average length for all segments * @param force2d If _true_ length is calculated using x&y only */ lengthTotal(force2d?: boolean): number; /** * Adds up the accumulated length of all points (using {@link lengthTotal}) * dividing by the total number of points. * @param force2d * @returns */ lengthAverage(force2d?: boolean): number; /** * Returns the last x coord */ get x(): number; /** * Returns the last y coord */ get y(): number; /** * Returns the last z coord (or _undefined_ if not available) */ get z(): number | undefined; } /** * A {@link TrackedValueMap} for points. Uses {@link PointTracker} to * track added values. */ declare class PointsTracker<TPoint extends Point = Point> extends TrackedValueMap<TPoint, PointTracker<TPoint>, PointTrackerResults> { constructor(opts?: TrackedValueOpts); get(id: string): PointTracker<TPoint> | undefined; } declare class UserPointerTracker extends PointTracker { /** * Adds a PointerEvent along with its * coalesced events, if available. * @param p * @returns */ seenEvent(p: PointerEvent | MouseEvent): PointTrackerResults; } declare class UserPointersTracker extends TrackedValueMap<Point, PointTracker, PointTrackerResults> { constructor(opts?: TrackedValueOpts); get(id: string): UserPointerTracker | undefined; /** * Track a PointerEvent * @param event */ seenEvent(event: PointerEvent): Promise<PointTrackerResults[]>; } //#endregion //#region ../packages/geometry/src/point/progress-between.d.ts /** * Computes the progress between two waypoints, given `position`. * * [Source](https://www.habrador.com/tutorials/math/2-passed-waypoint/?s=09) * @param position Current position * @param waypointA Start * @param waypointB End * @returns */ declare const progressBetween: (position: Point | Point3d, waypointA: Point | Point3d, waypointB: Point | Point3d) => number; //#endregion //#region ../packages/geometry/src/point/project.d.ts /** * Project `origin` by `distance` and `angle` (radians). * * To figure out rotation, imagine a horizontal line running through `origin`. * * Rotation = 0 deg puts the point on the right of origin, on same y-axis * * Rotation = 90 deg/3:00 puts the point below origin, on the same x-axis * * Rotation = 180 deg/6:00 puts the point on the left of origin on the same y-axis * * Rotation = 270 deg/12:00 puts the point above the origin, on the same x-axis * * ```js * // Yields a point 100 units away from 10,20 with 10 degrees rotation (ie slightly down) * const a = Points.project({x:10, y:20}, 100, degreeToRadian(10)); * ``` * @param origin * @param distance * @param angle * @returns */ declare const project: (origin: Point, distance: number, angle: number) => Point; //#endregion //#region ../packages/geometry/src/point/quantise.d.ts declare function quantiseEvery(pt: Point3d, snap: Point3d, middleRoundsUp?: boolean): Point3d; declare function quantiseEvery(pt: Point, snap: Point, middleRoundsUp?: boolean): Point; //#endregion //#region ../packages/geometry/src/point/random.d.ts /** * Returns a random 2D point on a 0..1 scale. * ```js * import { Points } from "@ixfx/geometry.js"; * const pt = Points.random(); // eg {x: 0.2549012, y:0.859301} * ``` * * A custom source of randomness can be provided: * ```js * import { Points } from "@ixfx/geometry.js"; * import { weightedSource } from "@ixfx/random.js" * const pt = Points.random(weightedSource(`quadIn`)); * ``` * @param rando * @returns */ declare const random$2: (rando?: RandomSource) => Point; /** * Returns a random 3D point on a 0..1 scale. * ```js * import { Points } from "@ixfx/geometry"; * const pt = Points.random(); // eg {x: 0.2549012, y:0.859301} * ``` * * A custom source of randomness can be provided: * ```js * import { Points } from "@ixfx/geometry"; * import { weightedSource } from "@ixfx/random.js" * const pt = Points.random(weightedSource(`quadIn`)); * ``` * @param rando * @returns */ declare const random3d: (rando?: RandomSource) => Point3d; //#endregion //#region ../packages/geometry/src/point/reduce.d.ts /** * Reduces over points, treating _x_ and _y_ separately. * * ``` * // Sum x and y values * const total = Points.reduce(points, (p, acc) => { * return {x: p.x + acc.x, y: p.y + acc.y} * }); * ``` * @param pts Points to reduce * @param fn Reducer * @param initial Initial value, uses `{ x:0, y:0 }` by default * @returns */ declare