@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,169 @@
1
+ import { Box } from './box.js';
2
+ import { type TriangleIndex } from './mesh.js';
3
+ import { type Point2Like, type PointLike } from './point.js';
4
+ /** Structural polygon: 2D vertices plus triangle indices and an optional elevation. */
5
+ export interface PolygonLike {
6
+ /** Polygon vertices (2D — xy only). */
7
+ readonly vertices: readonly Point2Like[];
8
+ /** Triangle index triplets. */
9
+ readonly indices: readonly TriangleIndex[];
10
+ /** Elevation in 3D space (default 0). */
11
+ readonly elevation?: number;
12
+ }
13
+ /**
14
+ * A planar triangulated polygon: 2D vertices (`{ x, y }`), triangle index triplets, and an
15
+ * `elevation` scalar that positions the plane in 3D space. Immutable value object: readonly
16
+ * getters; transforms return a new instance unless a `target` is passed.
17
+ *
18
+ * Polygon structurally satisfies `MeshLike` so its transform methods can forward to the
19
+ * canonical mesh free functions (`meshTranslate`, `meshScale`, `meshRotate`) without duplicating
20
+ * any transform logic.
21
+ */
22
+ export declare class Polygon {
23
+ /** Marker so callers can narrow the type at runtime. */
24
+ readonly isPolygon = true;
25
+ /** Internal mutable 2D vertex array. */
26
+ private _vertices;
27
+ /** Internal triangle index array. */
28
+ private _indices;
29
+ /** Elevation in 3D space. */
30
+ private _elevation;
31
+ /** Cached axis-aligned bounding box (xy only). */
32
+ private _bounds;
33
+ /**
34
+ * Constructs a polygon from a 2D vertex list, triangle index triplets, and an optional
35
+ * elevation.
36
+ * @param vertices - source vertices; stored as `{ x, y }` (z is dropped) (default `[]`)
37
+ * @param indices - triangle index triplets referencing positions in `vertices` (default `[]`)
38
+ * @param elevation - elevation of the plane in 3D space (default 0)
39
+ */
40
+ constructor(vertices?: readonly Point2Like[], indices?: readonly TriangleIndex[], elevation?: number);
41
+ /**
42
+ * Fan-triangulates an ordered convex ring into a {@link Polygon}.
43
+ *
44
+ * Generates triangles `[0, i, i+1]` for `i` in `1 .. n-2`. This triangulation is only valid
45
+ * for **convex** input rings — fan triangulation produces incorrect results for concave rings.
46
+ * For a concave or arbitrary shape, construct `Polygon` directly with explicit `indices`.
47
+ *
48
+ * Use `containsPoint` on the resulting polygon (via `polygonContainsPoint`) to test inclusion.
49
+ * @param points - ordered convex polygon vertices (CCW or CW)
50
+ * @param elevation - elevation of the plane in 3D space (default 0)
51
+ * @returns a new polygon, or an empty polygon when fewer than 3 points are given
52
+ */
53
+ static fromConvexRing(points: readonly Point2Like[], elevation?: number): Polygon;
54
+ /**
55
+ * Merges two or more polygons into a single {@link Polygon}, offsetting each polygon's
56
+ * triangle indices by the cumulative vertex count so they remain valid. Forwards to
57
+ * {@link meshMerge}.
58
+ * @param polygons - polygons to merge
59
+ * @returns a new merged polygon (elevation taken from first polygon, or 0)
60
+ */
61
+ static merge(...polygons: PolygonLike[]): Polygon;
62
+ /**
63
+ * Readonly array of polygon vertices as `{ x, y }` objects.
64
+ * @returns the vertex array
65
+ */
66
+ get vertices(): readonly Point2Like[];
67
+ /**
68
+ * Readonly array of triangle index triplets.
69
+ * @returns the index array
70
+ */
71
+ get indices(): readonly TriangleIndex[];
72
+ /**
73
+ * Elevation of this polygon's plane in 3D space.
74
+ * @returns the elevation
75
+ */
76
+ get elevation(): number;
77
+ /**
78
+ * Cached axis-aligned bounding {@link Box} of this polygon (xy only).
79
+ * @returns the bounding box
80
+ */
81
+ get bounds(): Box;
82
+ /**
83
+ * Total area of this polygon (sum of absolute triangle areas). See {@link polygonArea}.
84
+ * @returns the area in square units
85
+ */
86
+ get area(): number;
87
+ /**
88
+ * Returns true when `point` lies inside or on the boundary of this polygon.
89
+ * See {@link polygonContainsPoint}.
90
+ * @param point - the point to test
91
+ * @param opts - options controlling tolerance
92
+ * @param opts.areaTolerance - relative tolerance per triangle (0–1); default 0.01
93
+ * @returns true when `point` is contained
94
+ */
95
+ containsPoint(point: Point2Like, opts?: {
96
+ areaTolerance?: number;
97
+ }): boolean;
98
+ /**
99
+ * Returns a new polygon translated by `offset`. Forwards to {@link meshTranslate}.
100
+ * The elevation is preserved on the result.
101
+ * @param offset - 2D translation vector
102
+ * @param target - optional polygon to write into instead of allocating a new one
103
+ * @returns translated polygon
104
+ */
105
+ translate(offset: Point2Like, target?: Polygon): Polygon;
106
+ /**
107
+ * Returns a new polygon scaled by `factor` about `origin`. Forwards to {@link meshScale}.
108
+ * The elevation is preserved on the result.
109
+ * @param factor - uniform scale or per-axis `{ x, y }` scale
110
+ * @param origin - the fixed point of the scaling; defaults to the bounding-box center
111
+ * @param target - optional polygon to write into instead of allocating a new one
112
+ * @returns scaled polygon
113
+ */
114
+ scale(factor: number | Point2Like, origin?: Point2Like, target?: Polygon): Polygon;
115
+ /**
116
+ * Returns a new polygon rotated by `angle` radians about `origin`. Forwards to
117
+ * {@link meshRotate}.
118
+ * The elevation is preserved on the result.
119
+ * @param angle - rotation angle in radians (positive = clockwise in y-down space)
120
+ * @param origin - the pivot of the rotation; defaults to the bounding-box center
121
+ * @param target - optional polygon to write into instead of allocating a new one
122
+ * @returns rotated polygon
123
+ */
124
+ rotate(angle: number, origin?: Point2Like, target?: Polygon): Polygon;
125
+ /**
126
+ * Mutates this polygon in place, replacing vertices/indices and optionally the elevation, then
127
+ * refreshing the cached bounds. Vertices are stored as 2D `{ x, y }` — any z from the input is
128
+ * dropped. Do not optimize this clone away; the mesh transform free functions rely on it to avoid
129
+ * aliasing shared vertices. When `elevation` is omitted the current elevation is preserved (this
130
+ * keeps the 2-arg `target.set(v, i)` forwarding path in the mesh free functions intact). Use
131
+ * only for hot-path reuse.
132
+ * @param vertices - new vertex list (z ignored)
133
+ * @param indices - new triangle index list
134
+ * @param elevation - new elevation; defaults to the current elevation when omitted
135
+ * @returns `this`
136
+ */
137
+ set(vertices: readonly PointLike[], indices: readonly TriangleIndex[], elevation?: number): this;
138
+ }
139
+ /**
140
+ * Total signed area of the polygon, computed as the sum of the absolute areas of each triangle
141
+ * in the index list (fan/shoelace per triangle). The result is always non-negative regardless of
142
+ * vertex winding order.
143
+ * @param p - polygon or polygon-like object
144
+ * @returns the total area in square units
145
+ */
146
+ export declare function polygonArea(p: PolygonLike): number;
147
+ /**
148
+ * Returns true when `point` lies inside or on the boundary of polygon `p`. The test iterates
149
+ * over every triangle in `p.indices` and checks whether `point` lies within any of them using a
150
+ * signed-area (barycentric) test. Works for both convex shapes and arbitrary triangulated meshes.
151
+ * Zero-area (degenerate) triangles are skipped — they have no interior and never contain a point.
152
+ *
153
+ * The optional `areaTolerance` (default `0.01`, i.e. 1%) expands each triangle's containment
154
+ * boundary by a margin proportional to its area, admitting points that lie just outside the
155
+ * strict geometric boundary.
156
+ * @param p - polygon or polygon-like object
157
+ * @param point - the point to test
158
+ * @param opts - options controlling the tolerance
159
+ * @param opts.areaTolerance - relative slack per triangle, as a fraction of that triangle's own
160
+ * area; default `0.01` (1%), which absorbs float/GPS boundary noise. `0` is the strict geometric
161
+ * test. Intended range is small (`~[0, 0.1]`); values `>= 1` let the slack reach or exceed a
162
+ * triangle's area and admit points well outside the polygon, so they are not meaningful for
163
+ * containment.
164
+ * @returns true when `point` is contained within any triangle (within tolerance)
165
+ */
166
+ export declare function polygonContainsPoint(p: PolygonLike, point: Point2Like, opts?: {
167
+ areaTolerance?: number;
168
+ }): boolean;
169
+ //# sourceMappingURL=polygon.d.ts.map
@@ -0,0 +1,220 @@
1
+ import { Box } from './box.js';
2
+ import { meshBounds, meshMerge, meshRotate, meshScale, meshTranslate, } from './mesh.js';
3
+ /**
4
+ * A planar triangulated polygon: 2D vertices (`{ x, y }`), triangle index triplets, and an
5
+ * `elevation` scalar that positions the plane in 3D space. Immutable value object: readonly
6
+ * getters; transforms return a new instance unless a `target` is passed.
7
+ *
8
+ * Polygon structurally satisfies `MeshLike` so its transform methods can forward to the
9
+ * canonical mesh free functions (`meshTranslate`, `meshScale`, `meshRotate`) without duplicating
10
+ * any transform logic.
11
+ */
12
+ export class Polygon {
13
+ /** Marker so callers can narrow the type at runtime. */
14
+ isPolygon = true;
15
+ /** Internal mutable 2D vertex array. */
16
+ _vertices = [];
17
+ /** Internal triangle index array. */
18
+ _indices = [];
19
+ /** Elevation in 3D space. */
20
+ _elevation;
21
+ /** Cached axis-aligned bounding box (xy only). */
22
+ _bounds = new Box();
23
+ /**
24
+ * Constructs a polygon from a 2D vertex list, triangle index triplets, and an optional
25
+ * elevation.
26
+ * @param vertices - source vertices; stored as `{ x, y }` (z is dropped) (default `[]`)
27
+ * @param indices - triangle index triplets referencing positions in `vertices` (default `[]`)
28
+ * @param elevation - elevation of the plane in 3D space (default 0)
29
+ */
30
+ constructor(vertices = [], indices = [], elevation = 0) {
31
+ this._elevation = elevation;
32
+ this.set(vertices, indices);
33
+ }
34
+ /**
35
+ * Fan-triangulates an ordered convex ring into a {@link Polygon}.
36
+ *
37
+ * Generates triangles `[0, i, i+1]` for `i` in `1 .. n-2`. This triangulation is only valid
38
+ * for **convex** input rings — fan triangulation produces incorrect results for concave rings.
39
+ * For a concave or arbitrary shape, construct `Polygon` directly with explicit `indices`.
40
+ *
41
+ * Use `containsPoint` on the resulting polygon (via `polygonContainsPoint`) to test inclusion.
42
+ * @param points - ordered convex polygon vertices (CCW or CW)
43
+ * @param elevation - elevation of the plane in 3D space (default 0)
44
+ * @returns a new polygon, or an empty polygon when fewer than 3 points are given
45
+ */
46
+ static fromConvexRing(points, elevation = 0) {
47
+ if (points.length < 3)
48
+ return new Polygon([], [], elevation);
49
+ const indices = [];
50
+ for (let i = 1; i <= points.length - 2; i++) {
51
+ indices.push([0, i, i + 1]);
52
+ }
53
+ return new Polygon(points, indices, elevation);
54
+ }
55
+ /**
56
+ * Merges two or more polygons into a single {@link Polygon}, offsetting each polygon's
57
+ * triangle indices by the cumulative vertex count so they remain valid. Forwards to
58
+ * {@link meshMerge}.
59
+ * @param polygons - polygons to merge
60
+ * @returns a new merged polygon (elevation taken from first polygon, or 0)
61
+ */
62
+ static merge(...polygons) {
63
+ return meshMerge(polygons, new Polygon([], [], polygons[0]?.elevation ?? 0));
64
+ }
65
+ /**
66
+ * Readonly array of polygon vertices as `{ x, y }` objects.
67
+ * @returns the vertex array
68
+ */
69
+ get vertices() {
70
+ return this._vertices;
71
+ }
72
+ /**
73
+ * Readonly array of triangle index triplets.
74
+ * @returns the index array
75
+ */
76
+ get indices() {
77
+ return this._indices;
78
+ }
79
+ /**
80
+ * Elevation of this polygon's plane in 3D space.
81
+ * @returns the elevation
82
+ */
83
+ get elevation() {
84
+ return this._elevation;
85
+ }
86
+ /**
87
+ * Cached axis-aligned bounding {@link Box} of this polygon (xy only).
88
+ * @returns the bounding box
89
+ */
90
+ get bounds() {
91
+ return this._bounds;
92
+ }
93
+ /**
94
+ * Total area of this polygon (sum of absolute triangle areas). See {@link polygonArea}.
95
+ * @returns the area in square units
96
+ */
97
+ get area() {
98
+ return polygonArea(this);
99
+ }
100
+ /**
101
+ * Returns true when `point` lies inside or on the boundary of this polygon.
102
+ * See {@link polygonContainsPoint}.
103
+ * @param point - the point to test
104
+ * @param opts - options controlling tolerance
105
+ * @param opts.areaTolerance - relative tolerance per triangle (0–1); default 0.01
106
+ * @returns true when `point` is contained
107
+ */
108
+ containsPoint(point, opts) {
109
+ return polygonContainsPoint(this, point, opts);
110
+ }
111
+ /**
112
+ * Returns a new polygon translated by `offset`. Forwards to {@link meshTranslate}.
113
+ * The elevation is preserved on the result.
114
+ * @param offset - 2D translation vector
115
+ * @param target - optional polygon to write into instead of allocating a new one
116
+ * @returns translated polygon
117
+ */
118
+ translate(offset, target) {
119
+ return meshTranslate(this, offset, target ?? new Polygon([], [], this._elevation));
120
+ }
121
+ /**
122
+ * Returns a new polygon scaled by `factor` about `origin`. Forwards to {@link meshScale}.
123
+ * The elevation is preserved on the result.
124
+ * @param factor - uniform scale or per-axis `{ x, y }` scale
125
+ * @param origin - the fixed point of the scaling; defaults to the bounding-box center
126
+ * @param target - optional polygon to write into instead of allocating a new one
127
+ * @returns scaled polygon
128
+ */
129
+ scale(factor, origin = this._bounds.center, target) {
130
+ return meshScale(this, factor, origin, target ?? new Polygon([], [], this._elevation));
131
+ }
132
+ /**
133
+ * Returns a new polygon rotated by `angle` radians about `origin`. Forwards to
134
+ * {@link meshRotate}.
135
+ * The elevation is preserved on the result.
136
+ * @param angle - rotation angle in radians (positive = clockwise in y-down space)
137
+ * @param origin - the pivot of the rotation; defaults to the bounding-box center
138
+ * @param target - optional polygon to write into instead of allocating a new one
139
+ * @returns rotated polygon
140
+ */
141
+ rotate(angle, origin = this._bounds.center, target) {
142
+ return meshRotate(this, angle, origin, target ?? new Polygon([], [], this._elevation));
143
+ }
144
+ /**
145
+ * Mutates this polygon in place, replacing vertices/indices and optionally the elevation, then
146
+ * refreshing the cached bounds. Vertices are stored as 2D `{ x, y }` — any z from the input is
147
+ * dropped. Do not optimize this clone away; the mesh transform free functions rely on it to avoid
148
+ * aliasing shared vertices. When `elevation` is omitted the current elevation is preserved (this
149
+ * keeps the 2-arg `target.set(v, i)` forwarding path in the mesh free functions intact). Use
150
+ * only for hot-path reuse.
151
+ * @param vertices - new vertex list (z ignored)
152
+ * @param indices - new triangle index list
153
+ * @param elevation - new elevation; defaults to the current elevation when omitted
154
+ * @returns `this`
155
+ */
156
+ set(vertices, indices, elevation = this._elevation) {
157
+ this._vertices = vertices.map((v) => ({ x: v.x, y: v.y }));
158
+ this._indices = indices;
159
+ this._elevation = elevation;
160
+ this._bounds = meshBounds(this);
161
+ return this;
162
+ }
163
+ }
164
+ /**
165
+ * Total signed area of the polygon, computed as the sum of the absolute areas of each triangle
166
+ * in the index list (fan/shoelace per triangle). The result is always non-negative regardless of
167
+ * vertex winding order.
168
+ * @param p - polygon or polygon-like object
169
+ * @returns the total area in square units
170
+ */
171
+ export function polygonArea(p) {
172
+ let area = 0;
173
+ for (const [ai, bi, ci] of p.indices) {
174
+ const va = p.vertices[ai], vb = p.vertices[bi], vc = p.vertices[ci];
175
+ area += Math.abs((vb.x - va.x) * (vc.y - va.y) - (vc.x - va.x) * (vb.y - va.y)) / 2;
176
+ }
177
+ return area;
178
+ }
179
+ /**
180
+ * Returns true when `point` lies inside or on the boundary of polygon `p`. The test iterates
181
+ * over every triangle in `p.indices` and checks whether `point` lies within any of them using a
182
+ * signed-area (barycentric) test. Works for both convex shapes and arbitrary triangulated meshes.
183
+ * Zero-area (degenerate) triangles are skipped — they have no interior and never contain a point.
184
+ *
185
+ * The optional `areaTolerance` (default `0.01`, i.e. 1%) expands each triangle's containment
186
+ * boundary by a margin proportional to its area, admitting points that lie just outside the
187
+ * strict geometric boundary.
188
+ * @param p - polygon or polygon-like object
189
+ * @param point - the point to test
190
+ * @param opts - options controlling the tolerance
191
+ * @param opts.areaTolerance - relative slack per triangle, as a fraction of that triangle's own
192
+ * area; default `0.01` (1%), which absorbs float/GPS boundary noise. `0` is the strict geometric
193
+ * test. Intended range is small (`~[0, 0.1]`); values `>= 1` let the slack reach or exceed a
194
+ * triangle's area and admit points well outside the polygon, so they are not meaningful for
195
+ * containment.
196
+ * @returns true when `point` is contained within any triangle (within tolerance)
197
+ */
198
+ export function polygonContainsPoint(p, point, opts) {
199
+ const tol = opts?.areaTolerance ?? 0.01;
200
+ for (const [ai, bi, ci] of p.indices) {
201
+ const va = p.vertices[ai], vb = p.vertices[bi], vc = p.vertices[ci];
202
+ const triArea = Math.abs((vb.x - va.x) * (vc.y - va.y) - (vc.x - va.x) * (vb.y - va.y)) / 2;
203
+ // A zero-area triangle (single-point or collinear vertices) has no interior, so it
204
+ // contains nothing. Skip it: otherwise threshold = 0 and the barycentric test below
205
+ // sees every d = 0 and reports the entire plane as contained.
206
+ if (triArea === 0)
207
+ continue;
208
+ const threshold = tol * triArea;
209
+ // Barycentric signed-area test: the point is inside when d1, d2, d3 all share the
210
+ // same sign (or lie within the threshold margin).
211
+ const d1 = (point.x - vb.x) * (va.y - vb.y) - (va.x - vb.x) * (point.y - vb.y);
212
+ const d2 = (point.x - vc.x) * (vb.y - vc.y) - (vb.x - vc.x) * (point.y - vc.y);
213
+ const d3 = (point.x - va.x) * (vc.y - va.y) - (vc.x - va.x) * (point.y - va.y);
214
+ const hasNeg = d1 < -threshold || d2 < -threshold || d3 < -threshold;
215
+ const hasPos = d1 > threshold || d2 > threshold || d3 > threshold;
216
+ if (!(hasNeg && hasPos))
217
+ return true;
218
+ }
219
+ return false;
220
+ }
@@ -0,0 +1,200 @@
1
+ import { Box } from './box.js';
2
+ import type { LineLike } from './line.js';
3
+ import { Point, type Point2Like, type SizeLike } from './point.js';
4
+ import { Polygon } from './polygon.js';
5
+ /** Structural rotatable rect. */
6
+ export interface RectLike {
7
+ /** Center point. */
8
+ readonly center: Point2Like;
9
+ /** Width/height. */
10
+ readonly size: Point2Like;
11
+ /** Rotation in radians; positive = clockwise (y-down). Defaults to 0. */
12
+ readonly rotation?: number;
13
+ /** Planar elevation (z). Defaults to 0. */
14
+ readonly elevation?: number;
15
+ }
16
+ /**
17
+ * A rectangle that may be rotated about its center (center + size + rotation + elevation; the
18
+ * unrotated box is not exposed). Immutable value object: readonly getters; transforms return new
19
+ * unless a method `target` is passed. Rotation in radians, positive = clockwise (y-down).
20
+ */
21
+ export declare class Rect {
22
+ /** Marker so callers can narrow the type at runtime. */
23
+ readonly isRect = true;
24
+ /** Internal mutable backing for the center point. */
25
+ private readonly _center;
26
+ /** Internal mutable backing for the size vector (x = width, y = height). */
27
+ private readonly _size;
28
+ /** Internal mutable rotation in radians. */
29
+ private _rotation;
30
+ /** Internal mutable elevation (z). */
31
+ private _elevation;
32
+ /**
33
+ * Constructs a {@link Rect} from center, size, rotation, and elevation.
34
+ * @param center - center point `{ x, y }`
35
+ * @param size - dimensions `{ x: width, y: height }`
36
+ * @param rotation - rotation in radians, positive = clockwise (y-down); defaults to 0
37
+ * @param elevation - planar elevation (z); defaults to 0
38
+ */
39
+ constructor(center: Point2Like, size: Point2Like, rotation?: number, elevation?: number);
40
+ /**
41
+ * Constructs a {@link Rect} from a min/max corner pair.
42
+ * @param min - minimum (top-left) corner `{ x, y }`
43
+ * @param max - maximum (bottom-right) corner `{ x, y }`
44
+ * @param rotation - rotation in radians; defaults to 0
45
+ * @param elevation - planar elevation (z); defaults to 0
46
+ * @returns a new {@link Rect} whose center is the midpoint of min/max
47
+ */
48
+ static fromMinMax(min: Point2Like, max: Point2Like, rotation?: number, elevation?: number): Rect;
49
+ /**
50
+ * The center point of this rect.
51
+ * @returns a readonly `{ x, y }` view of the center
52
+ */
53
+ get center(): Readonly<Point2Like>;
54
+ /**
55
+ * The size (width/height) of this rect. `width` aliases `x`; `height` aliases `y`.
56
+ * @returns a readonly point view with `width` and `height` accessors
57
+ */
58
+ get size(): SizeLike;
59
+ /**
60
+ * Rotation in radians (positive = clockwise, y-down).
61
+ * @returns the current rotation
62
+ */
63
+ get rotation(): number;
64
+ /**
65
+ * Planar elevation (z coordinate of the rect plane).
66
+ * @returns the current elevation
67
+ */
68
+ get elevation(): number;
69
+ /**
70
+ * Returns the four corners of this rect, rotated about its center.
71
+ * @returns array of four {@link Point} instances: top-left, top-right, bottom-right, bottom-left
72
+ */
73
+ corners(): Point[];
74
+ /**
75
+ * The axis-aligned bounding box that contains this (possibly rotated) rect.
76
+ * @returns a {@link Box} representing the AABB
77
+ */
78
+ get bounds(): Box;
79
+ /**
80
+ * Converts this rect to a triangulated {@link Polygon}, embedding the elevation as `z`.
81
+ * @returns a {@link Polygon} with four vertices and two triangle indices
82
+ */
83
+ toPolygon(): Polygon;
84
+ /**
85
+ * Returns whether a point lies inside this (possibly rotated) rect.
86
+ * @param p - the point to test `{ x, y }`
87
+ * @returns `true` if `p` is inside or on the boundary of this rect
88
+ */
89
+ containsPoint(p: Point2Like): boolean;
90
+ /**
91
+ * Returns a new rect translated by `offset`. If `target` is provided, writes into `target`
92
+ * and returns it instead of allocating.
93
+ * @param offset - translation vector `{ x, y }`
94
+ * @param target - optional rect to mutate in place
95
+ * @returns the translated rect
96
+ */
97
+ translate(offset: Point2Like, target?: Rect): Rect;
98
+ /**
99
+ * Returns a new rect with rotation increased by `angle`. If `target` is provided, writes into
100
+ * `target` and returns it instead of allocating.
101
+ * @param angle - angle to add in radians
102
+ * @param target - optional rect to mutate in place
103
+ * @returns the rotated rect
104
+ */
105
+ rotate(angle: number, target?: Rect): Rect;
106
+ /**
107
+ * Returns a new rect scaled by `factor` about `origin`: the center moves toward/away from `origin`
108
+ * by `factor` and the size is multiplied by `factor`; rotation and elevation are preserved.
109
+ * If `target` is provided, writes into it instead of allocating.
110
+ * @param factor - uniform scale or per-axis `{ x, y }` scale
111
+ * @param origin - the fixed point of the scaling; defaults to this rect's center
112
+ * @param target - optional rect to mutate in place
113
+ * @returns the scaled rect
114
+ */
115
+ scale(factor: number | Point2Like, origin?: Point2Like, target?: Rect): Rect;
116
+ /**
117
+ * Points where `line` crosses this rect. Delegates to {@link intersectLineRect}.
118
+ * @param line - the segment
119
+ * @returns the intersection points
120
+ */
121
+ intersectLine(line: LineLike): Point[];
122
+ /**
123
+ * Returns a copy of this rect. If `target` is provided, writes into `target` and returns it.
124
+ * @param target - optional rect to mutate in place
125
+ * @returns the cloned rect
126
+ */
127
+ clone(target?: Rect): Rect;
128
+ /**
129
+ * Mutates this rect in place (center, size, rotation, elevation). Prefer the immutable
130
+ * transforms; use this (or a transform `target`) only for hot-path reuse.
131
+ * @param cx - center x
132
+ * @param cy - center y
133
+ * @param sx - size x (width)
134
+ * @param sy - size y (height)
135
+ * @param rotation - rotation in radians
136
+ * @param elevation - planar elevation (z)
137
+ * @returns `this` for chaining
138
+ */
139
+ set(cx: number, cy: number, sx: number, sy: number, rotation: number, elevation: number): this;
140
+ }
141
+ /**
142
+ * Returns the four corners of a {@link RectLike}, rotated about its center.
143
+ * Order: top-left, top-right, bottom-right, bottom-left.
144
+ * @param r - the rect-like to compute corners for
145
+ * @returns array of four {@link Point} instances
146
+ */
147
+ export declare function rectCorners(r: RectLike): Point[];
148
+ /**
149
+ * Returns the axis-aligned bounding box (AABB) that contains all four corners of a
150
+ * {@link RectLike}.
151
+ * @param r - the rect-like to compute bounds for
152
+ * @returns a {@link Box} representing the AABB
153
+ */
154
+ export declare function rectBounds(r: RectLike): Box;
155
+ /**
156
+ * Converts a {@link RectLike} to a triangulated {@link Polygon} via fan-triangulation, embedding
157
+ * the elevation as `z` on each vertex. Rect corners form a convex quad, so
158
+ * {@link Polygon.fromConvexRing} is valid here.
159
+ * @param r - the rect-like to convert
160
+ * @returns a {@link Polygon} with four vertices and two triangle indices
161
+ */
162
+ export declare function rectToPolygon(r: RectLike): Polygon;
163
+ /**
164
+ * Returns whether a point lies inside a (possibly rotated) {@link RectLike} by transforming the
165
+ * point into the rect's local axis-aligned space.
166
+ * @param r - the rect-like to test against
167
+ * @param p - the point to test `{ x, y }`
168
+ * @returns `true` if `p` is inside or on the boundary of `r`
169
+ */
170
+ export declare function rectContainsPoint(r: RectLike, p: Point2Like): boolean;
171
+ /**
172
+ * Returns a new rect translated by `offset`. If `target` is provided, writes into `target` and
173
+ * returns it instead of allocating a new instance.
174
+ * @param r - the source rect-like
175
+ * @param offset - translation vector `{ x, y }`
176
+ * @param target - optional {@link Rect} to mutate in place
177
+ * @returns the translated rect
178
+ */
179
+ export declare function rectTranslate(r: RectLike, offset: Point2Like, target?: Rect): Rect;
180
+ /**
181
+ * Returns a new rect with rotation increased by `angle`. If `target` is provided, writes into
182
+ * `target` and returns it instead of allocating a new instance.
183
+ * @param r - the source rect-like
184
+ * @param angle - angle to add in radians
185
+ * @param target - optional {@link Rect} to mutate in place
186
+ * @returns the rotated rect
187
+ */
188
+ export declare function rectRotate(r: RectLike, angle: number, target?: Rect): Rect;
189
+ /**
190
+ * Returns a new rect scaled by `factor` about `origin`: the center moves toward/away from `origin`
191
+ * by `factor` and the size is multiplied by `factor`; rotation and elevation are preserved. If
192
+ * `target` is provided, writes into it instead of allocating a new instance.
193
+ * @param r - the source rect-like
194
+ * @param factor - uniform scale or per-axis `{ x, y }` scale
195
+ * @param origin - the fixed point of the scaling; defaults to `r`'s center
196
+ * @param target - optional {@link Rect} to mutate in place
197
+ * @returns the scaled rect
198
+ */
199
+ export declare function rectScale(r: RectLike, factor: number | Point2Like, origin?: Point2Like, target?: Rect): Rect;
200
+ //# sourceMappingURL=rect.d.ts.map