@expofp/geometry 3.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,72 @@
1
+ import { pointLerp } from './point.js';
2
+ import { rectCorners } from './rect.js';
3
+ /** Default tolerance for elevation comparison. */
4
+ const DEFAULT_ELEVATION_TOLERANCE = 1e-3;
5
+ /**
6
+ * Computes the crossing of lines `a` and `b` using the parametric form. Returns the crossing
7
+ * point plus flags indicating whether the crossing lies within each segment's `[0, 1]` parameter
8
+ * range. Returns `null` only when the lines are parallel (denominator is zero) or when both lines
9
+ * have a defined elevation and they differ by more than `elevationTolerance`.
10
+ * @param a - first line segment, defined by `p0` and `p1`
11
+ * @param b - second line segment, defined by `p0` and `p1`
12
+ * @param elevationTolerance - maximum elevation difference for a crossing to be reported; defaults to `1e-3`
13
+ * @returns `{ point, onLine1, onLine2 }`, or `null` when the lines are parallel or elevation-incompatible
14
+ */
15
+ export function lineIntersection(a, b, elevationTolerance = DEFAULT_ELEVATION_TOLERANCE) {
16
+ if (a.elevation != null &&
17
+ b.elevation != null &&
18
+ Math.abs(a.elevation - b.elevation) > elevationTolerance) {
19
+ return null;
20
+ }
21
+ const { x: x1, y: y1 } = a.p0, { x: x2, y: y2 } = a.p1;
22
+ const { x: x3, y: y3 } = b.p0, { x: x4, y: y4 } = b.p1;
23
+ const denom = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
24
+ if (denom === 0)
25
+ return null;
26
+ const t = ((x1 - x3) * (y3 - y4) - (y1 - y3) * (x3 - x4)) / denom;
27
+ const u = ((x1 - x3) * (y1 - y2) - (y1 - y3) * (x1 - x2)) / denom;
28
+ const point = pointLerp(a.p0, a.p1, t);
29
+ point.z = a.elevation ?? b.elevation ?? 0;
30
+ return { point, onLine1: t >= 0 && t <= 1, onLine2: u >= 0 && u <= 1 };
31
+ }
32
+ /**
33
+ * Returns the intersection point of two line segments `a` and `b`, or `null` when the segments
34
+ * do not cross. See `lineIntersection` for the full crossing result (includes out-of-segment
35
+ * flags). See `intersectLineRect` for the higher-level helper.
36
+ * @param a - first segment, defined by `p0` and `p1`
37
+ * @param b - second segment, defined by `p0` and `p1`
38
+ * @param elevationTolerance - maximum elevation difference for a crossing to be reported; defaults to `1e-3`
39
+ * @returns the intersection {@link Point}, or `null` if the segments are parallel or non-crossing
40
+ */
41
+ function segmentIntersection(a, b, elevationTolerance) {
42
+ const r = lineIntersection(a, b, elevationTolerance);
43
+ return r?.onLine1 && r.onLine2 ? r.point : null;
44
+ }
45
+ /**
46
+ * Returns the points where a line segment crosses a rect's edges. Works for any `RectLike`,
47
+ * including a rotated rect or an unrotated `Box` (a `Box` satisfies `RectLike` and is treated
48
+ * as a rect with rotation 0). When both `line` and `rect` have a defined elevation that differs
49
+ * by more than `elevationTolerance`, returns an empty array.
50
+ * @param line - the segment, defined by `p0` and `p1`
51
+ * @param rect - the rect (possibly rotated; a `Box` is accepted as an unrotated rect)
52
+ * @param elevationTolerance - maximum elevation difference for a crossing to be reported; defaults to `1e-3`
53
+ * @returns the intersection points (0–2 for a convex rect)
54
+ */
55
+ export function intersectLineRect(line, rect, elevationTolerance = DEFAULT_ELEVATION_TOLERANCE) {
56
+ if (line.elevation != null &&
57
+ rect.elevation != null &&
58
+ Math.abs(line.elevation - rect.elevation) > elevationTolerance) {
59
+ return [];
60
+ }
61
+ const resultZ = line.elevation ?? rect.elevation ?? 0;
62
+ const corners = rectCorners(rect);
63
+ const hits = [];
64
+ for (let i = 0; i < 4; i++) {
65
+ const hit = segmentIntersection(line, { p0: corners[i], p1: corners[(i + 1) % 4] }, elevationTolerance);
66
+ if (hit) {
67
+ hit.z = resultZ;
68
+ hits.push(hit);
69
+ }
70
+ }
71
+ return hits;
72
+ }
@@ -0,0 +1,134 @@
1
+ import { Point, type Point2Like } from './point.js';
2
+ import type { RectLike } from './rect.js';
3
+ /** Structural line segment with 2D endpoints and an optional planar elevation. */
4
+ export interface LineLike {
5
+ /** Start point (2D). */
6
+ readonly p0: Point2Like;
7
+ /** End point (2D). */
8
+ readonly p1: Point2Like;
9
+ /** Planar elevation (z). When absent the segment is treated as elevation-agnostic (matches any). */
10
+ readonly elevation?: number;
11
+ }
12
+ /** A line segment between two 2D points at a given elevation. */
13
+ export declare class Line {
14
+ /** Marker so callers can narrow the type at runtime. */
15
+ readonly isLine = true;
16
+ /** Internal mutable start point (2D). */
17
+ private _p0;
18
+ /** Internal mutable end point (2D). */
19
+ private _p1;
20
+ /** Internal mutable elevation (z). */
21
+ private _elevation;
22
+ /**
23
+ * @param p0 - start point (2D)
24
+ * @param p1 - end point (2D)
25
+ * @param elevation - planar elevation (z); defaults to 0
26
+ */
27
+ constructor(p0: Point2Like, p1: Point2Like, elevation?: number);
28
+ /**
29
+ * Start point (2D).
30
+ * @returns a readonly `{ x, y }` view of the start point
31
+ */
32
+ get p0(): Readonly<Point2Like>;
33
+ /**
34
+ * End point (2D).
35
+ * @returns a readonly `{ x, y }` view of the end point
36
+ */
37
+ get p1(): Readonly<Point2Like>;
38
+ /**
39
+ * Planar elevation (z coordinate of the segment's plane).
40
+ * @returns the current elevation
41
+ */
42
+ get elevation(): number;
43
+ /**
44
+ * Mutates this segment in place, replacing p0, p1, and optionally elevation. When `elevation`
45
+ * is omitted the current elevation is preserved. Prefer the constructor for one-off segments;
46
+ * use this only for hot-path reuse.
47
+ * @param p0 - new start point (2D); stored as a fresh `{ x, y }` copy
48
+ * @param p1 - new end point (2D); stored as a fresh `{ x, y }` copy
49
+ * @param elevation - new elevation; defaults to the current elevation when omitted
50
+ * @returns `this`
51
+ */
52
+ set(p0: Point2Like, p1: Point2Like, elevation?: number): this;
53
+ /**
54
+ * Length of this segment.
55
+ * @returns the distance between p0 and p1
56
+ */
57
+ length(): number;
58
+ /**
59
+ * Midpoint of this segment.
60
+ * @param target - optional point to write into; defaults to a new {@link Point}
61
+ * @returns the midpoint
62
+ */
63
+ center(target?: Point): Point;
64
+ /**
65
+ * Direction of this segment in radians.
66
+ * @returns the angle in radians
67
+ */
68
+ angle(): number;
69
+ /**
70
+ * Points where this line crosses `rect`.
71
+ * @param rect - the rect (possibly rotated; a `Box` is accepted as an unrotated rect)
72
+ * @param elevationTolerance - maximum elevation difference for a crossing to be reported; defaults to `1e-3`
73
+ * @returns the intersection points
74
+ */
75
+ intersectRect(rect: RectLike, elevationTolerance?: number): Point[];
76
+ /**
77
+ * Nearest point on this segment to `point`, with parameter and distance.
78
+ * @param point - the point to project onto this segment
79
+ * @param target - optional point to write the projected position into; defaults to a new {@link Point}
80
+ * @returns `{ projected, t, distance }`
81
+ */
82
+ projectPoint(point: Point2Like, target?: Point): {
83
+ projected: Point;
84
+ t: number;
85
+ distance: number;
86
+ };
87
+ /**
88
+ * Intersection with another segment `other` on the infinite lines.
89
+ * @param other - the other segment
90
+ * @param elevationTolerance - maximum elevation difference for a crossing to be reported; defaults to `1e-3`
91
+ * @returns the crossing data, or `null` when the lines are parallel or elevations are incompatible
92
+ */
93
+ intersect(other: LineLike, elevationTolerance?: number): {
94
+ point: Point;
95
+ onLine1: boolean;
96
+ onLine2: boolean;
97
+ } | null;
98
+ }
99
+ /**
100
+ * Euclidean length of a line segment.
101
+ * @param line the segment
102
+ * @returns the distance between `line.p0` and `line.p1`
103
+ */
104
+ export declare function lineLength(line: LineLike): number;
105
+ /**
106
+ * Midpoint of a line segment.
107
+ * @param line the segment
108
+ * @param target optional point to write into; defaults to a new {@link Point}
109
+ * @returns the midpoint
110
+ */
111
+ export declare function lineCenter(line: LineLike, target?: Point): Point;
112
+ /**
113
+ * Direction of the segment p0→p1 in radians.
114
+ * @param p0 start point
115
+ * @param p1 end point
116
+ * @returns the angle in radians
117
+ */
118
+ export declare function lineAngle(p0: Point2Like, p1: Point2Like): number;
119
+ /**
120
+ * Projects `point` onto the nearest position on segment `line`, returning the projected point,
121
+ * the normalized parameter `t` (clamped to `[0, 1]`), and the distance from `point` to the
122
+ * projection. For a zero-length segment, `t` is `0`, the projected point equals `line.p0`, and
123
+ * the distance is the distance from `point` to `p0`.
124
+ * @param line - the segment to project onto
125
+ * @param point - the point to project
126
+ * @param target - optional point to write the projected position into; defaults to a new {@link Point}
127
+ * @returns `{ projected, t, distance }` where `t ∈ [0, 1]`
128
+ */
129
+ export declare function lineProjectPoint(line: LineLike, point: Point2Like, target?: Point): {
130
+ projected: Point;
131
+ t: number;
132
+ distance: number;
133
+ };
134
+ //# sourceMappingURL=line.d.ts.map
@@ -0,0 +1,167 @@
1
+ import { intersectLineRect, lineIntersection } from './intersections.js';
2
+ import { Point, pointDistance, pointLerp } from './point.js';
3
+ /** A line segment between two 2D points at a given elevation. */
4
+ export class Line {
5
+ /** Marker so callers can narrow the type at runtime. */
6
+ isLine = true;
7
+ /** Internal mutable start point (2D). */
8
+ _p0;
9
+ /** Internal mutable end point (2D). */
10
+ _p1;
11
+ /** Internal mutable elevation (z). */
12
+ _elevation;
13
+ /**
14
+ * @param p0 - start point (2D)
15
+ * @param p1 - end point (2D)
16
+ * @param elevation - planar elevation (z); defaults to 0
17
+ */
18
+ constructor(p0, p1, elevation = 0) {
19
+ this._p0 = { x: p0.x, y: p0.y };
20
+ this._p1 = { x: p1.x, y: p1.y };
21
+ this._elevation = elevation;
22
+ }
23
+ /**
24
+ * Start point (2D).
25
+ * @returns a readonly `{ x, y }` view of the start point
26
+ */
27
+ get p0() {
28
+ return this._p0;
29
+ }
30
+ /**
31
+ * End point (2D).
32
+ * @returns a readonly `{ x, y }` view of the end point
33
+ */
34
+ get p1() {
35
+ return this._p1;
36
+ }
37
+ /**
38
+ * Planar elevation (z coordinate of the segment's plane).
39
+ * @returns the current elevation
40
+ */
41
+ get elevation() {
42
+ return this._elevation;
43
+ }
44
+ /**
45
+ * Mutates this segment in place, replacing p0, p1, and optionally elevation. When `elevation`
46
+ * is omitted the current elevation is preserved. Prefer the constructor for one-off segments;
47
+ * use this only for hot-path reuse.
48
+ * @param p0 - new start point (2D); stored as a fresh `{ x, y }` copy
49
+ * @param p1 - new end point (2D); stored as a fresh `{ x, y }` copy
50
+ * @param elevation - new elevation; defaults to the current elevation when omitted
51
+ * @returns `this`
52
+ */
53
+ set(p0, p1, elevation = this._elevation) {
54
+ this._p0 = { x: p0.x, y: p0.y };
55
+ this._p1 = { x: p1.x, y: p1.y };
56
+ this._elevation = elevation;
57
+ return this;
58
+ }
59
+ /**
60
+ * Length of this segment.
61
+ * @returns the distance between p0 and p1
62
+ */
63
+ length() {
64
+ return lineLength(this);
65
+ }
66
+ /**
67
+ * Midpoint of this segment.
68
+ * @param target - optional point to write into; defaults to a new {@link Point}
69
+ * @returns the midpoint
70
+ */
71
+ center(target) {
72
+ return lineCenter(this, target);
73
+ }
74
+ /**
75
+ * Direction of this segment in radians.
76
+ * @returns the angle in radians
77
+ */
78
+ angle() {
79
+ return lineAngle(this.p0, this.p1);
80
+ }
81
+ /**
82
+ * Points where this line crosses `rect`.
83
+ * @param rect - the rect (possibly rotated; a `Box` is accepted as an unrotated rect)
84
+ * @param elevationTolerance - maximum elevation difference for a crossing to be reported; defaults to `1e-3`
85
+ * @returns the intersection points
86
+ */
87
+ intersectRect(rect, elevationTolerance) {
88
+ return intersectLineRect(this, rect, elevationTolerance);
89
+ }
90
+ /**
91
+ * Nearest point on this segment to `point`, with parameter and distance.
92
+ * @param point - the point to project onto this segment
93
+ * @param target - optional point to write the projected position into; defaults to a new {@link Point}
94
+ * @returns `{ projected, t, distance }`
95
+ */
96
+ projectPoint(point, target) {
97
+ return lineProjectPoint(this, point, target);
98
+ }
99
+ /**
100
+ * Intersection with another segment `other` on the infinite lines.
101
+ * @param other - the other segment
102
+ * @param elevationTolerance - maximum elevation difference for a crossing to be reported; defaults to `1e-3`
103
+ * @returns the crossing data, or `null` when the lines are parallel or elevations are incompatible
104
+ */
105
+ intersect(other, elevationTolerance) {
106
+ return lineIntersection(this, other, elevationTolerance);
107
+ }
108
+ }
109
+ /**
110
+ * Euclidean length of a line segment.
111
+ * @param line the segment
112
+ * @returns the distance between `line.p0` and `line.p1`
113
+ */
114
+ export function lineLength(line) {
115
+ return pointDistance(line.p0, line.p1);
116
+ }
117
+ /**
118
+ * Midpoint of a line segment.
119
+ * @param line the segment
120
+ * @param target optional point to write into; defaults to a new {@link Point}
121
+ * @returns the midpoint
122
+ */
123
+ export function lineCenter(line, target) {
124
+ return pointLerp(line.p0, line.p1, 0.5, target);
125
+ }
126
+ /**
127
+ * Direction of the segment p0→p1 in radians.
128
+ * @param p0 start point
129
+ * @param p1 end point
130
+ * @returns the angle in radians
131
+ */
132
+ export function lineAngle(p0, p1) {
133
+ return Math.atan2(p1.y - p0.y, p1.x - p0.x);
134
+ }
135
+ /**
136
+ * Projects `point` onto the nearest position on segment `line`, returning the projected point,
137
+ * the normalized parameter `t` (clamped to `[0, 1]`), and the distance from `point` to the
138
+ * projection. For a zero-length segment, `t` is `0`, the projected point equals `line.p0`, and
139
+ * the distance is the distance from `point` to `p0`.
140
+ * @param line - the segment to project onto
141
+ * @param point - the point to project
142
+ * @param target - optional point to write the projected position into; defaults to a new {@link Point}
143
+ * @returns `{ projected, t, distance }` where `t ∈ [0, 1]`
144
+ */
145
+ export function lineProjectPoint(line, point, target) {
146
+ // Read inputs to locals — alias-safe even if `target` overlaps with `line` points.
147
+ const p0x = line.p0.x, p0y = line.p0.y;
148
+ const p1x = line.p1.x, p1y = line.p1.y;
149
+ const px = point.x, py = point.y;
150
+ const dx = p1x - p0x, dy = p1y - p0y;
151
+ const lenSq = dx * dx + dy * dy;
152
+ let t;
153
+ if (lenSq === 0) {
154
+ t = 0;
155
+ }
156
+ else {
157
+ const dot = (px - p0x) * dx + (py - p0y) * dy;
158
+ t = dot / lenSq;
159
+ t = t < 0 ? 0 : t > 1 ? 1 : t;
160
+ }
161
+ // Inline the lerp (avoid two transient {x,y} allocations on this hot path); `target` may alias an
162
+ // input, but all coords were copied to locals above. The distance uses the saved px/py snapshot so it
163
+ // stays correct even when `target === point`.
164
+ const projected = (target ?? new Point()).set(p0x + dx * t, p0y + dy * t, line.elevation ?? 0);
165
+ const distance = pointDistance({ x: px, y: py }, projected);
166
+ return { projected, t, distance };
167
+ }
@@ -0,0 +1,166 @@
1
+ import { Box } from './box.js';
2
+ import { Point, type Point2Like, type PointLike } from './point.js';
3
+ import type { Polygon } from './polygon.js';
4
+ /** A triplet of vertex indices forming a triangle. */
5
+ export type TriangleIndex = readonly [number, number, number];
6
+ /** Structural mesh: vertices plus triangle indices. */
7
+ export interface MeshLike {
8
+ /** Mesh vertices (may carry a z coordinate). */
9
+ readonly vertices: readonly PointLike[];
10
+ /** Triangle index triplets. */
11
+ readonly indices: readonly TriangleIndex[];
12
+ }
13
+ /**
14
+ * A 3D triangle mesh: vertices carry an optional z coordinate, plus triangle index triplets.
15
+ * Immutable value object: readonly getters; transforms return a new instance unless a `target`
16
+ * is passed. For a planar triangulated polygon with area/containment use `Polygon` instead.
17
+ */
18
+ export declare class Mesh {
19
+ /** Marker so callers can narrow the type at runtime. */
20
+ readonly isMesh = true;
21
+ /** Internal mutable vertex array (3D). */
22
+ private _vertices;
23
+ /** Internal triangle index array. */
24
+ private _indices;
25
+ /** Cached axis-aligned bounding box (xy only). */
26
+ private _bounds;
27
+ /**
28
+ * Constructs a mesh from a vertex list and triangle index triplets.
29
+ * @param vertices - source vertices; each is cloned into a {@link Point} (default `[]`)
30
+ * @param indices - triangle index triplets referencing positions in `vertices` (default `[]`)
31
+ */
32
+ constructor(vertices?: readonly PointLike[], indices?: readonly TriangleIndex[]);
33
+ /**
34
+ * Readonly array of mesh vertices as {@link Point} instances.
35
+ * @returns the vertex array
36
+ */
37
+ get vertices(): readonly Point[];
38
+ /**
39
+ * Readonly array of triangle index triplets.
40
+ * @returns the index array
41
+ */
42
+ get indices(): readonly TriangleIndex[];
43
+ /**
44
+ * Cached axis-aligned bounding {@link Box} of this mesh (xy only, z ignored).
45
+ * @returns the bounding box
46
+ */
47
+ get bounds(): Box;
48
+ /**
49
+ * Mutates this mesh in place, replacing vertices/indices and refreshing the cached bounds.
50
+ * Vertices are copied into fresh {@link Point}s — do not optimize this clone away; transform
51
+ * free functions rely on it to avoid aliasing shared vertices. Use only for hot-path reuse.
52
+ * @param vertices - new vertex list
53
+ * @param indices - new triangle index list
54
+ * @returns `this`
55
+ */
56
+ set(vertices: readonly PointLike[], indices: readonly TriangleIndex[]): this;
57
+ /**
58
+ * Merges two or more meshes into a single {@link Mesh}, offsetting each mesh's triangle indices
59
+ * by the cumulative vertex count so they remain valid. Forwards to {@link meshMerge}.
60
+ * @param meshes - meshes to merge
61
+ * @returns a new merged mesh
62
+ */
63
+ static merge(...meshes: MeshLike[]): Mesh;
64
+ /**
65
+ * Returns a new mesh translated by `offset`. Forwards to {@link meshTranslate}.
66
+ * @param offset - translation vector
67
+ * @param target - optional mesh to write into instead of allocating a new one
68
+ * @returns translated mesh
69
+ */
70
+ translate(offset: PointLike, target?: Mesh): Mesh;
71
+ /**
72
+ * Returns a new mesh scaled by `factor` about `origin`. Forwards to {@link meshScale}.
73
+ * @param factor - uniform scale or per-axis `{ x, y }` scale
74
+ * @param origin - the fixed point of the scaling; defaults to the bounding-box center
75
+ * @param target - optional mesh to write into instead of allocating a new one
76
+ * @returns scaled mesh
77
+ */
78
+ scale(factor: number | Point2Like, origin?: Point2Like, target?: Mesh): Mesh;
79
+ /**
80
+ * Returns a new mesh rotated by `angle` radians about `origin`. Forwards to {@link meshRotate}.
81
+ * @param angle - rotation angle in radians (positive = clockwise in y-down space)
82
+ * @param origin - the pivot of the rotation; defaults to the bounding-box center
83
+ * @param target - optional mesh to write into instead of allocating a new one
84
+ * @returns rotated mesh
85
+ */
86
+ rotate(angle: number, origin?: Point2Like, target?: Mesh): Mesh;
87
+ }
88
+ /**
89
+ * Computes the axis-aligned bounding {@link Box} of a mesh by sweeping all vertex xy coordinates.
90
+ * The z component is ignored — bounds are always in the xy plane.
91
+ * @param m - mesh or mesh-like object
92
+ * @returns the bounding box
93
+ */
94
+ export declare function meshBounds(m: MeshLike): Box;
95
+ /**
96
+ * Merges two or more meshes into a single mesh, offsetting each mesh's triangle indices by the
97
+ * cumulative vertex count so they remain valid. When `target` is provided the result is written
98
+ * into it, preserving the target's concrete type (e.g. a `Polygon` target stays a `Polygon`).
99
+ * @param meshes - meshes to merge
100
+ * @param target - mesh to write into; receives the merged vertices and indices
101
+ * @returns `target` with the merged data
102
+ */
103
+ export declare function meshMerge<T extends Mesh | Polygon>(meshes: readonly MeshLike[], target: T): T;
104
+ /**
105
+ * Merges two or more meshes into a single new {@link Mesh}, offsetting each mesh's triangle
106
+ * indices by the cumulative vertex count so they remain valid.
107
+ * @param meshes - meshes to merge
108
+ * @returns a new merged mesh
109
+ */
110
+ export declare function meshMerge(meshes: readonly MeshLike[]): Mesh;
111
+ /**
112
+ * Returns a new mesh whose vertices are translated by `offset`. Writes into `target` when
113
+ * provided, preserving the target's concrete type (e.g. a `Polygon` target stays a `Polygon`).
114
+ * @param m - source mesh
115
+ * @param offset - translation vector; `z` defaults to 0
116
+ * @param target - mesh to write into; receives the translated vertices in place
117
+ * @returns `target` with updated vertices
118
+ */
119
+ export declare function meshTranslate<T extends Mesh | Polygon>(m: MeshLike, offset: PointLike, target: T): T;
120
+ /**
121
+ * Returns a new {@link Mesh} whose vertices are translated by `offset`. Does not mutate `m`.
122
+ * @param m - source mesh
123
+ * @param offset - translation vector; `z` defaults to 0
124
+ * @returns new translated mesh
125
+ */
126
+ export declare function meshTranslate(m: MeshLike, offset: PointLike): Mesh;
127
+ /**
128
+ * Returns a new mesh whose vertices are scaled by `factor` about `origin`. The xy coordinates
129
+ * are scaled; z is preserved unchanged. Writes into `target` when provided.
130
+ * @param m - source mesh
131
+ * @param factor - uniform scale or per-axis `{ x, y }` scale
132
+ * @param origin - the fixed point of the scaling; defaults to the mesh's bounding-box center
133
+ * @param target - mesh to write into; receives the scaled vertices in place
134
+ * @returns `target` with updated vertices
135
+ */
136
+ export declare function meshScale<T extends Mesh | Polygon>(m: MeshLike, factor: number | Point2Like, origin: Point2Like, target: T): T;
137
+ /**
138
+ * Returns a new {@link Mesh} whose vertices are scaled by `factor` about `origin`. Does not
139
+ * mutate `m`.
140
+ * @param m - source mesh
141
+ * @param factor - uniform scale or per-axis `{ x, y }` scale
142
+ * @param origin - the fixed point of the scaling; defaults to the mesh's bounding-box center
143
+ * @returns new scaled mesh
144
+ */
145
+ export declare function meshScale(m: MeshLike, factor: number | Point2Like, origin?: Point2Like): Mesh;
146
+ /**
147
+ * Returns a new mesh whose vertices are rotated by `angle` radians about `origin`. The xy
148
+ * coordinates are rotated; z is preserved unchanged. Positive angles rotate clockwise in
149
+ * y-down coordinate space. Writes into `target` when provided.
150
+ * @param m - source mesh
151
+ * @param angle - rotation angle in radians (positive = clockwise in y-down space)
152
+ * @param origin - the pivot of the rotation; defaults to the mesh's bounding-box center
153
+ * @param target - mesh to write into; receives the rotated vertices in place
154
+ * @returns `target` with updated vertices
155
+ */
156
+ export declare function meshRotate<T extends Mesh | Polygon>(m: MeshLike, angle: number, origin: Point2Like, target: T): T;
157
+ /**
158
+ * Returns a new {@link Mesh} whose vertices are rotated by `angle` radians about `origin`. Does
159
+ * not mutate `m`.
160
+ * @param m - source mesh
161
+ * @param angle - rotation angle in radians (positive = clockwise in y-down space)
162
+ * @param origin - the pivot of the rotation; defaults to the mesh's bounding-box center
163
+ * @returns new rotated mesh
164
+ */
165
+ export declare function meshRotate(m: MeshLike, angle: number, origin?: Point2Like): Mesh;
166
+ //# sourceMappingURL=mesh.d.ts.map