@vived/core 2.0.1 → 2.0.2
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 +275 -65
- package/dist/cjs/ExampleFeature/index.js +23 -0
- package/dist/cjs/ExampleFeature/index.js.map +1 -0
- package/dist/esm/ExampleFeature/index.js +7 -0
- package/dist/esm/ExampleFeature/index.js.map +1 -0
- package/dist/types/ExampleFeature/index.d.ts +5 -0
- package/dist/types/ExampleFeature/index.d.ts.map +1 -0
- package/package.json +3 -2
- package/src/AppObject/README.md +476 -0
- package/src/DomainFactories/README.md +154 -0
- package/src/Entities/README.md +340 -0
- package/src/ExampleFeature/README.md +804 -0
- package/src/Types/README.md +549 -0
- package/src/Utilities/README.md +478 -0
- package/src/ValueObjects/README.md +552 -0
|
@@ -0,0 +1,552 @@
|
|
|
1
|
+
# ValueObjects
|
|
2
|
+
|
|
3
|
+
The ValueObjects folder provides immutable, mathematical primitives for 3D graphics, geometry, and data representation. These classes follow the Value Object pattern - they are immutable, comparable by value, and provide rich static methods for common operations.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Value objects are designed to be:
|
|
8
|
+
- **Immutable** - Once created, their values cannot change
|
|
9
|
+
- **Comparable** - Equality is based on values, not identity
|
|
10
|
+
- **Self-contained** - Include all operations relevant to their domain
|
|
11
|
+
- **Framework-agnostic** - Pure TypeScript with no external dependencies
|
|
12
|
+
|
|
13
|
+
## Mathematical Types
|
|
14
|
+
|
|
15
|
+
### Vector3
|
|
16
|
+
|
|
17
|
+
3D vector with comprehensive linear algebra operations.
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { Vector3 } from "@vived/core";
|
|
21
|
+
|
|
22
|
+
// Factory methods
|
|
23
|
+
const zero = Vector3.Zero(); // [0,0,0]
|
|
24
|
+
const one = Vector3.One(); // [1,1,1]
|
|
25
|
+
const up = Vector3.Up(); // [0,1,0]
|
|
26
|
+
const down = Vector3.Down(); // [0,-1,0]
|
|
27
|
+
const right = Vector3.Right(); // [1,0,0]
|
|
28
|
+
const left = Vector3.Left(); // [-1,0,0]
|
|
29
|
+
const forward = Vector3.Forward(); // [0,0,1]
|
|
30
|
+
const backward = Vector3.Backward(); // [0,0,-1]
|
|
31
|
+
|
|
32
|
+
// Create from components
|
|
33
|
+
const position = new Vector3(10, 20, 30);
|
|
34
|
+
|
|
35
|
+
// Vector operations
|
|
36
|
+
const a = new Vector3(1, 2, 3);
|
|
37
|
+
const b = new Vector3(4, 5, 6);
|
|
38
|
+
|
|
39
|
+
const sum = Vector3.Add(a, b);
|
|
40
|
+
const difference = Vector3.Subtract(a, b);
|
|
41
|
+
const dot = Vector3.Dot(a, b);
|
|
42
|
+
const cross = Vector3.Cross(a, b);
|
|
43
|
+
|
|
44
|
+
// Vector properties
|
|
45
|
+
console.log(a.magnitude); // Length of vector
|
|
46
|
+
console.log(a.unit); // Normalized vector
|
|
47
|
+
console.log(a.array); // [1, 2, 3]
|
|
48
|
+
console.log(a.dto); // { x: 1, y: 2, z: 3 }
|
|
49
|
+
|
|
50
|
+
// Comparison
|
|
51
|
+
const equal = Vector3.Equal(a, b);
|
|
52
|
+
const close = Vector3.Close(a, b, 0.01); // Within tolerance
|
|
53
|
+
|
|
54
|
+
// Transformations
|
|
55
|
+
const scaled = Vector3.NewVectorOfLength(a, 10);
|
|
56
|
+
const lerped = Vector3.Lerp(a, b, 0.5); // 50% between a and b
|
|
57
|
+
const transformed = Vector3.Transform(a, matrix);
|
|
58
|
+
|
|
59
|
+
// Serialization
|
|
60
|
+
const fromArray = Vector3.FromArray([1, 2, 3]);
|
|
61
|
+
const fromDTO = Vector3.FromDTO({ x: 1, y: 2, z: 3 });
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Vector2
|
|
65
|
+
|
|
66
|
+
2D vector with rotation and geometric operations.
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
import { Vector2, Angle } from "@vived/core";
|
|
70
|
+
|
|
71
|
+
// Factory methods
|
|
72
|
+
const zero = Vector2.Zero(); // [0,0]
|
|
73
|
+
const one = Vector2.One(); // [1,1]
|
|
74
|
+
|
|
75
|
+
// Create and manipulate
|
|
76
|
+
const a = new Vector2(3, 4);
|
|
77
|
+
const b = new Vector2(1, 1);
|
|
78
|
+
|
|
79
|
+
const sum = Vector2.Add(a, b);
|
|
80
|
+
const difference = Vector2.Subtract(a, b);
|
|
81
|
+
const dot = Vector2.Dot(a, b);
|
|
82
|
+
const cross = Vector2.Cross(a, b); // Returns scalar
|
|
83
|
+
|
|
84
|
+
// Properties
|
|
85
|
+
console.log(a.magnitude); // 5
|
|
86
|
+
console.log(a.unit); // Normalized vector
|
|
87
|
+
|
|
88
|
+
// Rotation
|
|
89
|
+
const rotated = Vector2.Rotate(a, Angle.FromDegrees(45));
|
|
90
|
+
|
|
91
|
+
// Scaling
|
|
92
|
+
const scaled = Vector2.Scale(a, 2);
|
|
93
|
+
const resized = Vector2.NewVectorOfLength(a, 10);
|
|
94
|
+
|
|
95
|
+
// Angles
|
|
96
|
+
const angleBetween = Vector2.AngleBetween(a, b);
|
|
97
|
+
|
|
98
|
+
// Comparison
|
|
99
|
+
const equal = Vector2.Equal(a, b);
|
|
100
|
+
const close = Vector2.Close(a, b, 0.01);
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Quaternion
|
|
104
|
+
|
|
105
|
+
Rotation representation with comprehensive conversion methods.
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
import { Quaternion, Angle, Vector3 } from "@vived/core";
|
|
109
|
+
|
|
110
|
+
// Factory methods
|
|
111
|
+
const identity = Quaternion.Identity();
|
|
112
|
+
|
|
113
|
+
// From angle-axis
|
|
114
|
+
const q1 = Quaternion.FromAngleAxis(
|
|
115
|
+
Vector3.Up(),
|
|
116
|
+
Angle.FromDegrees(90)
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
// From Euler angles
|
|
120
|
+
const q2 = Quaternion.FromEuler(
|
|
121
|
+
Angle.FromDegrees(0),
|
|
122
|
+
Angle.FromDegrees(90),
|
|
123
|
+
Angle.FromDegrees(0)
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
// From Yaw-Pitch-Roll
|
|
127
|
+
const q3 = Quaternion.FromYawPitchRoll(
|
|
128
|
+
Angle.FromDegrees(45), // Yaw
|
|
129
|
+
Angle.FromDegrees(0), // Pitch
|
|
130
|
+
Angle.FromDegrees(0) // Roll
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
// From direction vector
|
|
134
|
+
const q4 = Quaternion.FromDirectionVector(Vector3.Forward());
|
|
135
|
+
|
|
136
|
+
// Operations
|
|
137
|
+
const multiplied = Quaternion.Multiply(q1, q2);
|
|
138
|
+
const inverted = Quaternion.Inverse(q1);
|
|
139
|
+
const angleBetween = Quaternion.AngleBetween(q1, q2);
|
|
140
|
+
|
|
141
|
+
// Comparison
|
|
142
|
+
const equal = Quaternion.Equal(q1, q2);
|
|
143
|
+
const close = Quaternion.Close(q1, q2, 0.001);
|
|
144
|
+
|
|
145
|
+
// Conversion to Euler
|
|
146
|
+
const eulerAngles = q1.toEuler(); // { pitch, yaw, roll }
|
|
147
|
+
|
|
148
|
+
// Serialization
|
|
149
|
+
const array = q1.toArray(); // [x, y, z, w]
|
|
150
|
+
const dto = q1.toDTO(); // { x, y, z, w }
|
|
151
|
+
const fromDTO = Quaternion.FromDTO({ x: 0, y: 0, z: 0, w: 1 });
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Matrix
|
|
155
|
+
|
|
156
|
+
4x4 transformation matrix for 3D graphics.
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
import { Matrix, Vector3, Quaternion, Angle } from "@vived/core";
|
|
160
|
+
|
|
161
|
+
// Factory methods
|
|
162
|
+
const identity = Matrix.Identity();
|
|
163
|
+
const zero = Matrix.Zero();
|
|
164
|
+
|
|
165
|
+
// Transformation matrices
|
|
166
|
+
const translation = Matrix.Translation(new Vector3(10, 20, 30));
|
|
167
|
+
const scale = Matrix.Scaling(new Vector3(2, 2, 2));
|
|
168
|
+
const rotation = Matrix.RotationYawPitchRoll(
|
|
169
|
+
Angle.FromDegrees(0),
|
|
170
|
+
Angle.FromDegrees(90),
|
|
171
|
+
Angle.FromDegrees(0)
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
// From quaternion
|
|
175
|
+
const rotationQ = Matrix.FromQuaternion(quaternion);
|
|
176
|
+
|
|
177
|
+
// Matrix operations
|
|
178
|
+
const product = Matrix.Multiply(translation, rotation);
|
|
179
|
+
const inverted = Matrix.Invert(matrix);
|
|
180
|
+
const transposed = Matrix.Transpose(matrix);
|
|
181
|
+
|
|
182
|
+
// Decomposition
|
|
183
|
+
const decomposed = matrix.decompose(); // { translation, rotation, scale }
|
|
184
|
+
|
|
185
|
+
// Comparison
|
|
186
|
+
const equal = Matrix.Equal(m1, m2);
|
|
187
|
+
const close = Matrix.Close(m1, m2, 0.001);
|
|
188
|
+
|
|
189
|
+
// Access raw data
|
|
190
|
+
const array = matrix.m; // Float32Array of 16 elements
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Angle
|
|
194
|
+
|
|
195
|
+
Type-safe angle representation with automatic conversion between degrees and radians.
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
import { Angle } from "@vived/core";
|
|
199
|
+
|
|
200
|
+
// Create from degrees or radians
|
|
201
|
+
const angle1 = Angle.FromDegrees(90);
|
|
202
|
+
const angle2 = Angle.FromRadians(Math.PI / 2);
|
|
203
|
+
|
|
204
|
+
// Access both representations
|
|
205
|
+
console.log(angle1.degrees); // 90
|
|
206
|
+
console.log(angle1.radians); // ~1.5708
|
|
207
|
+
|
|
208
|
+
// Comparison
|
|
209
|
+
const equal = angle1.degrees === angle2.degrees;
|
|
210
|
+
const close = Angle.Close(angle1, angle2, 0.001);
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
## Geometric Types
|
|
214
|
+
|
|
215
|
+
### LineSegment2D
|
|
216
|
+
|
|
217
|
+
2D line segment with intersection and projection operations.
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
220
|
+
import { LineSegment2D, Vector2 } from "@vived/core";
|
|
221
|
+
|
|
222
|
+
const line = new LineSegment2D(
|
|
223
|
+
new Vector2(0, 0),
|
|
224
|
+
new Vector2(10, 10)
|
|
225
|
+
);
|
|
226
|
+
|
|
227
|
+
// Properties
|
|
228
|
+
console.log(line.length); // Length of segment
|
|
229
|
+
console.log(line.direction); // Unit direction vector
|
|
230
|
+
|
|
231
|
+
// Position along line
|
|
232
|
+
const midpoint = LineSegment2D.GetPositionAtPercent(line, 0.5);
|
|
233
|
+
|
|
234
|
+
// Intersection
|
|
235
|
+
const line2 = new LineSegment2D(
|
|
236
|
+
new Vector2(0, 10),
|
|
237
|
+
new Vector2(10, 0)
|
|
238
|
+
);
|
|
239
|
+
const intersection = LineSegment2D.Intersect(line, line2);
|
|
240
|
+
|
|
241
|
+
// Closest point
|
|
242
|
+
const point = new Vector2(5, 0);
|
|
243
|
+
const closest = LineSegment2D.ClosestPointOnLine(line, point);
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### ParametricLine
|
|
247
|
+
|
|
248
|
+
3D parametric line representation.
|
|
249
|
+
|
|
250
|
+
```typescript
|
|
251
|
+
import { ParametricLine, Vector3 } from "@vived/core";
|
|
252
|
+
|
|
253
|
+
// Factory methods
|
|
254
|
+
const forward = ParametricLine.Forward();
|
|
255
|
+
const up = ParametricLine.Up();
|
|
256
|
+
const right = ParametricLine.Right();
|
|
257
|
+
|
|
258
|
+
// From two points
|
|
259
|
+
const line1 = ParametricLine.FromTwoPoint(
|
|
260
|
+
new Vector3(0, 0, 0),
|
|
261
|
+
new Vector3(1, 1, 1)
|
|
262
|
+
);
|
|
263
|
+
|
|
264
|
+
// From point and direction
|
|
265
|
+
const line2 = ParametricLine.FromPointDirection(
|
|
266
|
+
Vector3.Zero(),
|
|
267
|
+
Vector3.Up()
|
|
268
|
+
);
|
|
269
|
+
|
|
270
|
+
// Get point at distance
|
|
271
|
+
const point = ParametricLine.GetPointAtDistance(line1, 5);
|
|
272
|
+
|
|
273
|
+
// Properties
|
|
274
|
+
console.log(line1.origin); // Starting point
|
|
275
|
+
console.log(line1.direction); // Direction vector
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### ParametricPlane
|
|
279
|
+
|
|
280
|
+
3D plane representation with intersection calculations.
|
|
281
|
+
|
|
282
|
+
```typescript
|
|
283
|
+
import { ParametricPlane, Vector3, ParametricLine } from "@vived/core";
|
|
284
|
+
|
|
285
|
+
// Factory methods
|
|
286
|
+
const xy = ParametricPlane.XY(); // Z = 0
|
|
287
|
+
const zx = ParametricPlane.ZX(); // Y = 0
|
|
288
|
+
const yz = ParametricPlane.YZ(); // X = 0
|
|
289
|
+
|
|
290
|
+
// From point and normal
|
|
291
|
+
const plane1 = ParametricPlane.FromPointNormal(
|
|
292
|
+
new Vector3(0, 0, 0),
|
|
293
|
+
Vector3.Up()
|
|
294
|
+
);
|
|
295
|
+
|
|
296
|
+
// From three points
|
|
297
|
+
const plane2 = ParametricPlane.FromThreePoints(
|
|
298
|
+
new Vector3(0, 0, 0),
|
|
299
|
+
new Vector3(1, 0, 0),
|
|
300
|
+
new Vector3(0, 1, 0)
|
|
301
|
+
);
|
|
302
|
+
|
|
303
|
+
// Get plane equation (ax + by + cz + d = 0)
|
|
304
|
+
const params = plane1.GetParameters(); // { a, b, c, d }
|
|
305
|
+
|
|
306
|
+
// Intersection with line
|
|
307
|
+
const line = ParametricLine.Forward();
|
|
308
|
+
const intersection = plane1.intersectLine(line); // Vector3 or undefined
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### Rectangle
|
|
312
|
+
|
|
313
|
+
2D rectangular bounds.
|
|
314
|
+
|
|
315
|
+
```typescript
|
|
316
|
+
import { Rectangle } from "@vived/core";
|
|
317
|
+
|
|
318
|
+
const rect = new Rectangle(
|
|
319
|
+
0, // top
|
|
320
|
+
100, // right
|
|
321
|
+
100, // bottom
|
|
322
|
+
0 // left
|
|
323
|
+
);
|
|
324
|
+
|
|
325
|
+
// Properties
|
|
326
|
+
console.log(rect.top);
|
|
327
|
+
console.log(rect.right);
|
|
328
|
+
console.log(rect.bottom);
|
|
329
|
+
console.log(rect.left);
|
|
330
|
+
|
|
331
|
+
// Serialization
|
|
332
|
+
const dto = rect.dto;
|
|
333
|
+
const fromDTO = Rectangle.FromDTO(dto);
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
## Color Types
|
|
337
|
+
|
|
338
|
+
### Color
|
|
339
|
+
|
|
340
|
+
Immutable color with multiple creation methods and conversions.
|
|
341
|
+
|
|
342
|
+
```typescript
|
|
343
|
+
import { Color } from "@vived/core";
|
|
344
|
+
|
|
345
|
+
// Factory methods
|
|
346
|
+
const rgb = Color.RGB(255, 0, 0); // Red
|
|
347
|
+
const rgba = Color.RGBA(255, 0, 0, 128); // Semi-transparent red
|
|
348
|
+
const hex = Color.Hex("#FF0000");
|
|
349
|
+
const x11 = Color.X11("Red"); // X11 color names
|
|
350
|
+
|
|
351
|
+
// Color properties
|
|
352
|
+
console.log(rgb.r); // 0-255
|
|
353
|
+
console.log(rgb.g);
|
|
354
|
+
console.log(rgb.b);
|
|
355
|
+
console.log(rgb.a);
|
|
356
|
+
|
|
357
|
+
// As percentages
|
|
358
|
+
console.log(rgb.rPercent); // 0-1
|
|
359
|
+
console.log(rgb.gPercent);
|
|
360
|
+
console.log(rgb.bPercent);
|
|
361
|
+
console.log(rgb.aPercent);
|
|
362
|
+
|
|
363
|
+
// Conversions
|
|
364
|
+
console.log(rgb.hex); // "#ff0000"
|
|
365
|
+
console.log(rgb.array); // [255, 0, 0, 255]
|
|
366
|
+
console.log(rgb.dto); // { r: 255, g: 0, b: 0, a: 255 }
|
|
367
|
+
|
|
368
|
+
// Comparison
|
|
369
|
+
const equal = Color.Equal(color1, color2);
|
|
370
|
+
|
|
371
|
+
// Serialization
|
|
372
|
+
const fromDTO = Color.FromDTO({ r: 255, g: 0, b: 0, a: 255 });
|
|
373
|
+
|
|
374
|
+
// X11 colors
|
|
375
|
+
// Supports 140+ named colors like:
|
|
376
|
+
// "Red", "Blue", "Green", "White", "Black", "Gray"
|
|
377
|
+
// "LightBlue", "DarkRed", "MediumSeaGreen", etc.
|
|
378
|
+
const blue = Color.X11("Blue");
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
## Versioning
|
|
382
|
+
|
|
383
|
+
### Version
|
|
384
|
+
|
|
385
|
+
Semantic version comparison and management.
|
|
386
|
+
|
|
387
|
+
```typescript
|
|
388
|
+
import { Version, VersionStage } from "@vived/core";
|
|
389
|
+
|
|
390
|
+
// Parse version strings
|
|
391
|
+
const v1 = Version.FromString("1.2.3");
|
|
392
|
+
const v2 = Version.FromString("2.0.0-beta");
|
|
393
|
+
|
|
394
|
+
// Access components
|
|
395
|
+
console.log(v1.major); // 1
|
|
396
|
+
console.log(v1.minor); // 2
|
|
397
|
+
console.log(v1.patch); // 3
|
|
398
|
+
console.log(v2.stage); // VersionStage.BETA
|
|
399
|
+
|
|
400
|
+
// Find latest version
|
|
401
|
+
const versions = [
|
|
402
|
+
Version.FromString("1.0.0"),
|
|
403
|
+
Version.FromString("1.2.0"),
|
|
404
|
+
Version.FromString("2.0.0")
|
|
405
|
+
];
|
|
406
|
+
const latest = Version.GetLatest(versions); // 2.0.0
|
|
407
|
+
|
|
408
|
+
// Find latest with specific major
|
|
409
|
+
const latestV1 = Version.GetLatestWithMajor(versions, 1); // 1.2.0
|
|
410
|
+
|
|
411
|
+
// Find latest with specific major.minor
|
|
412
|
+
const latestV1_2 = Version.GetLatestWithMajorMinor(versions, 1, 2); // 1.2.0
|
|
413
|
+
|
|
414
|
+
// Version stages
|
|
415
|
+
VersionStage.RELEASED
|
|
416
|
+
VersionStage.BETA
|
|
417
|
+
VersionStage.ALPHA
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
## Design Principles
|
|
421
|
+
|
|
422
|
+
### Immutability
|
|
423
|
+
|
|
424
|
+
All value objects are immutable. Operations return new instances:
|
|
425
|
+
|
|
426
|
+
```typescript
|
|
427
|
+
const v1 = new Vector3(1, 2, 3);
|
|
428
|
+
const v2 = Vector3.Add(v1, Vector3.One()); // Returns new Vector3
|
|
429
|
+
// v1 remains unchanged
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
### Static Factory Methods
|
|
433
|
+
|
|
434
|
+
Use static methods for common operations to avoid creating intermediate objects:
|
|
435
|
+
|
|
436
|
+
```typescript
|
|
437
|
+
// Good - single object creation
|
|
438
|
+
const result = Vector3.Add(a, b);
|
|
439
|
+
|
|
440
|
+
// Avoid - creates temporary objects
|
|
441
|
+
const result = a.add(b); // If this existed
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
### Equality by Value
|
|
445
|
+
|
|
446
|
+
Value objects are compared by their values, not by reference:
|
|
447
|
+
|
|
448
|
+
```typescript
|
|
449
|
+
const a = new Vector3(1, 2, 3);
|
|
450
|
+
const b = new Vector3(1, 2, 3);
|
|
451
|
+
|
|
452
|
+
console.log(a === b); // false (different objects)
|
|
453
|
+
console.log(Vector3.Equal(a, b)); // true (same values)
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
### DTO Pattern
|
|
457
|
+
|
|
458
|
+
All complex value objects support Data Transfer Objects for serialization:
|
|
459
|
+
|
|
460
|
+
```typescript
|
|
461
|
+
// To DTO
|
|
462
|
+
const dto = vector.dto; // { x: 1, y: 2, z: 3 }
|
|
463
|
+
const json = JSON.stringify(dto);
|
|
464
|
+
|
|
465
|
+
// From DTO
|
|
466
|
+
const parsed = JSON.parse(json);
|
|
467
|
+
const vector = Vector3.FromDTO(parsed);
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
## Common Patterns
|
|
471
|
+
|
|
472
|
+
### Transformations
|
|
473
|
+
|
|
474
|
+
Chain transformations using matrix multiplication:
|
|
475
|
+
|
|
476
|
+
```typescript
|
|
477
|
+
const translation = Matrix.Translation(new Vector3(10, 0, 0));
|
|
478
|
+
const rotation = Matrix.RotationYawPitchRoll(
|
|
479
|
+
Angle.FromDegrees(45),
|
|
480
|
+
Angle.FromDegrees(0),
|
|
481
|
+
Angle.FromDegrees(0)
|
|
482
|
+
);
|
|
483
|
+
const scale = Matrix.Scaling(new Vector3(2, 2, 2));
|
|
484
|
+
|
|
485
|
+
// Order matters: Scale -> Rotate -> Translate
|
|
486
|
+
const transform = Matrix.Multiply(
|
|
487
|
+
translation,
|
|
488
|
+
Matrix.Multiply(rotation, scale)
|
|
489
|
+
);
|
|
490
|
+
|
|
491
|
+
const transformed = Vector3.Transform(position, transform);
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
### Rotations
|
|
495
|
+
|
|
496
|
+
Use quaternions for smooth rotations:
|
|
497
|
+
|
|
498
|
+
```typescript
|
|
499
|
+
// Create rotation
|
|
500
|
+
const rotation = Quaternion.FromAngleAxis(
|
|
501
|
+
Vector3.Up(),
|
|
502
|
+
Angle.FromDegrees(90)
|
|
503
|
+
);
|
|
504
|
+
|
|
505
|
+
// Convert to matrix for transformations
|
|
506
|
+
const matrix = Matrix.FromQuaternion(rotation);
|
|
507
|
+
|
|
508
|
+
// Apply to vector
|
|
509
|
+
const rotated = Vector3.Transform(vector, matrix);
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
### Interpolation
|
|
513
|
+
|
|
514
|
+
Lerp between values for smooth animations:
|
|
515
|
+
|
|
516
|
+
```typescript
|
|
517
|
+
const start = new Vector3(0, 0, 0);
|
|
518
|
+
const end = new Vector3(10, 10, 10);
|
|
519
|
+
|
|
520
|
+
// Animate from 0% to 100%
|
|
521
|
+
for (let t = 0; t <= 1; t += 0.1)
|
|
522
|
+
{
|
|
523
|
+
const position = Vector3.Lerp(start, end, t);
|
|
524
|
+
}
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
## Use Cases
|
|
528
|
+
|
|
529
|
+
- **3D Graphics** - Position, rotation, scale transformations
|
|
530
|
+
- **Game Development** - Entity positions, camera math, physics
|
|
531
|
+
- **Geometric Calculations** - Ray casting, collision detection, intersection tests
|
|
532
|
+
- **Animation** - Interpolation, rotation, smooth transitions
|
|
533
|
+
- **UI Layout** - 2D positioning, rectangular bounds
|
|
534
|
+
- **Data Serialization** - JSON-safe DTOs for network/storage
|
|
535
|
+
- **Version Management** - Semantic versioning for assets or APIs
|
|
536
|
+
|
|
537
|
+
## Performance Considerations
|
|
538
|
+
|
|
539
|
+
- **Immutability overhead** - Creating new objects for each operation has a cost
|
|
540
|
+
- **Use static methods** - Avoid unnecessary object creation
|
|
541
|
+
- **Reuse common values** - Cache frequently used vectors (Zero, One, Up, etc.)
|
|
542
|
+
- **Matrix operations** - Matrix multiplication is computationally expensive
|
|
543
|
+
- **Normalize wisely** - Computing unit vectors involves square roots
|
|
544
|
+
|
|
545
|
+
## Testing
|
|
546
|
+
|
|
547
|
+
All value objects include comprehensive test coverage demonstrating:
|
|
548
|
+
- Factory method creation
|
|
549
|
+
- Mathematical operations
|
|
550
|
+
- Equality and comparison
|
|
551
|
+
- Edge cases (zero vectors, identity matrices, etc.)
|
|
552
|
+
- Serialization and deserialization
|