@ue-too/math 0.14.0 → 0.15.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/2dVector.d.ts ADDED
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Represents a 2D or 3D point with optional z-coordinate.
3
+ *
4
+ * @remarks
5
+ * When z is undefined, operations treat the point as 2D (z = 0).
6
+ * This type is used throughout the library for all point and vector operations.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * // 2D point
11
+ * const p2d: Point = { x: 10, y: 20 };
12
+ *
13
+ * // 3D point
14
+ * const p3d: Point = { x: 10, y: 20, z: 30 };
15
+ * ```
16
+ */
17
+ export type Point = {
18
+ /** X-coordinate */
19
+ x: number;
20
+ /** Y-coordinate */
21
+ y: number;
22
+ /** Optional Z-coordinate for 3D operations */
23
+ z?: number;
24
+ };
25
+ declare const addVector: (a: Point, b: Point) => {
26
+ x: number;
27
+ y: number;
28
+ z?: undefined;
29
+ } | {
30
+ x: number;
31
+ y: number;
32
+ z: number;
33
+ };
34
+ declare const subVector: (a: Point, b: Point) => Point;
35
+ declare const multiplyVectorByScalar: (a: Point, b: number) => Point;
36
+ declare const divideVectorByScalar: (a: Point, b: number) => Point;
37
+ declare const magnitude: (a: Point) => number;
38
+ declare const unitVector: (a: Point) => Point;
39
+ declare const dotProduct: (a: Point, b: Point) => number;
40
+ declare const crossProduct: (a: Point, b: Point) => Point;
41
+ declare const unitVectorFromA2B: (a: Point, b: Point) => Point;
42
+ declare const rotatePoint: (point: Point, angle: number) => Point;
43
+ declare const transform2NewAxis: (point: Point, angleFromOriginalAxis2DestAxis: number) => Point;
44
+ declare const angleFromA2B: (a: Point, b: Point) => number;
45
+ declare const transformPointWRTAnchor: (point: Point, anchor: Point, angle: number) => Point;
46
+ declare const distanceBetweenPoints: (a: Point, b: Point) => number;
47
+ declare const flipYAxis: (point: Point) => Point;
48
+ declare const linearInterpolation: (a: Point, b: Point, t: number) => Point;
49
+ declare const isEqual: (a: Point, b: Point) => boolean;
50
+ declare const getLineIntersection: (startPoint: Point, endPoint: Point, startPoint2: Point, endPoint2: Point) => {
51
+ intersects: boolean;
52
+ intersection?: Point;
53
+ offset?: number;
54
+ };
55
+ export { addVector, subVector, multiplyVectorByScalar, divideVectorByScalar, magnitude, unitVector, dotProduct, crossProduct, unitVectorFromA2B, rotatePoint, transform2NewAxis, angleFromA2B, transformPointWRTAnchor, distanceBetweenPoints, flipYAxis, linearInterpolation, isEqual, getLineIntersection, };
package/README.md CHANGED
@@ -34,7 +34,7 @@ npm install @ue-too/math
34
34
  ## Quick Start
35
35
 
36
36
  ```typescript
37
- import { PointCal, Point } from '@ue-too/math';
37
+ import { Point, PointCal } from '@ue-too/math';
38
38
 
39
39
  // Vector addition
40
40
  const a: Point = { x: 1, y: 2 };
@@ -129,7 +129,7 @@ PointCal.getLineIntersection(line1Start, line1End, line2Start, line2End);
129
129
  ### Angle Utilities
130
130
 
131
131
  ```typescript
132
- import { normalizeAngleZero2TwoPI, angleSpan } from '@ue-too/math';
132
+ import { angleSpan, normalizeAngleZero2TwoPI } from '@ue-too/math';
133
133
 
134
134
  // Normalize angle to [0, 2π)
135
135
  const normalized = normalizeAngleZero2TwoPI(Math.PI * 3); // π
@@ -141,7 +141,7 @@ const diff = angleSpan(fromAngle, toAngle); // Range: (-π, π]
141
141
  ### Comparison Functions
142
142
 
143
143
  ```typescript
144
- import { samePoint, sameDirection, approximatelyTheSame } from '@ue-too/math';
144
+ import { approximatelyTheSame, sameDirection, samePoint } from '@ue-too/math';
145
145
 
146
146
  // Check if points are approximately equal
147
147
  samePoint(a, b); // Uses default precision (0.000001)
@@ -159,7 +159,7 @@ approximatelyTheSame(1.0, 1.0000001); // true
159
159
  ### Canvas Transformations
160
160
 
161
161
  ```typescript
162
- import { PointCal, Point } from '@ue-too/math';
162
+ import { Point, PointCal } from '@ue-too/math';
163
163
 
164
164
  // Transform mouse coordinates to rotated canvas space
165
165
  const mousePos: Point = { x: 150, y: 200 };
@@ -167,16 +167,16 @@ const canvasCenter: Point = { x: 100, y: 100 };
167
167
  const canvasRotation = Math.PI / 4; // 45 degrees
168
168
 
169
169
  const transformedPos = PointCal.transformPointWRTAnchor(
170
- mousePos,
171
- canvasCenter,
172
- -canvasRotation // Inverse rotation
170
+ mousePos,
171
+ canvasCenter,
172
+ -canvasRotation // Inverse rotation
173
173
  );
174
174
  ```
175
175
 
176
176
  ### Path Following
177
177
 
178
178
  ```typescript
179
- import { PointCal, Point } from '@ue-too/math';
179
+ import { Point, PointCal } from '@ue-too/math';
180
180
 
181
181
  // Calculate direction from current position to target
182
182
  const current: Point = { x: 10, y: 20 };
@@ -187,15 +187,15 @@ const speed = 5;
187
187
 
188
188
  // Move toward target
189
189
  const newPosition = PointCal.addVector(
190
- current,
191
- PointCal.multiplyVectorByScalar(direction, speed)
190
+ current,
191
+ PointCal.multiplyVectorByScalar(direction, speed)
192
192
  );
193
193
  ```
194
194
 
195
195
  ### Smooth Interpolation
196
196
 
197
197
  ```typescript
198
- import { PointCal, Point } from '@ue-too/math';
198
+ import { Point, PointCal } from '@ue-too/math';
199
199
 
200
200
  // Animate between two positions
201
201
  const start: Point = { x: 0, y: 0 };
@@ -208,6 +208,7 @@ const currentPos = PointCal.linearInterpolation(start, end, progress);
208
208
  ## API Reference
209
209
 
210
210
  For complete API documentation with detailed examples, see:
211
+
211
212
  - [Full TypeDoc Documentation](/math/) (generated from source)
212
213
  - [Source Code](https://github.com/ue-too/ue-too/blob/main/packages/math/src/index.ts) with inline JSDoc comments
213
214
 
package/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { Point } from './2dVector';
1
2
  /**
2
3
  * @packageDocumentation
3
4
  * Mathematical utilities for 2D and 3D point operations, vector calculations, and transformations.
@@ -64,30 +65,6 @@ export type point = {
64
65
  /** Optional Z-coordinate for 3D operations */
65
66
  z?: number;
66
67
  };
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
- */
83
- export type Point = {
84
- /** X-coordinate */
85
- x: number;
86
- /** Y-coordinate */
87
- y: number;
88
- /** Optional Z-coordinate for 3D operations */
89
- z?: number;
90
- };
91
68
  /**
92
69
  * Utility class for point and vector calculations.
93
70
  *
@@ -675,3 +652,5 @@ export declare function directionAlignedToTangent(direction: Point, tangent: Poi
675
652
  * @category Comparison
676
653
  */
677
654
  export declare function samePoint(a: Point, b: Point, precision?: number): boolean;
655
+ export * from './matrix';
656
+ export * from './2dVector';
package/index.js CHANGED
@@ -1,5 +1,5 @@
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};
1
+ class O{_matrix;_inverse=null;constructor(j){this._matrix=j;this._inverse=q(this._matrix)}get inverse(){return this._inverse}setMatrix(j){this._matrix=j,this._inverse=q(j)}transformPoint(j){return E(j,this._matrix)}invertPoint(j){if(!this._inverse)return null;return E(j,this._inverse)}}function q(j){let{a:J,b:K,c:Q,d:_,e:$,f:X,g:H,h:L,i:R}=j,W=J*(_*R-X*L)-Q*(K*R-X*H)+$*(K*L-_*H);if(Math.abs(W)<0.0000000001)return null;let G=1/W,M=(_*R-X*L)*G,Y=(X*H-K*R)*G,N=($*L-Q*R)*G,S=(J*R-$*H)*G,z=(Q*X-$*_)*G,T=($*K-J*X)*G,V=(K*L-_*H)*G,w=(Q*H-J*L)*G,v=(J*_-Q*K)*G;return{a:M,b:Y,c:N,d:S,e:z,f:T,g:V,h:w,i:v}}function E(j,J){let{x:K,y:Q}=j,{a:_,b:$,c:X,d:H,e:L,f:R,g:W,h:G,i:M}=J,Y=W*K+G*Q+M;return{x:(_*K+X*Q+L)/Y,y:($*K+H*Q+R)/Y}}var C=(j,J)=>{if(j.z==null&&J.z==null)return{x:j.x+J.x,y:j.y+J.y};if(j.z==null||J.z==null){if(j.z==null)j.z=0;if(J.z==null)J.z=0}return{x:j.x+J.x,y:j.y+J.y,z:j.z+J.z}},Z=(j,J)=>{if(j.z==null&&J.z==null)return{x:j.x-J.x,y:j.y-J.y};if(j.z==null||J.z==null){if(j.z==null)j.z=0;if(J.z==null)J.z=0}return{x:j.x-J.x,y:j.y-J.y,z:j.z-J.z}},f=(j,J)=>{if(j.z==null)return{x:j.x*J,y:j.y*J};return{x:j.x*J,y:j.y*J,z:j.z*J}},A=(j,J)=>{if(J==0)return{x:j.x,y:j.y};if(j.z==null)return{x:j.x/J,y:j.y/J};return{x:j.x/J,y:j.y/J,z:j.z/J}},k=(j)=>{if(j.z==null)j.z=0;return Math.sqrt(j.x*j.x+j.y*j.y+j.z*j.z)},y=(j)=>{if(j.z==null)j.z=0;let J=k(j);return J!=0?{x:j.x/J,y:j.y/J,z:j.z/J}:{x:0,y:0,z:0}},x=(j,J)=>{if(j.z==null&&J.z==null)return j.x*J.x+j.y*J.y;if(j.z==null||J.z==null){if(j.z==null)j.z=0;if(J.z==null)J.z=0}return j.x*J.x+j.y*J.y+j.z*J.z},c=(j,J)=>{if(j.z==null||J.z==null){if(j.z==null)j.z=0;if(J.z==null)J.z=0}return{x:j.y*J.z-j.z*J.y,y:j.z*J.x-j.x*J.z,z:j.x*J.y-j.y*J.x}},d=(j,J)=>{return y(Z(J,j))},F=(j,J)=>{return{x:j.x*Math.cos(J)-j.y*Math.sin(J),y:j.x*Math.sin(J)+j.y*Math.cos(J)}},m=(j,J)=>{return{x:j.x*Math.cos(J)+j.y*Math.sin(J),y:-j.x*Math.sin(J)+j.y*Math.cos(J)}},p=(j,J)=>{return Math.atan2(j.x*J.y-j.y*J.x,j.x*J.x+j.y*J.y)},P=(j,J,K)=>{let Q=F(Z(j,J),K);return C(Q,J)},g=(j,J)=>{return k(Z(j,J))},l=(j)=>{return{x:j.x,y:-j.y,z:j.z}},u=(j,J,K)=>{if(j.z==null||J.z==null)return{x:j.x+(J.x-j.x)*K,y:j.y+(J.y-j.y)*K};else return{x:j.x+(J.x-j.x)*K,y:j.y+(J.y-j.y)*K,z:j.z+(J.z-j.z)*K}},s=(j,J)=>{if(j.z==null)j.z=0;if(J.z==null)J.z=0;return j.x==J.x&&j.y==J.y&&j.z==J.z},r=(j,J,K,Q)=>{let _=(Q.x-K.x)*(j.y-K.y)-(Q.y-K.y)*(j.x-K.x),$=(Q.y-K.y)*(J.x-j.x)-(Q.x-K.x)*(J.y-j.y);if($===0)return{intersects:!1};let X=_/$;if(X>=0&&X<=1)return{intersects:!0,intersection:u(j,J,X),offset:X};else return{intersects:!1}};class U{static addVector(j,J){if(j.z==null&&J.z==null)return{x:j.x+J.x,y:j.y+J.y};if(j.z==null||J.z==null){if(j.z==null)j.z=0;if(J.z==null)J.z=0}return{x:j.x+J.x,y:j.y+J.y,z:j.z+J.z}}static subVector(j,J){if(j.z==null&&J.z==null)return{x:j.x-J.x,y:j.y-J.y};if(j.z==null||J.z==null){if(j.z==null)j.z=0;if(J.z==null)J.z=0}return{x:j.x-J.x,y:j.y-J.y,z:j.z-J.z}}static multiplyVectorByScalar(j,J){if(j.z==null)return{x:j.x*J,y:j.y*J};return{x:j.x*J,y:j.y*J,z:j.z*J}}static divideVectorByScalar(j,J){if(J==0)return{x:j.x,y:j.y};if(j.z==null)return{x:j.x/J,y:j.y/J};return{x:j.x/J,y:j.y/J,z:j.z/J}}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,J){if(j.z==null&&J.z==null)return j.x*J.x+j.y*J.y;if(j.z==null||J.z==null){if(j.z==null)j.z=0;if(J.z==null)J.z=0}return j.x*J.x+j.y*J.y+j.z*J.z}static crossProduct(j,J){if(j.z==null||J.z==null){if(j.z==null)j.z=0;if(J.z==null)J.z=0}return{x:j.y*J.z-j.z*J.y,y:j.z*J.x-j.x*J.z,z:j.x*J.y-j.y*J.x}}static unitVectorFromA2B(j,J){return this.unitVector(this.subVector(J,j))}static rotatePoint(j,J){return{x:j.x*Math.cos(J)-j.y*Math.sin(J),y:j.x*Math.sin(J)+j.y*Math.cos(J)}}static transform2NewAxis(j,J){return{x:j.x*Math.cos(J)+j.y*Math.sin(J),y:-j.x*Math.sin(J)+j.y*Math.cos(J)}}static angleFromA2B(j,J){return Math.atan2(j.x*J.y-j.y*J.x,j.x*J.x+j.y*J.y)}static transformPointWRTAnchor(j,J,K){let Q=this.rotatePoint(this.subVector(j,J),K);return this.addVector(Q,J)}static distanceBetweenPoints(j,J){return this.magnitude(this.subVector(j,J))}static flipYAxis(j){return{x:j.x,y:-j.y,z:j.z}}static linearInterpolation(j,J,K){if(j.z==null||J.z==null)return{x:j.x+(J.x-j.x)*K,y:j.y+(J.y-j.y)*K};else return{x:j.x+(J.x-j.x)*K,y:j.y+(J.y-j.y)*K,z:j.z+(J.z-j.z)*K}}static isEqual(j,J){if(j.z==null)j.z=0;if(J.z==null)J.z=0;return j.x==J.x&&j.y==J.y&&j.z==J.z}static getLineIntersection(j,J,K,Q){let _=(Q.x-K.x)*(j.y-K.y)-(Q.y-K.y)*(j.x-K.x),$=(Q.y-K.y)*(J.x-j.x)-(Q.x-K.x)*(J.y-j.y);if($===0)return{intersects:!1};let X=_/$;if(X>=0&&X<=1)return{intersects:!0,intersection:U.linearInterpolation(j,J,X),offset:X};else return{intersects:!1}}}function B(j){return j=j%(Math.PI*2),j=(j+Math.PI*2)%(Math.PI*2),j}function b(j,J){j=B(j),J=B(J);let K=J-j;if(K>Math.PI)K=-(Math.PI*2-K);if(K<-Math.PI)K+=Math.PI*2;return K}function I(j,J,K){return Math.abs(j-J)<=(K||0.000001)}function o(j,J,K=0.001){let Q=U.unitVector(j),_=U.unitVector(J);return h(Q,_,K)}function i(j,J){let K=U.unitVector(j),Q=U.unitVector(J),_={x:-J.x,y:-J.y,z:J.z},$=U.angleFromA2B(K,Q),X=U.angleFromA2B(K,_);return $<Math.PI/2&&$>-Math.PI/2&&(X>Math.PI/2||X<-Math.PI/2)}function h(j,J,K){if(I(j.x,J.x,K)&&I(j.y,J.y,K))return!0;return!1}export{d as unitVectorFromA2B,y as unitVector,P as transformPointWRTAnchor,m as transform2NewAxis,Z as subVector,h as samePoint,o as sameDirection,F as rotatePoint,B as normalizeAngleZero2TwoPI,f as multiplyVectorByScalar,k as magnitude,u as linearInterpolation,s as isEqual,q as inverseMatrix3x3,r as getLineIntersection,l as flipYAxis,x as dotProduct,A as divideVectorByScalar,g as distanceBetweenPoints,i as directionAlignedToTangent,c as crossProduct,I as approximatelyTheSame,b as angleSpan,p as angleFromA2B,C as addVector,U as PointCal,O as Matrix};
2
2
 
3
- //# debugId=E7FBAB931781982464756E2164756E21
3
+ //# debugId=4EFEFB3D0526414A64756E2164756E21
4
4
 
5
5
  //# sourceMappingURL=index.js.map
package/index.js.map CHANGED
@@ -1,12 +1,16 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": [
4
+ "matrix.ts",
5
+ "2dVector.ts",
4
6
  "index.ts"
5
7
  ],
6
8
  "sourcesContent": [
7
- "/**\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"
9
+ "import type { Point } from './2dVector';\n\nexport class Matrix {\n private _inverse: Matrix3x3 | null = null;\n\n constructor(private _matrix: Matrix3x3) {\n this._inverse = inverseMatrix3x3(this._matrix);\n }\n\n get inverse(): Matrix3x3 | null {\n return this._inverse;\n }\n\n setMatrix(matrix: Matrix3x3): void {\n this._matrix = matrix;\n this._inverse = inverseMatrix3x3(matrix);\n }\n\n transformPoint(point: Point): Point {\n return transformPoint(point, this._matrix);\n }\n\n invertPoint(point: Point): Point | null {\n if (!this._inverse) {\n return null;\n }\n return transformPoint(point, this._inverse);\n }\n}\n\nexport interface Matrix3x3 {\n a: number;\n c: number;\n e: number;\n b: number;\n d: number;\n f: number;\n g: number;\n h: number;\n i: number;\n}\n\nexport function inverseMatrix3x3(m: Matrix3x3): Matrix3x3 | null {\n const { a, b, c, d, e, f, g, h, i } = m;\n\n // Matrix layout:\n // | a c e |\n // | b d f |\n // | g h i |\n\n // Calculate determinant\n const det = a * (d * i - f * h) - c * (b * i - f * g) + e * (b * h - d * g);\n\n // Check if matrix is singular (non-invertible)\n if (Math.abs(det) < 1e-10) {\n return null; // Matrix is not invertible\n }\n\n // Calculate inverse using adjugate matrix divided by determinant\n const invDet = 1 / det;\n\n const A = (d * i - f * h) * invDet;\n const B = (f * g - b * i) * invDet;\n const C = (e * h - c * i) * invDet;\n const D = (a * i - e * g) * invDet;\n const E = (c * f - e * d) * invDet;\n const F = (e * b - a * f) * invDet;\n const G = (b * h - d * g) * invDet;\n const H = (c * g - a * h) * invDet;\n const I = (a * d - c * b) * invDet;\n\n return {\n a: A,\n b: B,\n c: C,\n d: D,\n e: E,\n f: F,\n g: G,\n h: H,\n i: I,\n };\n}\n\nfunction transformPoint(point: Point, matrix: Matrix3x3): Point {\n const { x, y } = point;\n const { a, b, c, d, e, f, g, h, i } = matrix;\n\n // Matrix layout:\n // | a c e |\n // | b d f |\n // | g h i |\n\n // For homogeneous coordinates [x, y, 1]:\n const w = g * x + h * y + i;\n\n return {\n x: (a * x + c * y + e) / w,\n y: (b * x + d * y + f) / w,\n };\n}\n",
10
+ "/**\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\nconst addVector = (a: Point, b: 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\nconst 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\nconst 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\nconst 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\nconst 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\nconst unitVector = (a: Point): Point => {\n if (a.z == null) a.z = 0;\n const mag = magnitude(a);\n return mag != 0\n ? {\n x: a.x / mag,\n y: a.y / mag,\n z: a.z / mag,\n }\n : { x: 0, y: 0, z: 0 };\n};\n\nconst 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\nconst 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 {\n x: a.y * b.z - a.z * b.y,\n y: a.z * b.x - a.x * b.z,\n z: a.x * b.y - a.y * b.x,\n };\n};\n\nconst unitVectorFromA2B = (a: Point, b: Point): Point => {\n return unitVector(subVector(b, a));\n};\n\nconst rotatePoint = (point: Point, angle: number): Point => {\n return {\n x: point.x * Math.cos(angle) - point.y * Math.sin(angle),\n y: point.x * Math.sin(angle) + point.y * Math.cos(angle),\n };\n};\n\nconst transform2NewAxis = (\n point: Point,\n angleFromOriginalAxis2DestAxis: number\n): Point => {\n // angle is the angle from the original axis to the destination axis ccw is positive as always\n return {\n x:\n point.x * Math.cos(angleFromOriginalAxis2DestAxis) +\n point.y * Math.sin(angleFromOriginalAxis2DestAxis),\n y:\n -point.x * Math.sin(angleFromOriginalAxis2DestAxis) +\n point.y * Math.cos(angleFromOriginalAxis2DestAxis),\n };\n};\n\nconst 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\nconst transformPointWRTAnchor = (\n point: Point,\n anchor: Point,\n angle: number\n): Point => {\n // angle is in radians\n let newPoint = rotatePoint(subVector(point, anchor), angle);\n return addVector(newPoint, anchor);\n};\n\nconst distanceBetweenPoints = (a: Point, b: Point): number => {\n return magnitude(subVector(a, b));\n};\n\nconst flipYAxis = (point: Point): Point => {\n return { x: point.x, y: -point.y, z: point.z };\n};\n\nconst 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 {\n x: a.x + (b.x - a.x) * t,\n y: a.y + (b.y - a.y) * t,\n z: a.z + (b.z - a.z) * t,\n };\n }\n};\n\nconst 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\nconst getLineIntersection = (\n startPoint: Point,\n endPoint: Point,\n startPoint2: Point,\n endPoint2: Point\n): {\n intersects: boolean;\n intersection?: Point;\n offset?: number;\n} => {\n const numerator =\n (endPoint2.x - startPoint2.x) * (startPoint.y - startPoint2.y) -\n (endPoint2.y - startPoint2.y) * (startPoint.x - startPoint2.x);\n const denominator =\n (endPoint2.y - startPoint2.y) * (endPoint.x - startPoint.x) -\n (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: linearInterpolation(startPoint, endPoint, t),\n offset: t,\n };\n } else {\n return {\n intersects: false,\n };\n }\n};\n\nexport {\n addVector,\n subVector,\n multiplyVectorByScalar,\n divideVectorByScalar,\n magnitude,\n unitVector,\n dotProduct,\n crossProduct,\n unitVectorFromA2B,\n rotatePoint,\n transform2NewAxis,\n angleFromA2B,\n transformPointWRTAnchor,\n distanceBetweenPoints,\n flipYAxis,\n linearInterpolation,\n isEqual,\n getLineIntersection,\n};\n",
11
+ "import type { Point } from './2dVector';\n\n/**\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 * 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 * 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\n ? {\n x: a.x / this.magnitude(a),\n y: a.y / this.magnitude(a),\n z: a.z / this.magnitude(a),\n }\n : { 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 {\n x: a.y * b.z - a.z * b.y,\n y: a.z * b.x - a.x * b.z,\n z: a.x * b.y - a.y * b.x,\n };\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 {\n x: point.x * Math.cos(angle) - point.y * Math.sin(angle),\n y: point.x * Math.sin(angle) + point.y * Math.cos(angle),\n };\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(\n point: point,\n angleFromOriginalAxis2DestAxis: number\n ): Point {\n // angle is the angle from the original axis to the destination axis ccw is positive as always\n return {\n x:\n point.x * Math.cos(angleFromOriginalAxis2DestAxis) +\n point.y * Math.sin(angleFromOriginalAxis2DestAxis),\n y:\n -point.x * Math.sin(angleFromOriginalAxis2DestAxis) +\n point.y * Math.cos(angleFromOriginalAxis2DestAxis),\n };\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(\n point: point,\n anchor: point,\n angle: number\n ): 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 {\n x: a.x + (b.x - a.x) * t,\n y: a.y + (b.y - a.y) * t,\n z: a.z + (b.z - a.z) * t,\n };\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(\n startPoint: Point,\n endPoint: Point,\n startPoint2: Point,\n endPoint2: Point\n ): {\n intersects: boolean;\n intersection?: Point;\n offset?: number;\n } {\n const numerator =\n (endPoint2.x - startPoint2.x) * (startPoint.y - startPoint2.y) -\n (endPoint2.y - startPoint2.y) * (startPoint.x - startPoint2.x);\n const denominator =\n (endPoint2.y - startPoint2.y) * (endPoint.x - startPoint.x) -\n (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(\n startPoint,\n endPoint,\n t\n ),\n offset: t,\n };\n } else {\n return {\n intersects: false,\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(\n a: number,\n b: number,\n precision?: number\n): 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(\n a: Point,\n b: Point,\n precision: number = 0.001\n): 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(\n direction: Point,\n tangent: Point\n): 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 (\n angle < Math.PI / 2 &&\n angle > -Math.PI / 2 &&\n (angle2 > Math.PI / 2 || angle2 < -Math.PI / 2)\n );\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 (\n approximatelyTheSame(a.x, b.x, precision) &&\n approximatelyTheSame(a.y, b.y, precision)\n ) {\n return true;\n }\n return false;\n}\n\nexport * from './matrix';\nexport * from './2dVector';\n"
8
12
  ],
9
- "mappings": "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",
10
- "debugId": "E7FBAB931781982464756E2164756E21",
13
+ "mappings": "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",
14
+ "debugId": "4EFEFB3D0526414A64756E2164756E21",
11
15
  "names": []
12
16
  }
package/matrix.d.ts ADDED
@@ -0,0 +1,22 @@
1
+ import type { Point } from './2dVector';
2
+ export declare class Matrix {
3
+ private _matrix;
4
+ private _inverse;
5
+ constructor(_matrix: Matrix3x3);
6
+ get inverse(): Matrix3x3 | null;
7
+ setMatrix(matrix: Matrix3x3): void;
8
+ transformPoint(point: Point): Point;
9
+ invertPoint(point: Point): Point | null;
10
+ }
11
+ export interface Matrix3x3 {
12
+ a: number;
13
+ c: number;
14
+ e: number;
15
+ b: number;
16
+ d: number;
17
+ f: number;
18
+ g: number;
19
+ h: number;
20
+ i: number;
21
+ }
22
+ export declare function inverseMatrix3x3(m: Matrix3x3): Matrix3x3 | null;
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.14.0",
5
+ "version": "0.15.0",
6
6
  "description": "Math utilities for uē-tôo",
7
7
  "license": "MIT",
8
8
  "repository": {