@ue-too/math 0.9.4 → 0.10.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.
package/README.md CHANGED
@@ -1,4 +1,258 @@
1
- # math
2
- This is a library that provides basic mathematical utilities for uē-tôo.
1
+ <h1 align="center">
2
+ @ue-too/math
3
+ </h1>
4
+ <p align="center">
5
+ Mathematical utilities for 2D and 3D point operations and transformations
6
+ </p>
3
7
 
4
- Detailed information would be added in the future.
8
+ <div align="center">
9
+
10
+ [![npm version](https://img.shields.io/npm/v/@ue-too/math.svg?style=for-the-badge)](https://www.npmjs.com/package/@ue-too/math)
11
+ [![License](https://img.shields.io/github/license/ue-too/ue-too?style=for-the-badge)](https://github.com/ue-too/ue-too/blob/main/LICENSE.txt)
12
+
13
+ </div>
14
+
15
+ ## Overview
16
+
17
+ `@ue-too/math` provides essential mathematical operations for canvas-based applications, including vector arithmetic, geometric transformations, angle calculations, and point comparisons. It seamlessly handles both 2D and 3D coordinates.
18
+
19
+ ### Key Features
20
+
21
+ - **Vector Operations**: Addition, subtraction, scaling, dot product, cross product
22
+ - **Geometric Transformations**: Rotation, axis transformation, coordinate conversion
23
+ - **Angle Utilities**: Normalization, angular difference calculation
24
+ - **Point Utilities**: Distance, interpolation, intersection detection
25
+ - **Comparison Functions**: Approximate equality with configurable precision
26
+ - **2D/3D Support**: All operations work with optional z-coordinates
27
+
28
+ ## Installation
29
+
30
+ ```bash
31
+ npm install @ue-too/math
32
+ ```
33
+
34
+ ## Quick Start
35
+
36
+ ```typescript
37
+ import { PointCal, Point } from '@ue-too/math';
38
+
39
+ // Vector addition
40
+ const a: Point = { x: 1, y: 2 };
41
+ const b: Point = { x: 3, y: 4 };
42
+ const sum = PointCal.addVector(a, b); // { x: 4, y: 6 }
43
+
44
+ // Calculate magnitude
45
+ const magnitude = PointCal.magnitude(a); // 2.236...
46
+
47
+ // Rotate a point
48
+ const point: Point = { x: 10, y: 0 };
49
+ const rotated = PointCal.rotatePoint(point, Math.PI / 2); // 90 degrees
50
+ // Result: { x: ~0, y: 10 }
51
+
52
+ // Get distance between points
53
+ const distance = PointCal.distanceBetweenPoints(a, b); // 2.828...
54
+ ```
55
+
56
+ ## Core APIs
57
+
58
+ ### PointCal Class
59
+
60
+ The `PointCal` class provides static methods for all point and vector operations.
61
+
62
+ #### Vector Arithmetic
63
+
64
+ ```typescript
65
+ // Add two vectors
66
+ PointCal.addVector(a, b);
67
+
68
+ // Subtract vectors
69
+ PointCal.subVector(a, b);
70
+
71
+ // Scale by scalar
72
+ PointCal.multiplyVectorByScalar(v, 2.5);
73
+
74
+ // Divide by scalar
75
+ PointCal.divideVectorByScalar(v, 2);
76
+ ```
77
+
78
+ #### Vector Operations
79
+
80
+ ```typescript
81
+ // Magnitude (length) of vector
82
+ PointCal.magnitude(v);
83
+
84
+ // Unit vector (normalized to length 1)
85
+ PointCal.unitVector(v);
86
+
87
+ // Dot product
88
+ PointCal.dotProduct(a, b);
89
+
90
+ // Cross product
91
+ PointCal.crossProduct(a, b);
92
+
93
+ // Unit vector from point a to point b
94
+ PointCal.unitVectorFromA2B(a, b);
95
+ ```
96
+
97
+ #### Transformations
98
+
99
+ ```typescript
100
+ // Rotate point around origin
101
+ PointCal.rotatePoint(point, angleInRadians);
102
+
103
+ // Rotate point around custom anchor
104
+ PointCal.transformPointWRTAnchor(point, anchor, angleInRadians);
105
+
106
+ // Transform to new axis system
107
+ PointCal.transform2NewAxis(point, angleInRadians);
108
+
109
+ // Flip y-axis (useful for coordinate system conversion)
110
+ PointCal.flipYAxis(point);
111
+ ```
112
+
113
+ #### Geometric Calculations
114
+
115
+ ```typescript
116
+ // Distance between points
117
+ PointCal.distanceBetweenPoints(a, b);
118
+
119
+ // Linear interpolation (lerp)
120
+ PointCal.linearInterpolation(a, b, 0.5); // Midpoint
121
+
122
+ // Angle from vector a to vector b
123
+ PointCal.angleFromA2B(a, b);
124
+
125
+ // Line segment intersection
126
+ PointCal.getLineIntersection(line1Start, line1End, line2Start, line2End);
127
+ ```
128
+
129
+ ### Angle Utilities
130
+
131
+ ```typescript
132
+ import { normalizeAngleZero2TwoPI, angleSpan } from '@ue-too/math';
133
+
134
+ // Normalize angle to [0, 2π)
135
+ const normalized = normalizeAngleZero2TwoPI(Math.PI * 3); // π
136
+
137
+ // Calculate smallest angle difference
138
+ const diff = angleSpan(fromAngle, toAngle); // Range: (-π, π]
139
+ ```
140
+
141
+ ### Comparison Functions
142
+
143
+ ```typescript
144
+ import { samePoint, sameDirection, approximatelyTheSame } from '@ue-too/math';
145
+
146
+ // Check if points are approximately equal
147
+ samePoint(a, b); // Uses default precision (0.000001)
148
+ samePoint(a, b, 0.01); // Custom precision
149
+
150
+ // Check if vectors have same direction
151
+ sameDirection(v1, v2);
152
+
153
+ // Approximate number equality
154
+ approximatelyTheSame(1.0, 1.0000001); // true
155
+ ```
156
+
157
+ ## Common Use Cases
158
+
159
+ ### Canvas Transformations
160
+
161
+ ```typescript
162
+ import { PointCal, Point } from '@ue-too/math';
163
+
164
+ // Transform mouse coordinates to rotated canvas space
165
+ const mousePos: Point = { x: 150, y: 200 };
166
+ const canvasCenter: Point = { x: 100, y: 100 };
167
+ const canvasRotation = Math.PI / 4; // 45 degrees
168
+
169
+ const transformedPos = PointCal.transformPointWRTAnchor(
170
+ mousePos,
171
+ canvasCenter,
172
+ -canvasRotation // Inverse rotation
173
+ );
174
+ ```
175
+
176
+ ### Path Following
177
+
178
+ ```typescript
179
+ import { PointCal, Point } from '@ue-too/math';
180
+
181
+ // Calculate direction from current position to target
182
+ const current: Point = { x: 10, y: 20 };
183
+ const target: Point = { x: 50, y: 80 };
184
+
185
+ const direction = PointCal.unitVectorFromA2B(current, target);
186
+ const speed = 5;
187
+
188
+ // Move toward target
189
+ const newPosition = PointCal.addVector(
190
+ current,
191
+ PointCal.multiplyVectorByScalar(direction, speed)
192
+ );
193
+ ```
194
+
195
+ ### Smooth Interpolation
196
+
197
+ ```typescript
198
+ import { PointCal, Point } from '@ue-too/math';
199
+
200
+ // Animate between two positions
201
+ const start: Point = { x: 0, y: 0 };
202
+ const end: Point = { x: 100, y: 100 };
203
+ const progress = 0.3; // 30% through animation
204
+
205
+ const currentPos = PointCal.linearInterpolation(start, end, progress);
206
+ ```
207
+
208
+ ## API Reference
209
+
210
+ For complete API documentation with detailed examples, see:
211
+ - [Full TypeDoc Documentation](../../docs/math) (generated from source)
212
+ - [Source Code](./src/index.ts) with inline JSDoc comments
213
+
214
+ ## TypeScript Support
215
+
216
+ This package is written in TypeScript and includes full type definitions:
217
+
218
+ ```typescript
219
+ import { Point, PointCal } from '@ue-too/math';
220
+
221
+ const point: Point = { x: 10, y: 20 }; // z is optional
222
+ const point3d: Point = { x: 10, y: 20, z: 30 };
223
+ ```
224
+
225
+ ## Performance Considerations
226
+
227
+ - All operations are pure functions with no side effects
228
+ - Static methods minimize object allocation overhead
229
+ - Suitable for tight animation loops (60fps)
230
+ - For performance-critical code, consider using the operations directly rather than chaining
231
+
232
+ ### Performance Tips
233
+
234
+ ```typescript
235
+ // ✅ Good: Single operation
236
+ const mag = PointCal.magnitude(vector);
237
+
238
+ // ⚠️ Less optimal: Multiple magnitude calls
239
+ const unit = PointCal.unitVector(vector); // Calls magnitude twice internally
240
+
241
+ // ✅ Better: Calculate magnitude once if needed separately
242
+ const mag = PointCal.magnitude(vector);
243
+ const unit = PointCal.divideVectorByScalar(vector, mag);
244
+ ```
245
+
246
+ ## Related Packages
247
+
248
+ - [`@ue-too/board`](../board) - Canvas viewport management with pan, zoom, rotate
249
+ - [`@ue-too/animate`](../animate) - Animation system using these math utilities
250
+ - [`@ue-too/dynamics`](../dynamics) - Physics engine built on these operations
251
+
252
+ ## License
253
+
254
+ MIT License - see [LICENSE.txt](../../LICENSE.txt) for details.
255
+
256
+ ## Contributing
257
+
258
+ > Currently not accepting contributions. If you have feature requests or bug reports, please [create an issue](https://github.com/ue-too/ue-too/issues).
package/index.d.ts CHANGED
@@ -1,34 +1,533 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * Mathematical utilities for 2D and 3D point operations, vector calculations, and transformations.
4
+ *
5
+ * @remarks
6
+ * This package provides essential mathematical operations for canvas applications including:
7
+ * - Vector arithmetic (add, subtract, multiply, divide)
8
+ * - Vector operations (dot product, cross product, magnitude, unit vectors)
9
+ * - Geometric transformations (rotation, axis transformation)
10
+ * - Angle calculations and normalization
11
+ * - Point comparisons and interpolation
12
+ * - Line intersection detection
13
+ *
14
+ * All operations support both 2D and 3D coordinates, with the z-axis being optional.
15
+ *
16
+ * @example
17
+ * Basic vector operations
18
+ * ```typescript
19
+ * import { PointCal, Point } from '@ue-too/math';
20
+ *
21
+ * const a: Point = { x: 1, y: 2 };
22
+ * const b: Point = { x: 3, y: 4 };
23
+ *
24
+ * // Add vectors
25
+ * const sum = PointCal.addVector(a, b); // { x: 4, y: 6 }
26
+ *
27
+ * // Calculate magnitude
28
+ * const mag = PointCal.magnitude(a); // 2.236...
29
+ *
30
+ * // Get unit vector
31
+ * const unit = PointCal.unitVector(a); // { x: 0.447..., y: 0.894... }
32
+ * ```
33
+ *
34
+ * @example
35
+ * Rotation and transformation
36
+ * ```typescript
37
+ * import { PointCal, Point } from '@ue-too/math';
38
+ *
39
+ * const point: Point = { x: 10, y: 0 };
40
+ * const angle = Math.PI / 2; // 90 degrees
41
+ *
42
+ * // Rotate point around origin
43
+ * const rotated = PointCal.rotatePoint(point, angle); // { x: 0, y: 10 }
44
+ *
45
+ * // Rotate around a custom anchor
46
+ * const anchor: Point = { x: 5, y: 5 };
47
+ * const rotatedAroundAnchor = PointCal.transformPointWRTAnchor(point, anchor, angle);
48
+ * ```
49
+ */
50
+ /**
51
+ * Represents a 2D or 3D point with optional z-coordinate.
52
+ *
53
+ * @remarks
54
+ * This is a lowercase variant maintained for backward compatibility.
55
+ * Use {@link Point} for new code.
56
+ *
57
+ * @deprecated Use {@link Point} instead for better TypeScript conventions.
58
+ */
1
59
  export type point = {
60
+ /** X-coordinate */
2
61
  x: number;
62
+ /** Y-coordinate */
3
63
  y: number;
64
+ /** Optional Z-coordinate for 3D operations */
4
65
  z?: number;
5
66
  };
67
+ /**
68
+ * Represents a 2D or 3D point with optional z-coordinate.
69
+ *
70
+ * @remarks
71
+ * When z is undefined, operations treat the point as 2D (z = 0).
72
+ * This type is used throughout the library for all point and vector operations.
73
+ *
74
+ * @example
75
+ * ```typescript
76
+ * // 2D point
77
+ * const p2d: Point = { x: 10, y: 20 };
78
+ *
79
+ * // 3D point
80
+ * const p3d: Point = { x: 10, y: 20, z: 30 };
81
+ * ```
82
+ */
6
83
  export type Point = {
84
+ /** X-coordinate */
7
85
  x: number;
86
+ /** Y-coordinate */
8
87
  y: number;
88
+ /** Optional Z-coordinate for 3D operations */
9
89
  z?: number;
10
90
  };
91
+ /**
92
+ * Utility class for point and vector calculations.
93
+ *
94
+ * @remarks
95
+ * PointCal provides static methods for common 2D and 3D mathematical operations
96
+ * used in canvas applications. All methods handle both 2D and 3D coordinates seamlessly.
97
+ *
98
+ * @example
99
+ * ```typescript
100
+ * import { PointCal, Point } from '@ue-too/math';
101
+ *
102
+ * const v1: Point = { x: 1, y: 2 };
103
+ * const v2: Point = { x: 3, y: 4 };
104
+ *
105
+ * const sum = PointCal.addVector(v1, v2);
106
+ * const dot = PointCal.dotProduct(v1, v2);
107
+ * ```
108
+ */
11
109
  export declare class PointCal {
110
+ /**
111
+ * Adds two vectors together.
112
+ *
113
+ * @param a - First vector
114
+ * @param b - Second vector
115
+ * @returns The sum of vectors a and b
116
+ *
117
+ * @remarks
118
+ * If either vector lacks a z-coordinate, it's treated as 0.
119
+ * The result will include a z-coordinate if either input has one.
120
+ *
121
+ * @example
122
+ * ```typescript
123
+ * const a = { x: 1, y: 2 };
124
+ * const b = { x: 3, y: 4 };
125
+ * const sum = PointCal.addVector(a, b); // { x: 4, y: 6 }
126
+ *
127
+ * // With 3D coordinates
128
+ * const a3d = { x: 1, y: 2, z: 3 };
129
+ * const b3d = { x: 4, y: 5, z: 6 };
130
+ * const sum3d = PointCal.addVector(a3d, b3d); // { x: 5, y: 7, z: 9 }
131
+ * ```
132
+ *
133
+ * @group Vector Arithmetic
134
+ */
12
135
  static addVector(a: point, b: point): Point;
136
+ /**
137
+ * Subtracts vector b from vector a.
138
+ *
139
+ * @param a - Vector to subtract from
140
+ * @param b - Vector to subtract
141
+ * @returns The difference (a - b)
142
+ *
143
+ * @remarks
144
+ * If either vector lacks a z-coordinate, it's treated as 0.
145
+ *
146
+ * @example
147
+ * ```typescript
148
+ * const a = { x: 5, y: 7 };
149
+ * const b = { x: 2, y: 3 };
150
+ * const diff = PointCal.subVector(a, b); // { x: 3, y: 4 }
151
+ * ```
152
+ *
153
+ * @group Vector Arithmetic
154
+ */
13
155
  static subVector(a: point, b: point): Point;
156
+ /**
157
+ * Multiplies a vector by a scalar value.
158
+ *
159
+ * @param a - Vector to multiply
160
+ * @param b - Scalar multiplier
161
+ * @returns The scaled vector
162
+ *
163
+ * @example
164
+ * ```typescript
165
+ * const v = { x: 2, y: 3 };
166
+ * const scaled = PointCal.multiplyVectorByScalar(v, 2.5); // { x: 5, y: 7.5 }
167
+ * ```
168
+ *
169
+ * @group Vector Arithmetic
170
+ */
14
171
  static multiplyVectorByScalar(a: point, b: number): Point;
172
+ /**
173
+ * Divides a vector by a scalar value.
174
+ *
175
+ * @param a - Vector to divide
176
+ * @param b - Scalar divisor
177
+ * @returns The divided vector, or the original vector if b is 0
178
+ *
179
+ * @remarks
180
+ * Division by zero returns the original vector unchanged to prevent NaN values.
181
+ *
182
+ * @example
183
+ * ```typescript
184
+ * const v = { x: 10, y: 20 };
185
+ * const divided = PointCal.divideVectorByScalar(v, 2); // { x: 5, y: 10 }
186
+ * ```
187
+ *
188
+ * @group Vector Arithmetic
189
+ */
15
190
  static divideVectorByScalar(a: point, b: number): Point;
191
+ /**
192
+ * Calculates the magnitude (length) of a vector.
193
+ *
194
+ * @param a - Vector to measure
195
+ * @returns The magnitude of the vector
196
+ *
197
+ * @remarks
198
+ * Uses the Euclidean distance formula: √(x² + y² + z²)
199
+ *
200
+ * @example
201
+ * ```typescript
202
+ * const v = { x: 3, y: 4 };
203
+ * const mag = PointCal.magnitude(v); // 5
204
+ *
205
+ * const v3d = { x: 1, y: 2, z: 2 };
206
+ * const mag3d = PointCal.magnitude(v3d); // 3
207
+ * ```
208
+ *
209
+ * @group Vector Operations
210
+ */
16
211
  static magnitude(a: point): number;
212
+ /**
213
+ * Converts a vector to its unit vector (normalized to length 1).
214
+ *
215
+ * @param a - Vector to normalize
216
+ * @returns Unit vector in the same direction, or zero vector if magnitude is 0
217
+ *
218
+ * @remarks
219
+ * A unit vector has magnitude 1 and preserves the original direction.
220
+ * Returns {x: 0, y: 0, z: 0} if the input vector has zero magnitude.
221
+ *
222
+ * **Performance note**: This method calls `magnitude()` twice. For better performance
223
+ * when you need both magnitude and unit vector, calculate magnitude once and divide manually.
224
+ *
225
+ * @example
226
+ * ```typescript
227
+ * const v = { x: 3, y: 4 };
228
+ * const unit = PointCal.unitVector(v); // { x: 0.6, y: 0.8 }
229
+ * ```
230
+ *
231
+ * @group Vector Operations
232
+ */
17
233
  static unitVector(a: point): Point;
234
+ /**
235
+ * Calculates the dot product of two vectors.
236
+ *
237
+ * @param a - First vector
238
+ * @param b - Second vector
239
+ * @returns The dot product (scalar value)
240
+ *
241
+ * @remarks
242
+ * The dot product is: a.x * b.x + a.y * b.y + a.z * b.z
243
+ *
244
+ * **Use cases:**
245
+ * - Determine if vectors are perpendicular (dot = 0)
246
+ * - Calculate angle between vectors: θ = acos(dot / (|a| * |b|))
247
+ * - Project one vector onto another
248
+ *
249
+ * @example
250
+ * ```typescript
251
+ * const a = { x: 1, y: 0 };
252
+ * const b = { x: 0, y: 1 };
253
+ * const dot = PointCal.dotProduct(a, b); // 0 (perpendicular vectors)
254
+ *
255
+ * const c = { x: 2, y: 3 };
256
+ * const d = { x: 4, y: 5 };
257
+ * const dot2 = PointCal.dotProduct(c, d); // 23
258
+ * ```
259
+ *
260
+ * @group Vector Operations
261
+ */
18
262
  static dotProduct(a: point, b: point): number;
263
+ /**
264
+ * Calculates the cross product of two vectors.
265
+ *
266
+ * @param a - First vector
267
+ * @param b - Second vector
268
+ * @returns The cross product vector perpendicular to both inputs
269
+ *
270
+ * @remarks
271
+ * The cross product is perpendicular to both input vectors, following the right-hand rule.
272
+ * For 2D vectors (z undefined), z is treated as 0.
273
+ *
274
+ * **Properties:**
275
+ * - Result is perpendicular to both input vectors
276
+ * - Magnitude equals area of parallelogram formed by vectors
277
+ * - Direction follows right-hand rule
278
+ *
279
+ * @example
280
+ * ```typescript
281
+ * const a = { x: 1, y: 0, z: 0 };
282
+ * const b = { x: 0, y: 1, z: 0 };
283
+ * const cross = PointCal.crossProduct(a, b); // { x: 0, y: 0, z: 1 }
284
+ * ```
285
+ *
286
+ * @group Vector Operations
287
+ */
19
288
  static crossProduct(a: point, b: point): Point;
289
+ /**
290
+ * Calculates the unit vector pointing from point a to point b.
291
+ *
292
+ * @param a - Starting point
293
+ * @param b - Ending point
294
+ * @returns Unit vector in the direction from a to b
295
+ *
296
+ * @remarks
297
+ * Equivalent to calling unitVector(subVector(b, a))
298
+ *
299
+ * @example
300
+ * ```typescript
301
+ * const a = { x: 0, y: 0 };
302
+ * const b = { x: 3, y: 4 };
303
+ * const direction = PointCal.unitVectorFromA2B(a, b); // { x: 0.6, y: 0.8 }
304
+ * ```
305
+ *
306
+ * @group Geometric Calculations
307
+ */
20
308
  static unitVectorFromA2B(a: point, b: point): Point;
309
+ /**
310
+ * Rotates a point around the origin.
311
+ *
312
+ * @param point - Point to rotate
313
+ * @param angle - Rotation angle in radians (counter-clockwise)
314
+ * @returns Rotated point
315
+ *
316
+ * @remarks
317
+ * Rotation is performed around the origin (0, 0).
318
+ * Positive angles rotate counter-clockwise, negative angles rotate clockwise.
319
+ * For rotation around a custom anchor, use {@link transformPointWRTAnchor}.
320
+ *
321
+ * **Performance**: Uses trigonometric functions (sin/cos). For many rotations with
322
+ * the same angle, pre-calculate sin/cos values and apply the transformation manually.
323
+ *
324
+ * @example
325
+ * ```typescript
326
+ * const point = { x: 1, y: 0 };
327
+ * const rotated = PointCal.rotatePoint(point, Math.PI / 2); // { x: 0, y: 1 }
328
+ * ```
329
+ *
330
+ * @group Transformations
331
+ */
21
332
  static rotatePoint(point: point, angle: number): Point;
333
+ /**
334
+ * Transforms a point's coordinates to a new rotated axis system.
335
+ *
336
+ * @param point - Point in original coordinate system
337
+ * @param angleFromOriginalAxis2DestAxis - Rotation angle from original to destination axis (radians, CCW positive)
338
+ * @returns Point coordinates in the new axis system
339
+ *
340
+ * @remarks
341
+ * This performs an axis rotation transformation, converting coordinates from one
342
+ * reference frame to another rotated by the specified angle.
343
+ *
344
+ * @example
345
+ * ```typescript
346
+ * const point = { x: 10, y: 0 };
347
+ * const angle = Math.PI / 4; // 45 degrees
348
+ * const transformed = PointCal.transform2NewAxis(point, angle);
349
+ * ```
350
+ *
351
+ * @group Transformations
352
+ */
22
353
  static transform2NewAxis(point: point, angleFromOriginalAxis2DestAxis: number): Point;
23
354
  /**
24
- * @description Gets the angle from vector a to vector b. (returned angle is always between -π to π)
355
+ * Calculates the signed angle from vector a to vector b.
356
+ *
357
+ * @param a - First vector (starting direction)
358
+ * @param b - Second vector (ending direction)
359
+ * @returns The signed angle in radians, range: (-π, π]
360
+ *
361
+ * @remarks
362
+ * - Positive angles indicate counter-clockwise rotation from a to b
363
+ * - Negative angles indicate clockwise rotation from a to b
364
+ * - Uses atan2 for proper quadrant handling
365
+ *
366
+ * @example
367
+ * ```typescript
368
+ * const right = { x: 1, y: 0 };
369
+ * const up = { x: 0, y: 1 };
370
+ * const angle = PointCal.angleFromA2B(right, up); // π/2 (90 degrees CCW)
371
+ *
372
+ * const down = { x: 0, y: -1 };
373
+ * const angleDown = PointCal.angleFromA2B(right, down); // -π/2 (90 degrees CW)
374
+ * ```
375
+ *
376
+ * @group Angle Utilities
25
377
  */
26
378
  static angleFromA2B(a: point, b: point): number;
379
+ /**
380
+ * Rotates a point around a custom anchor point.
381
+ *
382
+ * @param point - Point to rotate
383
+ * @param anchor - Anchor point to rotate around
384
+ * @param angle - Rotation angle in radians (counter-clockwise)
385
+ * @returns Rotated point
386
+ *
387
+ * @remarks
388
+ * This is equivalent to:
389
+ * 1. Translate point by -anchor
390
+ * 2. Rotate around origin
391
+ * 3. Translate back by +anchor
392
+ *
393
+ * @example
394
+ * ```typescript
395
+ * const point = { x: 10, y: 5 };
396
+ * const anchor = { x: 5, y: 5 };
397
+ * const angle = Math.PI / 2; // 90 degrees
398
+ * const rotated = PointCal.transformPointWRTAnchor(point, anchor, angle);
399
+ * // Rotates point around anchor (5, 5)
400
+ * ```
401
+ *
402
+ * @group Transformations
403
+ */
27
404
  static transformPointWRTAnchor(point: point, anchor: point, angle: number): Point;
405
+ /**
406
+ * Calculates the Euclidean distance between two points.
407
+ *
408
+ * @param a - First point
409
+ * @param b - Second point
410
+ * @returns The distance between the two points
411
+ *
412
+ * @remarks
413
+ * Equivalent to calculating the magnitude of the vector from a to b.
414
+ *
415
+ * @example
416
+ * ```typescript
417
+ * const a = { x: 0, y: 0 };
418
+ * const b = { x: 3, y: 4 };
419
+ * const distance = PointCal.distanceBetweenPoints(a, b); // 5
420
+ * ```
421
+ *
422
+ * @group Geometric Calculations
423
+ */
28
424
  static distanceBetweenPoints(a: point, b: point): number;
425
+ /**
426
+ * Flips a point's y-coordinate (mirrors across the x-axis).
427
+ *
428
+ * @param point - Point to flip
429
+ * @returns Point with negated y-coordinate
430
+ *
431
+ * @remarks
432
+ * Useful for converting between coordinate systems where the y-axis direction differs.
433
+ * Common when converting between screen coordinates (y-down) and mathematical coordinates (y-up).
434
+ *
435
+ * @example
436
+ * ```typescript
437
+ * const point = { x: 10, y: 20 };
438
+ * const flipped = PointCal.flipYAxis(point); // { x: 10, y: -20 }
439
+ * ```
440
+ *
441
+ * @group Transformations
442
+ */
29
443
  static flipYAxis(point: point): Point;
444
+ /**
445
+ * Performs linear interpolation between two points.
446
+ *
447
+ * @param a - Starting point (t = 0)
448
+ * @param b - Ending point (t = 1)
449
+ * @param t - Interpolation parameter (0 to 1)
450
+ * @returns Interpolated point
451
+ *
452
+ * @remarks
453
+ * - t = 0 returns point a
454
+ * - t = 1 returns point b
455
+ * - t = 0.5 returns the midpoint
456
+ * - Values outside [0, 1] perform extrapolation
457
+ *
458
+ * **Performance**: Suitable for animation loops and real-time interpolation.
459
+ *
460
+ * @example
461
+ * ```typescript
462
+ * const a = { x: 0, y: 0 };
463
+ * const b = { x: 10, y: 20 };
464
+ * const mid = PointCal.linearInterpolation(a, b, 0.5); // { x: 5, y: 10 }
465
+ * const quarter = PointCal.linearInterpolation(a, b, 0.25); // { x: 2.5, y: 5 }
466
+ * ```
467
+ *
468
+ * @group Geometric Calculations
469
+ */
30
470
  static linearInterpolation(a: point, b: point, t: number): point;
471
+ /**
472
+ * Checks if two points are exactly equal.
473
+ *
474
+ * @param a - First point
475
+ * @param b - Second point
476
+ * @returns True if all coordinates are exactly equal
477
+ *
478
+ * @remarks
479
+ * Uses strict equality (===) for comparison.
480
+ * For approximate equality with tolerance, use {@link samePoint} instead.
481
+ * Missing z-coordinates are treated as 0.
482
+ *
483
+ * @example
484
+ * ```typescript
485
+ * const a = { x: 1, y: 2 };
486
+ * const b = { x: 1, y: 2 };
487
+ * PointCal.isEqual(a, b); // true
488
+ *
489
+ * const c = { x: 1.0000001, y: 2 };
490
+ * PointCal.isEqual(a, c); // false (use samePoint for tolerance)
491
+ * ```
492
+ *
493
+ * @group Geometric Calculations
494
+ */
31
495
  static isEqual(a: point, b: point): boolean;
496
+ /**
497
+ * Calculates the intersection point of two line segments.
498
+ *
499
+ * @param startPoint - Start of first line segment
500
+ * @param endPoint - End of first line segment
501
+ * @param startPoint2 - Start of second line segment
502
+ * @param endPoint2 - End of second line segment
503
+ * @returns Object containing intersection status and details
504
+ *
505
+ * @remarks
506
+ * Returns an object with:
507
+ * - `intersects`: Boolean indicating if segments intersect
508
+ * - `intersection`: The intersection point (only if intersects is true)
509
+ * - `offset`: Parameter t where intersection occurs on first segment (0 to 1)
510
+ *
511
+ * The segments must actually cross within their bounds (not just their infinite extensions).
512
+ *
513
+ * **Use cases:**
514
+ * - Collision detection between line segments
515
+ * - Ray casting and visibility checks
516
+ * - Path intersection detection
517
+ *
518
+ * @example
519
+ * ```typescript
520
+ * const line1Start = { x: 0, y: 0 };
521
+ * const line1End = { x: 10, y: 10 };
522
+ * const line2Start = { x: 0, y: 10 };
523
+ * const line2End = { x: 10, y: 0 };
524
+ *
525
+ * const result = PointCal.getLineIntersection(line1Start, line1End, line2Start, line2End);
526
+ * // { intersects: true, intersection: { x: 5, y: 5 }, offset: 0.5 }
527
+ * ```
528
+ *
529
+ * @group Geometric Calculations
530
+ */
32
531
  static getLineIntersection(startPoint: Point, endPoint: Point, startPoint2: Point, endPoint2: Point): {
33
532
  intersects: boolean;
34
533
  intersection?: Point;
@@ -36,18 +535,143 @@ export declare class PointCal {
36
535
  };
37
536
  }
38
537
  /**
39
- * @description Normalizes the angle to be between 0 and 2π.
538
+ * Normalizes an angle to the range [0, 2π).
539
+ *
540
+ * @param angle - Angle in radians (can be any value)
541
+ * @returns Normalized angle between 0 and 2π
542
+ *
543
+ * @remarks
544
+ * This function wraps any angle to the range [0, 2π) by taking the modulo
545
+ * and ensuring the result is positive.
40
546
  *
41
- * @category Camera
547
+ * @example
548
+ * ```typescript
549
+ * normalizeAngleZero2TwoPI(Math.PI * 3); // π (180 degrees)
550
+ * normalizeAngleZero2TwoPI(-Math.PI / 2); // 3π/2 (270 degrees)
551
+ * normalizeAngleZero2TwoPI(0); // 0
552
+ * ```
553
+ *
554
+ * @category Angle
42
555
  */
43
556
  export declare function normalizeAngleZero2TwoPI(angle: number): number;
44
557
  /**
45
- * @description Gets the smaller angle span between two angles. (in radians)
558
+ * Calculates the smallest angular difference between two angles.
559
+ *
560
+ * @param from - Starting angle in radians
561
+ * @param to - Ending angle in radians
562
+ * @returns The smallest angle span from 'from' to 'to', in range (-π, π]
563
+ *
564
+ * @remarks
565
+ * This function accounts for wrapping around 2π and always returns the shorter path.
566
+ * Positive result means counter-clockwise rotation, negative means clockwise.
46
567
  *
47
- * @category Camera
568
+ * @example
569
+ * ```typescript
570
+ * // From 0° to 90°
571
+ * angleSpan(0, Math.PI / 2); // π/2 (90 degrees CCW)
572
+ *
573
+ * // From 350° to 10° (shorter to go CCW through 0°)
574
+ * angleSpan(350 * Math.PI / 180, 10 * Math.PI / 180); // ≈ 20 degrees
575
+ *
576
+ * // From 10° to 350° (shorter to go CW through 0°)
577
+ * angleSpan(10 * Math.PI / 180, 350 * Math.PI / 180); // ≈ -20 degrees
578
+ * ```
579
+ *
580
+ * @category Angle
48
581
  */
49
582
  export declare function angleSpan(from: number, to: number): number;
583
+ /**
584
+ * Checks if two numbers are approximately equal within a tolerance.
585
+ *
586
+ * @param a - First number
587
+ * @param b - Second number
588
+ * @param precision - Optional tolerance (defaults to 0.000001)
589
+ * @returns True if the absolute difference is within the precision threshold
590
+ *
591
+ * @remarks
592
+ * Useful for floating-point comparisons where exact equality is unreliable.
593
+ *
594
+ * @example
595
+ * ```typescript
596
+ * approximatelyTheSame(1.0, 1.0000001); // true (within default epsilon)
597
+ * approximatelyTheSame(1.0, 1.1); // false
598
+ * approximatelyTheSame(1.0, 1.01, 0.02); // true (within custom precision)
599
+ * ```
600
+ *
601
+ * @category Comparison
602
+ */
50
603
  export declare function approximatelyTheSame(a: number, b: number, precision?: number): boolean;
604
+ /**
605
+ * Checks if two vectors point in the same direction.
606
+ *
607
+ * @param a - First vector
608
+ * @param b - Second vector
609
+ * @param precision - Tolerance for comparison (defaults to 0.001)
610
+ * @returns True if vectors have the same direction (after normalization)
611
+ *
612
+ * @remarks
613
+ * Normalizes both vectors to unit vectors and compares them.
614
+ * Magnitude does not matter, only direction.
615
+ *
616
+ * @example
617
+ * ```typescript
618
+ * const a = { x: 1, y: 0 };
619
+ * const b = { x: 10, y: 0 }; // Same direction, different magnitude
620
+ * sameDirection(a, b); // true
621
+ *
622
+ * const c = { x: 1, y: 1 };
623
+ * sameDirection(a, c); // false (different direction)
624
+ * ```
625
+ *
626
+ * @category Comparison
627
+ */
51
628
  export declare function sameDirection(a: Point, b: Point, precision?: number): boolean;
629
+ /**
630
+ * Checks if a direction vector is aligned with a tangent vector.
631
+ *
632
+ * @param direction - Direction vector to check
633
+ * @param tangent - Tangent vector reference
634
+ * @returns True if direction aligns with tangent (within 90 degrees)
635
+ *
636
+ * @remarks
637
+ * Returns true if the direction is within 90 degrees of either the tangent
638
+ * or its reverse. Useful for determining if movement is along a path.
639
+ *
640
+ * @example
641
+ * ```typescript
642
+ * const direction = { x: 1, y: 0 };
643
+ * const tangent = { x: 1, y: 0.1 }; // Slightly rotated
644
+ * directionAlignedToTangent(direction, tangent); // true
645
+ *
646
+ * const perpendicular = { x: 0, y: 1 };
647
+ * directionAlignedToTangent(perpendicular, tangent); // false
648
+ * ```
649
+ *
650
+ * @category Comparison
651
+ */
52
652
  export declare function directionAlignedToTangent(direction: Point, tangent: Point): boolean;
653
+ /**
654
+ * Checks if two points are approximately at the same location.
655
+ *
656
+ * @param a - First point
657
+ * @param b - Second point
658
+ * @param precision - Optional tolerance for coordinate comparison
659
+ * @returns True if both x and y coordinates are within precision
660
+ *
661
+ * @remarks
662
+ * Uses {@link approximatelyTheSame} for coordinate comparison.
663
+ * For exact equality, use {@link PointCal.isEqual} instead.
664
+ *
665
+ * @example
666
+ * ```typescript
667
+ * const a = { x: 1.0, y: 2.0 };
668
+ * const b = { x: 1.0000001, y: 2.0000001 };
669
+ * samePoint(a, b); // true (within default precision)
670
+ *
671
+ * const c = { x: 1.1, y: 2.0 };
672
+ * samePoint(a, c); // false
673
+ * ```
674
+ *
675
+ * @category Comparison
676
+ */
53
677
  export declare function samePoint(a: Point, b: Point, precision?: number): boolean;
package/index.js CHANGED
@@ -1,175 +1,3 @@
1
- // src/index.ts
2
- class PointCal {
3
- static addVector(a, b) {
4
- if (a.z == null && b.z == null)
5
- return { x: a.x + b.x, y: a.y + b.y };
6
- if (a.z == null || b.z == null) {
7
- if (a.z == null)
8
- a.z = 0;
9
- if (b.z == null)
10
- b.z = 0;
11
- }
12
- return { x: a.x + b.x, y: a.y + b.y, z: a.z + b.z };
13
- }
14
- static subVector(a, b) {
15
- if (a.z == null && b.z == null)
16
- return { x: a.x - b.x, y: a.y - b.y };
17
- if (a.z == null || b.z == null) {
18
- if (a.z == null)
19
- a.z = 0;
20
- if (b.z == null)
21
- b.z = 0;
22
- }
23
- return { x: a.x - b.x, y: a.y - b.y, z: a.z - b.z };
24
- }
25
- static multiplyVectorByScalar(a, b) {
26
- if (a.z == null)
27
- return { x: a.x * b, y: a.y * b };
28
- return { x: a.x * b, y: a.y * b, z: a.z * b };
29
- }
30
- static divideVectorByScalar(a, b) {
31
- if (b == 0)
32
- return { x: a.x, y: a.y };
33
- if (a.z == null)
34
- return { x: a.x / b, y: a.y / b };
35
- return { x: a.x / b, y: a.y / b, z: a.z / b };
36
- }
37
- static magnitude(a) {
38
- if (a.z == null)
39
- a.z = 0;
40
- return Math.sqrt(a.x * a.x + a.y * a.y + a.z * a.z);
41
- }
42
- static unitVector(a) {
43
- if (a.z == null)
44
- a.z = 0;
45
- return this.magnitude(a) != 0 ? { x: a.x / this.magnitude(a), y: a.y / this.magnitude(a), z: a.z / this.magnitude(a) } : { x: 0, y: 0, z: 0 };
46
- }
47
- static dotProduct(a, b) {
48
- if (a.z == null && b.z == null)
49
- return a.x * b.x + a.y * b.y;
50
- if (a.z == null || b.z == null) {
51
- if (a.z == null)
52
- a.z = 0;
53
- if (b.z == null)
54
- b.z = 0;
55
- }
56
- return a.x * b.x + a.y * b.y + a.z * b.z;
57
- }
58
- static crossProduct(a, b) {
59
- if (a.z == null || b.z == null) {
60
- if (a.z == null)
61
- a.z = 0;
62
- if (b.z == null)
63
- b.z = 0;
64
- }
65
- return { x: a.y * b.z - a.z * b.y, y: a.z * b.x - a.x * b.z, z: a.x * b.y - a.y * b.x };
66
- }
67
- static unitVectorFromA2B(a, b) {
68
- return this.unitVector(this.subVector(b, a));
69
- }
70
- static rotatePoint(point, angle) {
71
- return { x: point.x * Math.cos(angle) - point.y * Math.sin(angle), y: point.x * Math.sin(angle) + point.y * Math.cos(angle) };
72
- }
73
- static transform2NewAxis(point, angleFromOriginalAxis2DestAxis) {
74
- return { x: point.x * Math.cos(angleFromOriginalAxis2DestAxis) + point.y * Math.sin(angleFromOriginalAxis2DestAxis), y: -point.x * Math.sin(angleFromOriginalAxis2DestAxis) + point.y * Math.cos(angleFromOriginalAxis2DestAxis) };
75
- }
76
- static angleFromA2B(a, b) {
77
- return Math.atan2(a.x * b.y - a.y * b.x, a.x * b.x + a.y * b.y);
78
- }
79
- static transformPointWRTAnchor(point, anchor, angle) {
80
- let newPoint = this.rotatePoint(this.subVector(point, anchor), angle);
81
- return this.addVector(newPoint, anchor);
82
- }
83
- static distanceBetweenPoints(a, b) {
84
- return this.magnitude(this.subVector(a, b));
85
- }
86
- static flipYAxis(point) {
87
- return { x: point.x, y: -point.y, z: point.z };
88
- }
89
- static linearInterpolation(a, b, t) {
90
- if (a.z == null || b.z == null) {
91
- return { x: a.x + (b.x - a.x) * t, y: a.y + (b.y - a.y) * t };
92
- } else {
93
- return { x: a.x + (b.x - a.x) * t, y: a.y + (b.y - a.y) * t, z: a.z + (b.z - a.z) * t };
94
- }
95
- }
96
- static isEqual(a, b) {
97
- if (a.z == null) {
98
- a.z = 0;
99
- }
100
- if (b.z == null) {
101
- b.z = 0;
102
- }
103
- return a.x == b.x && a.y == b.y && a.z == b.z;
104
- }
105
- static getLineIntersection(startPoint, endPoint, startPoint2, endPoint2) {
106
- const numerator = (endPoint2.x - startPoint2.x) * (startPoint.y - startPoint2.y) - (endPoint2.y - startPoint2.y) * (startPoint.x - startPoint2.x);
107
- const denominator = (endPoint2.y - startPoint2.y) * (endPoint.x - startPoint.x) - (endPoint2.x - startPoint2.x) * (endPoint.y - startPoint.y);
108
- if (denominator === 0) {
109
- return { intersects: false };
110
- }
111
- const t = numerator / denominator;
112
- if (t >= 0 && t <= 1) {
113
- return {
114
- intersects: true,
115
- intersection: PointCal.linearInterpolation(startPoint, endPoint, t),
116
- offset: t
117
- };
118
- } else {
119
- return {
120
- intersects: false
121
- };
122
- }
123
- }
124
- }
125
- function normalizeAngleZero2TwoPI(angle) {
126
- angle = angle % (Math.PI * 2);
127
- angle = (angle + Math.PI * 2) % (Math.PI * 2);
128
- return angle;
129
- }
130
- function angleSpan(from, to) {
131
- from = normalizeAngleZero2TwoPI(from);
132
- to = normalizeAngleZero2TwoPI(to);
133
- let angleDiff = to - from;
134
- if (angleDiff > Math.PI) {
135
- angleDiff = -(Math.PI * 2 - angleDiff);
136
- }
137
- if (angleDiff < -Math.PI) {
138
- angleDiff += Math.PI * 2;
139
- }
140
- return angleDiff;
141
- }
142
- function approximatelyTheSame(a, b, precision) {
143
- const epsilon = 0.000001;
144
- return Math.abs(a - b) <= (precision || epsilon);
145
- }
146
- function sameDirection(a, b, precision = 0.001) {
147
- const aNormalized = PointCal.unitVector(a);
148
- const bNormalized = PointCal.unitVector(b);
149
- return samePoint(aNormalized, bNormalized, precision);
150
- }
151
- function directionAlignedToTangent(direction, tangent) {
152
- const directionNormalized = PointCal.unitVector(direction);
153
- const tangentNormalized = PointCal.unitVector(tangent);
154
- const reversedTangent = { x: -tangent.x, y: -tangent.y, z: tangent.z };
155
- const angle = PointCal.angleFromA2B(directionNormalized, tangentNormalized);
156
- const angle2 = PointCal.angleFromA2B(directionNormalized, reversedTangent);
157
- return angle < Math.PI / 2 && angle > -Math.PI / 2 && (angle2 > Math.PI / 2 || angle2 < -Math.PI / 2);
158
- }
159
- function samePoint(a, b, precision) {
160
- if (approximatelyTheSame(a.x, b.x, precision) && approximatelyTheSame(a.y, b.y, precision)) {
161
- return true;
162
- }
163
- return false;
164
- }
165
- export {
166
- samePoint,
167
- sameDirection,
168
- normalizeAngleZero2TwoPI,
169
- directionAlignedToTangent,
170
- approximatelyTheSame,
171
- angleSpan,
172
- PointCal
173
- };
1
+ class J{static addVector(j,B){if(j.z==null&&B.z==null)return{x:j.x+B.x,y:j.y+B.y};if(j.z==null||B.z==null){if(j.z==null)j.z=0;if(B.z==null)B.z=0}return{x:j.x+B.x,y:j.y+B.y,z:j.z+B.z}}static subVector(j,B){if(j.z==null&&B.z==null)return{x:j.x-B.x,y:j.y-B.y};if(j.z==null||B.z==null){if(j.z==null)j.z=0;if(B.z==null)B.z=0}return{x:j.x-B.x,y:j.y-B.y,z:j.z-B.z}}static multiplyVectorByScalar(j,B){if(j.z==null)return{x:j.x*B,y:j.y*B};return{x:j.x*B,y:j.y*B,z:j.z*B}}static divideVectorByScalar(j,B){if(B==0)return{x:j.x,y:j.y};if(j.z==null)return{x:j.x/B,y:j.y/B};return{x:j.x/B,y:j.y/B,z:j.z/B}}static magnitude(j){if(j.z==null)j.z=0;return Math.sqrt(j.x*j.x+j.y*j.y+j.z*j.z)}static unitVector(j){if(j.z==null)j.z=0;return this.magnitude(j)!=0?{x:j.x/this.magnitude(j),y:j.y/this.magnitude(j),z:j.z/this.magnitude(j)}:{x:0,y:0,z:0}}static dotProduct(j,B){if(j.z==null&&B.z==null)return j.x*B.x+j.y*B.y;if(j.z==null||B.z==null){if(j.z==null)j.z=0;if(B.z==null)B.z=0}return j.x*B.x+j.y*B.y+j.z*B.z}static crossProduct(j,B){if(j.z==null||B.z==null){if(j.z==null)j.z=0;if(B.z==null)B.z=0}return{x:j.y*B.z-j.z*B.y,y:j.z*B.x-j.x*B.z,z:j.x*B.y-j.y*B.x}}static unitVectorFromA2B(j,B){return this.unitVector(this.subVector(B,j))}static rotatePoint(j,B){return{x:j.x*Math.cos(B)-j.y*Math.sin(B),y:j.x*Math.sin(B)+j.y*Math.cos(B)}}static transform2NewAxis(j,B){return{x:j.x*Math.cos(B)+j.y*Math.sin(B),y:-j.x*Math.sin(B)+j.y*Math.cos(B)}}static angleFromA2B(j,B){return Math.atan2(j.x*B.y-j.y*B.x,j.x*B.x+j.y*B.y)}static transformPointWRTAnchor(j,B,G){let H=this.rotatePoint(this.subVector(j,B),G);return this.addVector(H,B)}static distanceBetweenPoints(j,B){return this.magnitude(this.subVector(j,B))}static flipYAxis(j){return{x:j.x,y:-j.y,z:j.z}}static linearInterpolation(j,B,G){if(j.z==null||B.z==null)return{x:j.x+(B.x-j.x)*G,y:j.y+(B.y-j.y)*G};else return{x:j.x+(B.x-j.x)*G,y:j.y+(B.y-j.y)*G,z:j.z+(B.z-j.z)*G}}static isEqual(j,B){if(j.z==null)j.z=0;if(B.z==null)B.z=0;return j.x==B.x&&j.y==B.y&&j.z==B.z}static getLineIntersection(j,B,G,H){let L=(H.x-G.x)*(j.y-G.y)-(H.y-G.y)*(j.x-G.x),M=(H.y-G.y)*(B.x-j.x)-(H.x-G.x)*(B.y-j.y);if(M===0)return{intersects:!1};let K=L/M;if(K>=0&&K<=1)return{intersects:!0,intersection:J.linearInterpolation(j,B,K),offset:K};else return{intersects:!1}}}function Q(j){return j=j%(Math.PI*2),j=(j+Math.PI*2)%(Math.PI*2),j}function W(j,B){j=Q(j),B=Q(B);let G=B-j;if(G>Math.PI)G=-(Math.PI*2-G);if(G<-Math.PI)G+=Math.PI*2;return G}function R(j,B,G){return Math.abs(j-B)<=(G||0.000001)}function X(j,B,G=0.001){let H=J.unitVector(j),L=J.unitVector(B);return V(H,L,G)}function Y(j,B){let G=J.unitVector(j),H=J.unitVector(B),L={x:-B.x,y:-B.y,z:B.z},M=J.angleFromA2B(G,H),K=J.angleFromA2B(G,L);return M<Math.PI/2&&M>-Math.PI/2&&(K>Math.PI/2||K<-Math.PI/2)}function V(j,B,G){if(R(j.x,B.x,G)&&R(j.y,B.y,G))return!0;return!1}export{V as samePoint,X as sameDirection,Q as normalizeAngleZero2TwoPI,Y as directionAlignedToTangent,R as approximatelyTheSame,W as angleSpan,J as PointCal};
174
2
 
175
- //# debugId=B0C116870CD7AAF064756E2164756E21
3
+ //# debugId=E7FBAB931781982464756E2164756E21
package/index.js.map CHANGED
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts"],
4
4
  "sourcesContent": [
5
- "export type point = {\n x: number;\n y: number;\n z?: number;\n}\n\nexport type Point = {\n x: number;\n y: number;\n z?: number;\n}\n\n\nexport class PointCal {\n\n static addVector(a: point, b: point): Point {\n if (a.z == null && b.z == null) return {x: a.x + b.x, y: a.y + b.y};\n if (a.z == null || b.z == null) {\n if (a.z == null) a.z = 0;\n if (b.z == null) b.z = 0;\n }\n return {x: a.x + b.x, y: a.y + b.y, z: a.z + b.z}; \n }\n\n static subVector(a: point, b: point): Point {\n if (a.z == null && b.z == null) return {x: a.x - b.x, y: a.y - b.y};\n if (a.z == null || b.z == null) {\n if (a.z == null) a.z = 0;\n if (b.z == null) b.z = 0;\n }\n return {x: a.x - b.x, y: a.y - b.y, z: a.z - b.z};\n }\n\n static multiplyVectorByScalar(a: point, b: number): Point {\n if (a.z == null) return {x: a.x * b, y: a.y * b};\n return {x: a.x * b, y: a.y * b, z: a.z * b};\n }\n\n static divideVectorByScalar(a: point, b: number): Point {\n if (b == 0) return {x: a.x, y: a.y};\n if (a.z == null) return {x: a.x / b, y: a.y / b};\n return {x: a.x / b, y: a.y / b, z: a.z / b};\n }\n\n static magnitude(a: point): number {\n if (a.z == null) a.z = 0;\n return Math.sqrt(a.x * a.x + a.y * a.y + a.z * a.z);\n }\n\n static unitVector(a: point): Point {\n if (a.z == null) a.z = 0;\n return this.magnitude(a) != 0 ? {x: a.x / this.magnitude(a), y: a.y / this.magnitude(a), z: a.z / this.magnitude(a)} : {x: 0, y: 0, z: 0};\n }\n\n static dotProduct(a: point, b: point): number {\n if (a.z == null && b.z == null) return a.x * b.x + a.y * b.y;\n if (a.z == null || b.z == null) {\n if (a.z == null) a.z = 0;\n if (b.z == null) b.z = 0;\n }\n return a.x * b.x + a.y * b.y + a.z * b.z;\n }\n\n static crossProduct(a: point, b: point): Point {\n if (a.z == null || b.z == null) {\n if (a.z == null) a.z = 0;\n if (b.z == null) b.z = 0;\n }\n return {x: a.y * b.z - a.z * b.y, y: a.z * b.x - a.x * b.z, z: a.x * b.y - a.y * b.x};\n }\n\n static unitVectorFromA2B(a: point, b: point): Point {\n return this.unitVector(this.subVector(b, a));\n }\n\n static rotatePoint(point: point, angle: number): Point {\n return {x: point.x * Math.cos(angle) - point.y * Math.sin(angle), y: point.x * Math.sin(angle) + point.y * Math.cos(angle)};\n }\n\n static transform2NewAxis(point: point, angleFromOriginalAxis2DestAxis: number): Point {\n // angle is the angle from the original axis to the destination axis ccw is positive as always\n return {x: point.x * Math.cos(angleFromOriginalAxis2DestAxis) + point.y * Math.sin(angleFromOriginalAxis2DestAxis), y: -point.x * Math.sin(angleFromOriginalAxis2DestAxis) + point.y * Math.cos(angleFromOriginalAxis2DestAxis)};\n }\n\n /**\n * @description Gets the angle from vector a to vector b. (returned angle is always between -π to π)\n */\n static angleFromA2B(a: point, b: point): number {\n return Math.atan2(a.x * b.y - a.y * b.x, a.x * b.x + a.y * b.y);\n }\n\n static transformPointWRTAnchor(point: point, anchor: point, angle: number): Point {\n // angle is in radians\n let newPoint = this.rotatePoint(this.subVector(point, anchor), angle);\n return this.addVector(newPoint, anchor);\n }\n\n static distanceBetweenPoints(a: point, b: point): number {\n return this.magnitude(this.subVector(a, b));\n }\n\n static flipYAxis(point: point): Point{\n return {x: point.x, y: -point.y, z: point.z};\n }\n\n static linearInterpolation(a: point, b: point, t: number): point{\n if (a.z == null || b.z == null) {\n return {x: a.x + (b.x - a.x) * t, y: a.y + (b.y - a.y) * t};\n } else {\n return {x: a.x + (b.x - a.x) * t, y: a.y + (b.y - a.y) * t, z: a.z + (b.z - a.z) * t};\n }\n }\n\n static isEqual(a: point, b: point): boolean{\n if (a.z == null){\n a.z = 0;\n }\n if (b.z == null){\n b.z = 0;\n }\n return a.x == b.x && a.y == b.y && a.z == b.z;\n }\n\n static getLineIntersection(startPoint: Point, endPoint: Point, startPoint2: Point, endPoint2: Point):{\n intersects: boolean,\n intersection?: Point,\n offset?: number\n }{\n const numerator = (endPoint2.x - startPoint2.x) * (startPoint.y - startPoint2.y) - (endPoint2.y - startPoint2.y) * (startPoint.x - startPoint2.x);\n const denominator = (endPoint2.y - startPoint2.y) * (endPoint.x - startPoint.x) - (endPoint2.x - startPoint2.x) * (endPoint.y - startPoint.y);\n \n if (denominator === 0){\n return {intersects: false};\n }\n const t = numerator / denominator;\n if (t >= 0 && t <= 1){\n return {\n intersects: true, \n intersection: PointCal.linearInterpolation(startPoint, endPoint, t),\n offset: t\n }\n } else {\n return {\n intersects: false,\n }\n }\n \n }\n \n}\n\n/**\n * @description Normalizes the angle to be between 0 and 2π.\n * \n * @category Camera\n */\nexport function normalizeAngleZero2TwoPI(angle: number){\n // reduce the angle \n angle = angle % (Math.PI * 2);\n\n // force it to be the positive remainder, so that 0 <= angle < 2 * Math.PI \n angle = (angle + Math.PI * 2) % (Math.PI * 2); \n return angle;\n}\n\n/**\n * @description Gets the smaller angle span between two angles. (in radians)\n * \n * @category Camera\n */\nexport function angleSpan(from: number, to: number): number{\n // in radians\n from = normalizeAngleZero2TwoPI(from);\n to = normalizeAngleZero2TwoPI(to);\n let angleDiff = to - from;\n \n if(angleDiff > Math.PI){\n angleDiff = - (Math.PI * 2 - angleDiff);\n }\n\n if(angleDiff < -Math.PI){\n angleDiff += (Math.PI * 2);\n }\n return angleDiff;\n}\n\nexport function approximatelyTheSame(a: number, b: number, precision?: number): boolean {\n const epsilon = 0.000001\n return Math.abs(a - b) <= (precision || epsilon);\n}\n\nexport function sameDirection(a: Point, b: Point, precision: number = 0.001): boolean{\n const aNormalized = PointCal.unitVector(a);\n const bNormalized = PointCal.unitVector(b);\n return samePoint(aNormalized, bNormalized, precision);\n}\n\nexport function directionAlignedToTangent(direction: Point, tangent: Point): boolean {\n const directionNormalized = PointCal.unitVector(direction);\n const tangentNormalized = PointCal.unitVector(tangent);\n const reversedTangent = {x: -tangent.x, y: -tangent.y, z: tangent.z};\n const angle = PointCal.angleFromA2B(directionNormalized, tangentNormalized);\n const angle2 = PointCal.angleFromA2B(directionNormalized, reversedTangent);\n return (angle < Math.PI / 2 && angle > -Math.PI / 2) && (angle2 > Math.PI / 2 || angle2 < -Math.PI / 2);\n}\n\nexport function samePoint(a: Point, b: Point, precision?: number): boolean {\n if(approximatelyTheSame(a.x, b.x, precision) && approximatelyTheSame(a.y, b.y, precision)){\n return true;\n }\n return false;\n}\n"
5
+ "/**\n * @packageDocumentation\n * Mathematical utilities for 2D and 3D point operations, vector calculations, and transformations.\n *\n * @remarks\n * This package provides essential mathematical operations for canvas applications including:\n * - Vector arithmetic (add, subtract, multiply, divide)\n * - Vector operations (dot product, cross product, magnitude, unit vectors)\n * - Geometric transformations (rotation, axis transformation)\n * - Angle calculations and normalization\n * - Point comparisons and interpolation\n * - Line intersection detection\n *\n * All operations support both 2D and 3D coordinates, with the z-axis being optional.\n *\n * @example\n * Basic vector operations\n * ```typescript\n * import { PointCal, Point } from '@ue-too/math';\n *\n * const a: Point = { x: 1, y: 2 };\n * const b: Point = { x: 3, y: 4 };\n *\n * // Add vectors\n * const sum = PointCal.addVector(a, b); // { x: 4, y: 6 }\n *\n * // Calculate magnitude\n * const mag = PointCal.magnitude(a); // 2.236...\n *\n * // Get unit vector\n * const unit = PointCal.unitVector(a); // { x: 0.447..., y: 0.894... }\n * ```\n *\n * @example\n * Rotation and transformation\n * ```typescript\n * import { PointCal, Point } from '@ue-too/math';\n *\n * const point: Point = { x: 10, y: 0 };\n * const angle = Math.PI / 2; // 90 degrees\n *\n * // Rotate point around origin\n * const rotated = PointCal.rotatePoint(point, angle); // { x: 0, y: 10 }\n *\n * // Rotate around a custom anchor\n * const anchor: Point = { x: 5, y: 5 };\n * const rotatedAroundAnchor = PointCal.transformPointWRTAnchor(point, anchor, angle);\n * ```\n */\n\n/**\n * Represents a 2D or 3D point with optional z-coordinate.\n *\n * @remarks\n * This is a lowercase variant maintained for backward compatibility.\n * Use {@link Point} for new code.\n *\n * @deprecated Use {@link Point} instead for better TypeScript conventions.\n */\nexport type point = {\n /** X-coordinate */\n x: number;\n /** Y-coordinate */\n y: number;\n /** Optional Z-coordinate for 3D operations */\n z?: number;\n}\n\n/**\n * Represents a 2D or 3D point with optional z-coordinate.\n *\n * @remarks\n * When z is undefined, operations treat the point as 2D (z = 0).\n * This type is used throughout the library for all point and vector operations.\n *\n * @example\n * ```typescript\n * // 2D point\n * const p2d: Point = { x: 10, y: 20 };\n *\n * // 3D point\n * const p3d: Point = { x: 10, y: 20, z: 30 };\n * ```\n */\nexport type Point = {\n /** X-coordinate */\n x: number;\n /** Y-coordinate */\n y: number;\n /** Optional Z-coordinate for 3D operations */\n z?: number;\n}\n\n\n/**\n * Utility class for point and vector calculations.\n *\n * @remarks\n * PointCal provides static methods for common 2D and 3D mathematical operations\n * used in canvas applications. All methods handle both 2D and 3D coordinates seamlessly.\n *\n * @example\n * ```typescript\n * import { PointCal, Point } from '@ue-too/math';\n *\n * const v1: Point = { x: 1, y: 2 };\n * const v2: Point = { x: 3, y: 4 };\n *\n * const sum = PointCal.addVector(v1, v2);\n * const dot = PointCal.dotProduct(v1, v2);\n * ```\n */\nexport class PointCal {\n\n /**\n * Adds two vectors together.\n *\n * @param a - First vector\n * @param b - Second vector\n * @returns The sum of vectors a and b\n *\n * @remarks\n * If either vector lacks a z-coordinate, it's treated as 0.\n * The result will include a z-coordinate if either input has one.\n *\n * @example\n * ```typescript\n * const a = { x: 1, y: 2 };\n * const b = { x: 3, y: 4 };\n * const sum = PointCal.addVector(a, b); // { x: 4, y: 6 }\n *\n * // With 3D coordinates\n * const a3d = { x: 1, y: 2, z: 3 };\n * const b3d = { x: 4, y: 5, z: 6 };\n * const sum3d = PointCal.addVector(a3d, b3d); // { x: 5, y: 7, z: 9 }\n * ```\n *\n * @group Vector Arithmetic\n */\n static addVector(a: point, b: point): Point {\n if (a.z == null && b.z == null) return {x: a.x + b.x, y: a.y + b.y};\n if (a.z == null || b.z == null) {\n if (a.z == null) a.z = 0;\n if (b.z == null) b.z = 0;\n }\n return {x: a.x + b.x, y: a.y + b.y, z: a.z + b.z}; \n }\n\n /**\n * Subtracts vector b from vector a.\n *\n * @param a - Vector to subtract from\n * @param b - Vector to subtract\n * @returns The difference (a - b)\n *\n * @remarks\n * If either vector lacks a z-coordinate, it's treated as 0.\n *\n * @example\n * ```typescript\n * const a = { x: 5, y: 7 };\n * const b = { x: 2, y: 3 };\n * const diff = PointCal.subVector(a, b); // { x: 3, y: 4 }\n * ```\n *\n * @group Vector Arithmetic\n */\n static subVector(a: point, b: point): Point {\n if (a.z == null && b.z == null) return {x: a.x - b.x, y: a.y - b.y};\n if (a.z == null || b.z == null) {\n if (a.z == null) a.z = 0;\n if (b.z == null) b.z = 0;\n }\n return {x: a.x - b.x, y: a.y - b.y, z: a.z - b.z};\n }\n\n /**\n * Multiplies a vector by a scalar value.\n *\n * @param a - Vector to multiply\n * @param b - Scalar multiplier\n * @returns The scaled vector\n *\n * @example\n * ```typescript\n * const v = { x: 2, y: 3 };\n * const scaled = PointCal.multiplyVectorByScalar(v, 2.5); // { x: 5, y: 7.5 }\n * ```\n *\n * @group Vector Arithmetic\n */\n static multiplyVectorByScalar(a: point, b: number): Point {\n if (a.z == null) return {x: a.x * b, y: a.y * b};\n return {x: a.x * b, y: a.y * b, z: a.z * b};\n }\n\n /**\n * Divides a vector by a scalar value.\n *\n * @param a - Vector to divide\n * @param b - Scalar divisor\n * @returns The divided vector, or the original vector if b is 0\n *\n * @remarks\n * Division by zero returns the original vector unchanged to prevent NaN values.\n *\n * @example\n * ```typescript\n * const v = { x: 10, y: 20 };\n * const divided = PointCal.divideVectorByScalar(v, 2); // { x: 5, y: 10 }\n * ```\n *\n * @group Vector Arithmetic\n */\n static divideVectorByScalar(a: point, b: number): Point {\n if (b == 0) return {x: a.x, y: a.y};\n if (a.z == null) return {x: a.x / b, y: a.y / b};\n return {x: a.x / b, y: a.y / b, z: a.z / b};\n }\n\n /**\n * Calculates the magnitude (length) of a vector.\n *\n * @param a - Vector to measure\n * @returns The magnitude of the vector\n *\n * @remarks\n * Uses the Euclidean distance formula: √(x² + y² + z²)\n *\n * @example\n * ```typescript\n * const v = { x: 3, y: 4 };\n * const mag = PointCal.magnitude(v); // 5\n *\n * const v3d = { x: 1, y: 2, z: 2 };\n * const mag3d = PointCal.magnitude(v3d); // 3\n * ```\n *\n * @group Vector Operations\n */\n static magnitude(a: point): number {\n if (a.z == null) a.z = 0;\n return Math.sqrt(a.x * a.x + a.y * a.y + a.z * a.z);\n }\n\n /**\n * Converts a vector to its unit vector (normalized to length 1).\n *\n * @param a - Vector to normalize\n * @returns Unit vector in the same direction, or zero vector if magnitude is 0\n *\n * @remarks\n * A unit vector has magnitude 1 and preserves the original direction.\n * Returns {x: 0, y: 0, z: 0} if the input vector has zero magnitude.\n *\n * **Performance note**: This method calls `magnitude()` twice. For better performance\n * when you need both magnitude and unit vector, calculate magnitude once and divide manually.\n *\n * @example\n * ```typescript\n * const v = { x: 3, y: 4 };\n * const unit = PointCal.unitVector(v); // { x: 0.6, y: 0.8 }\n * ```\n *\n * @group Vector Operations\n */\n static unitVector(a: point): Point {\n if (a.z == null) a.z = 0;\n return this.magnitude(a) != 0 ? {x: a.x / this.magnitude(a), y: a.y / this.magnitude(a), z: a.z / this.magnitude(a)} : {x: 0, y: 0, z: 0};\n }\n\n /**\n * Calculates the dot product of two vectors.\n *\n * @param a - First vector\n * @param b - Second vector\n * @returns The dot product (scalar value)\n *\n * @remarks\n * The dot product is: a.x * b.x + a.y * b.y + a.z * b.z\n *\n * **Use cases:**\n * - Determine if vectors are perpendicular (dot = 0)\n * - Calculate angle between vectors: θ = acos(dot / (|a| * |b|))\n * - Project one vector onto another\n *\n * @example\n * ```typescript\n * const a = { x: 1, y: 0 };\n * const b = { x: 0, y: 1 };\n * const dot = PointCal.dotProduct(a, b); // 0 (perpendicular vectors)\n *\n * const c = { x: 2, y: 3 };\n * const d = { x: 4, y: 5 };\n * const dot2 = PointCal.dotProduct(c, d); // 23\n * ```\n *\n * @group Vector Operations\n */\n static dotProduct(a: point, b: point): number {\n if (a.z == null && b.z == null) return a.x * b.x + a.y * b.y;\n if (a.z == null || b.z == null) {\n if (a.z == null) a.z = 0;\n if (b.z == null) b.z = 0;\n }\n return a.x * b.x + a.y * b.y + a.z * b.z;\n }\n\n /**\n * Calculates the cross product of two vectors.\n *\n * @param a - First vector\n * @param b - Second vector\n * @returns The cross product vector perpendicular to both inputs\n *\n * @remarks\n * The cross product is perpendicular to both input vectors, following the right-hand rule.\n * For 2D vectors (z undefined), z is treated as 0.\n *\n * **Properties:**\n * - Result is perpendicular to both input vectors\n * - Magnitude equals area of parallelogram formed by vectors\n * - Direction follows right-hand rule\n *\n * @example\n * ```typescript\n * const a = { x: 1, y: 0, z: 0 };\n * const b = { x: 0, y: 1, z: 0 };\n * const cross = PointCal.crossProduct(a, b); // { x: 0, y: 0, z: 1 }\n * ```\n *\n * @group Vector Operations\n */\n static crossProduct(a: point, b: point): Point {\n if (a.z == null || b.z == null) {\n if (a.z == null) a.z = 0;\n if (b.z == null) b.z = 0;\n }\n return {x: a.y * b.z - a.z * b.y, y: a.z * b.x - a.x * b.z, z: a.x * b.y - a.y * b.x};\n }\n\n /**\n * Calculates the unit vector pointing from point a to point b.\n *\n * @param a - Starting point\n * @param b - Ending point\n * @returns Unit vector in the direction from a to b\n *\n * @remarks\n * Equivalent to calling unitVector(subVector(b, a))\n *\n * @example\n * ```typescript\n * const a = { x: 0, y: 0 };\n * const b = { x: 3, y: 4 };\n * const direction = PointCal.unitVectorFromA2B(a, b); // { x: 0.6, y: 0.8 }\n * ```\n *\n * @group Geometric Calculations\n */\n static unitVectorFromA2B(a: point, b: point): Point {\n return this.unitVector(this.subVector(b, a));\n }\n\n /**\n * Rotates a point around the origin.\n *\n * @param point - Point to rotate\n * @param angle - Rotation angle in radians (counter-clockwise)\n * @returns Rotated point\n *\n * @remarks\n * Rotation is performed around the origin (0, 0).\n * Positive angles rotate counter-clockwise, negative angles rotate clockwise.\n * For rotation around a custom anchor, use {@link transformPointWRTAnchor}.\n *\n * **Performance**: Uses trigonometric functions (sin/cos). For many rotations with\n * the same angle, pre-calculate sin/cos values and apply the transformation manually.\n *\n * @example\n * ```typescript\n * const point = { x: 1, y: 0 };\n * const rotated = PointCal.rotatePoint(point, Math.PI / 2); // { x: 0, y: 1 }\n * ```\n *\n * @group Transformations\n */\n static rotatePoint(point: point, angle: number): Point {\n return {x: point.x * Math.cos(angle) - point.y * Math.sin(angle), y: point.x * Math.sin(angle) + point.y * Math.cos(angle)};\n }\n\n /**\n * Transforms a point's coordinates to a new rotated axis system.\n *\n * @param point - Point in original coordinate system\n * @param angleFromOriginalAxis2DestAxis - Rotation angle from original to destination axis (radians, CCW positive)\n * @returns Point coordinates in the new axis system\n *\n * @remarks\n * This performs an axis rotation transformation, converting coordinates from one\n * reference frame to another rotated by the specified angle.\n *\n * @example\n * ```typescript\n * const point = { x: 10, y: 0 };\n * const angle = Math.PI / 4; // 45 degrees\n * const transformed = PointCal.transform2NewAxis(point, angle);\n * ```\n *\n * @group Transformations\n */\n static transform2NewAxis(point: point, angleFromOriginalAxis2DestAxis: number): Point {\n // angle is the angle from the original axis to the destination axis ccw is positive as always\n return {x: point.x * Math.cos(angleFromOriginalAxis2DestAxis) + point.y * Math.sin(angleFromOriginalAxis2DestAxis), y: -point.x * Math.sin(angleFromOriginalAxis2DestAxis) + point.y * Math.cos(angleFromOriginalAxis2DestAxis)};\n }\n\n /**\n * Calculates the signed angle from vector a to vector b.\n *\n * @param a - First vector (starting direction)\n * @param b - Second vector (ending direction)\n * @returns The signed angle in radians, range: (-π, π]\n *\n * @remarks\n * - Positive angles indicate counter-clockwise rotation from a to b\n * - Negative angles indicate clockwise rotation from a to b\n * - Uses atan2 for proper quadrant handling\n *\n * @example\n * ```typescript\n * const right = { x: 1, y: 0 };\n * const up = { x: 0, y: 1 };\n * const angle = PointCal.angleFromA2B(right, up); // π/2 (90 degrees CCW)\n *\n * const down = { x: 0, y: -1 };\n * const angleDown = PointCal.angleFromA2B(right, down); // -π/2 (90 degrees CW)\n * ```\n *\n * @group Angle Utilities\n */\n static angleFromA2B(a: point, b: point): number {\n return Math.atan2(a.x * b.y - a.y * b.x, a.x * b.x + a.y * b.y);\n }\n\n /**\n * Rotates a point around a custom anchor point.\n *\n * @param point - Point to rotate\n * @param anchor - Anchor point to rotate around\n * @param angle - Rotation angle in radians (counter-clockwise)\n * @returns Rotated point\n *\n * @remarks\n * This is equivalent to:\n * 1. Translate point by -anchor\n * 2. Rotate around origin\n * 3. Translate back by +anchor\n *\n * @example\n * ```typescript\n * const point = { x: 10, y: 5 };\n * const anchor = { x: 5, y: 5 };\n * const angle = Math.PI / 2; // 90 degrees\n * const rotated = PointCal.transformPointWRTAnchor(point, anchor, angle);\n * // Rotates point around anchor (5, 5)\n * ```\n *\n * @group Transformations\n */\n static transformPointWRTAnchor(point: point, anchor: point, angle: number): Point {\n // angle is in radians\n let newPoint = this.rotatePoint(this.subVector(point, anchor), angle);\n return this.addVector(newPoint, anchor);\n }\n\n /**\n * Calculates the Euclidean distance between two points.\n *\n * @param a - First point\n * @param b - Second point\n * @returns The distance between the two points\n *\n * @remarks\n * Equivalent to calculating the magnitude of the vector from a to b.\n *\n * @example\n * ```typescript\n * const a = { x: 0, y: 0 };\n * const b = { x: 3, y: 4 };\n * const distance = PointCal.distanceBetweenPoints(a, b); // 5\n * ```\n *\n * @group Geometric Calculations\n */\n static distanceBetweenPoints(a: point, b: point): number {\n return this.magnitude(this.subVector(a, b));\n }\n\n /**\n * Flips a point's y-coordinate (mirrors across the x-axis).\n *\n * @param point - Point to flip\n * @returns Point with negated y-coordinate\n *\n * @remarks\n * Useful for converting between coordinate systems where the y-axis direction differs.\n * Common when converting between screen coordinates (y-down) and mathematical coordinates (y-up).\n *\n * @example\n * ```typescript\n * const point = { x: 10, y: 20 };\n * const flipped = PointCal.flipYAxis(point); // { x: 10, y: -20 }\n * ```\n *\n * @group Transformations\n */\n static flipYAxis(point: point): Point{\n return {x: point.x, y: -point.y, z: point.z};\n }\n\n /**\n * Performs linear interpolation between two points.\n *\n * @param a - Starting point (t = 0)\n * @param b - Ending point (t = 1)\n * @param t - Interpolation parameter (0 to 1)\n * @returns Interpolated point\n *\n * @remarks\n * - t = 0 returns point a\n * - t = 1 returns point b\n * - t = 0.5 returns the midpoint\n * - Values outside [0, 1] perform extrapolation\n *\n * **Performance**: Suitable for animation loops and real-time interpolation.\n *\n * @example\n * ```typescript\n * const a = { x: 0, y: 0 };\n * const b = { x: 10, y: 20 };\n * const mid = PointCal.linearInterpolation(a, b, 0.5); // { x: 5, y: 10 }\n * const quarter = PointCal.linearInterpolation(a, b, 0.25); // { x: 2.5, y: 5 }\n * ```\n *\n * @group Geometric Calculations\n */\n static linearInterpolation(a: point, b: point, t: number): point{\n if (a.z == null || b.z == null) {\n return {x: a.x + (b.x - a.x) * t, y: a.y + (b.y - a.y) * t};\n } else {\n return {x: a.x + (b.x - a.x) * t, y: a.y + (b.y - a.y) * t, z: a.z + (b.z - a.z) * t};\n }\n }\n\n /**\n * Checks if two points are exactly equal.\n *\n * @param a - First point\n * @param b - Second point\n * @returns True if all coordinates are exactly equal\n *\n * @remarks\n * Uses strict equality (===) for comparison.\n * For approximate equality with tolerance, use {@link samePoint} instead.\n * Missing z-coordinates are treated as 0.\n *\n * @example\n * ```typescript\n * const a = { x: 1, y: 2 };\n * const b = { x: 1, y: 2 };\n * PointCal.isEqual(a, b); // true\n *\n * const c = { x: 1.0000001, y: 2 };\n * PointCal.isEqual(a, c); // false (use samePoint for tolerance)\n * ```\n *\n * @group Geometric Calculations\n */\n static isEqual(a: point, b: point): boolean{\n if (a.z == null){\n a.z = 0;\n }\n if (b.z == null){\n b.z = 0;\n }\n return a.x == b.x && a.y == b.y && a.z == b.z;\n }\n\n /**\n * Calculates the intersection point of two line segments.\n *\n * @param startPoint - Start of first line segment\n * @param endPoint - End of first line segment\n * @param startPoint2 - Start of second line segment\n * @param endPoint2 - End of second line segment\n * @returns Object containing intersection status and details\n *\n * @remarks\n * Returns an object with:\n * - `intersects`: Boolean indicating if segments intersect\n * - `intersection`: The intersection point (only if intersects is true)\n * - `offset`: Parameter t where intersection occurs on first segment (0 to 1)\n *\n * The segments must actually cross within their bounds (not just their infinite extensions).\n *\n * **Use cases:**\n * - Collision detection between line segments\n * - Ray casting and visibility checks\n * - Path intersection detection\n *\n * @example\n * ```typescript\n * const line1Start = { x: 0, y: 0 };\n * const line1End = { x: 10, y: 10 };\n * const line2Start = { x: 0, y: 10 };\n * const line2End = { x: 10, y: 0 };\n *\n * const result = PointCal.getLineIntersection(line1Start, line1End, line2Start, line2End);\n * // { intersects: true, intersection: { x: 5, y: 5 }, offset: 0.5 }\n * ```\n *\n * @group Geometric Calculations\n */\n static getLineIntersection(startPoint: Point, endPoint: Point, startPoint2: Point, endPoint2: Point):{\n intersects: boolean,\n intersection?: Point,\n offset?: number\n }{\n const numerator = (endPoint2.x - startPoint2.x) * (startPoint.y - startPoint2.y) - (endPoint2.y - startPoint2.y) * (startPoint.x - startPoint2.x);\n const denominator = (endPoint2.y - startPoint2.y) * (endPoint.x - startPoint.x) - (endPoint2.x - startPoint2.x) * (endPoint.y - startPoint.y);\n \n if (denominator === 0){\n return {intersects: false};\n }\n const t = numerator / denominator;\n if (t >= 0 && t <= 1){\n return {\n intersects: true, \n intersection: PointCal.linearInterpolation(startPoint, endPoint, t),\n offset: t\n }\n } else {\n return {\n intersects: false,\n }\n }\n \n }\n \n}\n\n/**\n * Normalizes an angle to the range [0, 2π).\n *\n * @param angle - Angle in radians (can be any value)\n * @returns Normalized angle between 0 and 2π\n *\n * @remarks\n * This function wraps any angle to the range [0, 2π) by taking the modulo\n * and ensuring the result is positive.\n *\n * @example\n * ```typescript\n * normalizeAngleZero2TwoPI(Math.PI * 3); // π (180 degrees)\n * normalizeAngleZero2TwoPI(-Math.PI / 2); // 3π/2 (270 degrees)\n * normalizeAngleZero2TwoPI(0); // 0\n * ```\n *\n * @category Angle\n */\nexport function normalizeAngleZero2TwoPI(angle: number){\n // reduce the angle \n angle = angle % (Math.PI * 2);\n\n // force it to be the positive remainder, so that 0 <= angle < 2 * Math.PI \n angle = (angle + Math.PI * 2) % (Math.PI * 2); \n return angle;\n}\n\n/**\n * Calculates the smallest angular difference between two angles.\n *\n * @param from - Starting angle in radians\n * @param to - Ending angle in radians\n * @returns The smallest angle span from 'from' to 'to', in range (-π, π]\n *\n * @remarks\n * This function accounts for wrapping around 2π and always returns the shorter path.\n * Positive result means counter-clockwise rotation, negative means clockwise.\n *\n * @example\n * ```typescript\n * // From 0° to 90°\n * angleSpan(0, Math.PI / 2); // π/2 (90 degrees CCW)\n *\n * // From 350° to 10° (shorter to go CCW through 0°)\n * angleSpan(350 * Math.PI / 180, 10 * Math.PI / 180); // ≈ 20 degrees\n *\n * // From 10° to 350° (shorter to go CW through 0°)\n * angleSpan(10 * Math.PI / 180, 350 * Math.PI / 180); // ≈ -20 degrees\n * ```\n *\n * @category Angle\n */\nexport function angleSpan(from: number, to: number): number{\n // in radians\n from = normalizeAngleZero2TwoPI(from);\n to = normalizeAngleZero2TwoPI(to);\n let angleDiff = to - from;\n \n if(angleDiff > Math.PI){\n angleDiff = - (Math.PI * 2 - angleDiff);\n }\n\n if(angleDiff < -Math.PI){\n angleDiff += (Math.PI * 2);\n }\n return angleDiff;\n}\n\n/**\n * Checks if two numbers are approximately equal within a tolerance.\n *\n * @param a - First number\n * @param b - Second number\n * @param precision - Optional tolerance (defaults to 0.000001)\n * @returns True if the absolute difference is within the precision threshold\n *\n * @remarks\n * Useful for floating-point comparisons where exact equality is unreliable.\n *\n * @example\n * ```typescript\n * approximatelyTheSame(1.0, 1.0000001); // true (within default epsilon)\n * approximatelyTheSame(1.0, 1.1); // false\n * approximatelyTheSame(1.0, 1.01, 0.02); // true (within custom precision)\n * ```\n *\n * @category Comparison\n */\nexport function approximatelyTheSame(a: number, b: number, precision?: number): boolean {\n const epsilon = 0.000001\n return Math.abs(a - b) <= (precision || epsilon);\n}\n\n/**\n * Checks if two vectors point in the same direction.\n *\n * @param a - First vector\n * @param b - Second vector\n * @param precision - Tolerance for comparison (defaults to 0.001)\n * @returns True if vectors have the same direction (after normalization)\n *\n * @remarks\n * Normalizes both vectors to unit vectors and compares them.\n * Magnitude does not matter, only direction.\n *\n * @example\n * ```typescript\n * const a = { x: 1, y: 0 };\n * const b = { x: 10, y: 0 }; // Same direction, different magnitude\n * sameDirection(a, b); // true\n *\n * const c = { x: 1, y: 1 };\n * sameDirection(a, c); // false (different direction)\n * ```\n *\n * @category Comparison\n */\nexport function sameDirection(a: Point, b: Point, precision: number = 0.001): boolean{\n const aNormalized = PointCal.unitVector(a);\n const bNormalized = PointCal.unitVector(b);\n return samePoint(aNormalized, bNormalized, precision);\n}\n\n/**\n * Checks if a direction vector is aligned with a tangent vector.\n *\n * @param direction - Direction vector to check\n * @param tangent - Tangent vector reference\n * @returns True if direction aligns with tangent (within 90 degrees)\n *\n * @remarks\n * Returns true if the direction is within 90 degrees of either the tangent\n * or its reverse. Useful for determining if movement is along a path.\n *\n * @example\n * ```typescript\n * const direction = { x: 1, y: 0 };\n * const tangent = { x: 1, y: 0.1 }; // Slightly rotated\n * directionAlignedToTangent(direction, tangent); // true\n *\n * const perpendicular = { x: 0, y: 1 };\n * directionAlignedToTangent(perpendicular, tangent); // false\n * ```\n *\n * @category Comparison\n */\nexport function directionAlignedToTangent(direction: Point, tangent: Point): boolean {\n const directionNormalized = PointCal.unitVector(direction);\n const tangentNormalized = PointCal.unitVector(tangent);\n const reversedTangent = {x: -tangent.x, y: -tangent.y, z: tangent.z};\n const angle = PointCal.angleFromA2B(directionNormalized, tangentNormalized);\n const angle2 = PointCal.angleFromA2B(directionNormalized, reversedTangent);\n return (angle < Math.PI / 2 && angle > -Math.PI / 2) && (angle2 > Math.PI / 2 || angle2 < -Math.PI / 2);\n}\n\n/**\n * Checks if two points are approximately at the same location.\n *\n * @param a - First point\n * @param b - Second point\n * @param precision - Optional tolerance for coordinate comparison\n * @returns True if both x and y coordinates are within precision\n *\n * @remarks\n * Uses {@link approximatelyTheSame} for coordinate comparison.\n * For exact equality, use {@link PointCal.isEqual} instead.\n *\n * @example\n * ```typescript\n * const a = { x: 1.0, y: 2.0 };\n * const b = { x: 1.0000001, y: 2.0000001 };\n * samePoint(a, b); // true (within default precision)\n *\n * const c = { x: 1.1, y: 2.0 };\n * samePoint(a, c); // false\n * ```\n *\n * @category Comparison\n */\nexport function samePoint(a: Point, b: Point, precision?: number): boolean {\n if(approximatelyTheSame(a.x, b.x, precision) && approximatelyTheSame(a.y, b.y, precision)){\n return true;\n }\n return false;\n}\n"
6
6
  ],
7
- "mappings": ";AAaO,MAAM,SAAS;AAAA,SAEX,SAAS,CAAC,GAAU,GAAiB;AAAA,IACxC,IAAI,EAAE,KAAK,QAAQ,EAAE,KAAK;AAAA,MAAM,OAAO,EAAC,GAAG,EAAE,IAAI,EAAE,GAAG,GAAG,EAAE,IAAI,EAAE,EAAC;AAAA,IAClE,IAAI,EAAE,KAAK,QAAQ,EAAE,KAAK,MAAM;AAAA,MAC5B,IAAI,EAAE,KAAK;AAAA,QAAM,EAAE,IAAI;AAAA,MACvB,IAAI,EAAE,KAAK;AAAA,QAAM,EAAE,IAAI;AAAA,IAC3B;AAAA,IACA,OAAO,EAAC,GAAG,EAAE,IAAI,EAAE,GAAG,GAAG,EAAE,IAAI,EAAE,GAAG,GAAG,EAAE,IAAI,EAAE,EAAC;AAAA;AAAA,SAG7C,SAAS,CAAC,GAAU,GAAiB;AAAA,IACxC,IAAI,EAAE,KAAK,QAAQ,EAAE,KAAK;AAAA,MAAM,OAAO,EAAC,GAAG,EAAE,IAAI,EAAE,GAAG,GAAG,EAAE,IAAI,EAAE,EAAC;AAAA,IAClE,IAAI,EAAE,KAAK,QAAQ,EAAE,KAAK,MAAM;AAAA,MAC5B,IAAI,EAAE,KAAK;AAAA,QAAM,EAAE,IAAI;AAAA,MACvB,IAAI,EAAE,KAAK;AAAA,QAAM,EAAE,IAAI;AAAA,IAC3B;AAAA,IACA,OAAO,EAAC,GAAG,EAAE,IAAI,EAAE,GAAG,GAAG,EAAE,IAAI,EAAE,GAAG,GAAG,EAAE,IAAI,EAAE,EAAC;AAAA;AAAA,SAG7C,sBAAsB,CAAC,GAAU,GAAkB;AAAA,IACtD,IAAI,EAAE,KAAK;AAAA,MAAM,OAAO,EAAC,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,IAAI,EAAC;AAAA,IAC/C,OAAO,EAAC,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,IAAI,EAAC;AAAA;AAAA,SAGvC,oBAAoB,CAAC,GAAU,GAAkB;AAAA,IACpD,IAAI,KAAK;AAAA,MAAG,OAAO,EAAC,GAAG,EAAE,GAAG,GAAG,EAAE,EAAC;AAAA,IAClC,IAAI,EAAE,KAAK;AAAA,MAAM,OAAO,EAAC,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,IAAI,EAAC;AAAA,IAC/C,OAAO,EAAC,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,IAAI,EAAC;AAAA;AAAA,SAGvC,SAAS,CAAC,GAAkB;AAAA,IAC/B,IAAI,EAAE,KAAK;AAAA,MAAM,EAAE,IAAI;AAAA,IACvB,OAAO,KAAK,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AAAA;AAAA,SAG/C,UAAU,CAAC,GAAiB;AAAA,IAC/B,IAAI,EAAE,KAAK;AAAA,MAAM,EAAE,IAAI;AAAA,IACvB,OAAO,KAAK,UAAU,CAAC,KAAK,IAAI,EAAC,GAAG,EAAE,IAAI,KAAK,UAAU,CAAC,GAAG,GAAG,EAAE,IAAI,KAAK,UAAU,CAAC,GAAG,GAAG,EAAE,IAAI,KAAK,UAAU,CAAC,EAAC,IAAI,EAAC,GAAG,GAAG,GAAG,GAAG,GAAG,EAAC;AAAA;AAAA,SAGrI,UAAU,CAAC,GAAU,GAAkB;AAAA,IAC1C,IAAI,EAAE,KAAK,QAAQ,EAAE,KAAK;AAAA,MAAM,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE;AAAA,IAC3D,IAAI,EAAE,KAAK,QAAQ,EAAE,KAAK,MAAM;AAAA,MAC5B,IAAI,EAAE,KAAK;AAAA,QAAM,EAAE,IAAI;AAAA,MACvB,IAAI,EAAE,KAAK;AAAA,QAAM,EAAE,IAAI;AAAA,IAC3B;AAAA,IACA,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE;AAAA;AAAA,SAGpC,YAAY,CAAC,GAAU,GAAiB;AAAA,IAC3C,IAAI,EAAE,KAAK,QAAQ,EAAE,KAAK,MAAM;AAAA,MAC5B,IAAI,EAAE,KAAK;AAAA,QAAM,EAAE,IAAI;AAAA,MACvB,IAAI,EAAE,KAAK;AAAA,QAAM,EAAE,IAAI;AAAA,IAC3B;AAAA,IACA,OAAO,EAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EAAC;AAAA;AAAA,SAGjF,iBAAiB,CAAC,GAAU,GAAiB;AAAA,IAChD,OAAO,KAAK,WAAW,KAAK,UAAU,GAAG,CAAC,CAAC;AAAA;AAAA,SAGxC,WAAW,CAAC,OAAc,OAAsB;AAAA,IACnD,OAAO,EAAC,GAAG,MAAM,IAAI,KAAK,IAAI,KAAK,IAAI,MAAM,IAAI,KAAK,IAAI,KAAK,GAAG,GAAG,MAAM,IAAI,KAAK,IAAI,KAAK,IAAI,MAAM,IAAI,KAAK,IAAI,KAAK,EAAC;AAAA;AAAA,SAGvH,iBAAiB,CAAC,OAAc,gCAA+C;AAAA,IAElF,OAAO,EAAC,GAAG,MAAM,IAAI,KAAK,IAAI,8BAA8B,IAAI,MAAM,IAAI,KAAK,IAAI,8BAA8B,GAAG,GAAG,CAAC,MAAM,IAAI,KAAK,IAAI,8BAA8B,IAAI,MAAM,IAAI,KAAK,IAAI,8BAA8B,EAAC;AAAA;AAAA,SAM5N,YAAY,CAAC,GAAU,GAAkB;AAAA,IAC5C,OAAO,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AAAA;AAAA,SAG3D,uBAAuB,CAAC,OAAc,QAAe,OAAsB;AAAA,IAE9E,IAAI,WAAW,KAAK,YAAY,KAAK,UAAU,OAAO,MAAM,GAAG,KAAK;AAAA,IACpE,OAAO,KAAK,UAAU,UAAU,MAAM;AAAA;AAAA,SAGnC,qBAAqB,CAAC,GAAU,GAAkB;AAAA,IACrD,OAAO,KAAK,UAAU,KAAK,UAAU,GAAG,CAAC,CAAC;AAAA;AAAA,SAGvC,SAAS,CAAC,OAAoB;AAAA,IACjC,OAAO,EAAC,GAAG,MAAM,GAAG,GAAG,CAAC,MAAM,GAAG,GAAG,MAAM,EAAC;AAAA;AAAA,SAGxC,mBAAmB,CAAC,GAAU,GAAU,GAAiB;AAAA,IAC5D,IAAI,EAAE,KAAK,QAAQ,EAAE,KAAK,MAAM;AAAA,MAC5B,OAAO,EAAC,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,GAAG,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAC;AAAA,IAC9D,EAAO;AAAA,MACH,OAAO,EAAC,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,GAAG,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,GAAG,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAC;AAAA;AAAA;AAAA,SAIrF,OAAO,CAAC,GAAU,GAAkB;AAAA,IACvC,IAAI,EAAE,KAAK,MAAK;AAAA,MACZ,EAAE,IAAI;AAAA,IACV;AAAA,IACA,IAAI,EAAE,KAAK,MAAK;AAAA,MACZ,EAAE,IAAI;AAAA,IACV;AAAA,IACA,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE;AAAA;AAAA,SAGzC,mBAAmB,CAAC,YAAmB,UAAiB,aAAoB,WAIlF;AAAA,IACG,MAAM,aAAa,UAAU,IAAI,YAAY,MAAM,WAAW,IAAI,YAAY,MAAM,UAAU,IAAI,YAAY,MAAM,WAAW,IAAI,YAAY;AAAA,IAC/I,MAAM,eAAe,UAAU,IAAI,YAAY,MAAM,SAAS,IAAI,WAAW,MAAM,UAAU,IAAI,YAAY,MAAM,SAAS,IAAI,WAAW;AAAA,IAE3I,IAAI,gBAAgB,GAAE;AAAA,MAClB,OAAO,EAAC,YAAY,MAAK;AAAA,IAC7B;AAAA,IACA,MAAM,IAAI,YAAY;AAAA,IACtB,IAAI,KAAK,KAAK,KAAK,GAAE;AAAA,MACjB,OAAO;AAAA,QACH,YAAY;AAAA,QACZ,cAAc,SAAS,oBAAoB,YAAY,UAAU,CAAC;AAAA,QAClE,QAAQ;AAAA,MACZ;AAAA,IACJ,EAAO;AAAA,MACH,OAAO;AAAA,QACH,YAAY;AAAA,MAChB;AAAA;AAAA;AAKZ;AAOO,SAAS,wBAAwB,CAAC,OAAc;AAAA,EAEnD,QAAQ,SAAS,KAAK,KAAK;AAAA,EAG3B,SAAS,QAAQ,KAAK,KAAK,MAAM,KAAK,KAAK;AAAA,EAC3C,OAAO;AAAA;AAQJ,SAAS,SAAS,CAAC,MAAc,IAAmB;AAAA,EAEvD,OAAO,yBAAyB,IAAI;AAAA,EACpC,KAAK,yBAAyB,EAAE;AAAA,EAChC,IAAI,YAAY,KAAK;AAAA,EAErB,IAAG,YAAY,KAAK,IAAG;AAAA,IACnB,YAAY,EAAG,KAAK,KAAK,IAAI;AAAA,EACjC;AAAA,EAEA,IAAG,YAAY,CAAC,KAAK,IAAG;AAAA,IACpB,aAAc,KAAK,KAAK;AAAA,EAC5B;AAAA,EACA,OAAO;AAAA;AAGJ,SAAS,oBAAoB,CAAC,GAAW,GAAW,WAA6B;AAAA,EACpF,MAAM,UAAU;AAAA,EAChB,OAAO,KAAK,IAAI,IAAI,CAAC,MAAM,aAAa;AAAA;AAGrC,SAAS,aAAa,CAAC,GAAU,GAAU,YAAoB,OAAe;AAAA,EAClF,MAAM,cAAc,SAAS,WAAW,CAAC;AAAA,EACzC,MAAM,cAAc,SAAS,WAAW,CAAC;AAAA,EACzC,OAAO,UAAU,aAAa,aAAa,SAAS;AAAA;AAGhD,SAAS,yBAAyB,CAAC,WAAkB,SAAyB;AAAA,EAClF,MAAM,sBAAsB,SAAS,WAAW,SAAS;AAAA,EACzD,MAAM,oBAAoB,SAAS,WAAW,OAAO;AAAA,EACrD,MAAM,kBAAkB,EAAC,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,QAAQ,GAAG,GAAG,QAAQ,EAAC;AAAA,EACnE,MAAM,QAAQ,SAAS,aAAa,qBAAqB,iBAAiB;AAAA,EAC1E,MAAM,SAAS,SAAS,aAAa,qBAAqB,eAAe;AAAA,EACzE,OAAQ,QAAQ,KAAK,KAAK,KAAK,QAAQ,CAAC,KAAK,KAAK,MAAO,SAAS,KAAK,KAAK,KAAK,SAAS,CAAC,KAAK,KAAK;AAAA;AAGjG,SAAS,SAAS,CAAC,GAAU,GAAU,WAA6B;AAAA,EACvE,IAAG,qBAAqB,EAAE,GAAG,EAAE,GAAG,SAAS,KAAK,qBAAqB,EAAE,GAAG,EAAE,GAAG,SAAS,GAAE;AAAA,IACtF,OAAO;AAAA,EACX;AAAA,EACA,OAAO;AAAA;",
8
- "debugId": "B0C116870CD7AAF064756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "E7FBAB931781982464756E2164756E21",
9
9
  "names": []
10
10
  }
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@ue-too/math",
3
3
  "author": "niuee",
4
4
  "type": "module",
5
- "version": "0.9.4",
5
+ "version": "0.10.0",
6
6
  "description": "Math utilities for uē-tôo",
7
7
  "license": "MIT",
8
8
  "repository": {