0
# Mathematics and Linear Algebra
1
2
Panda3D provides a comprehensive 3D mathematics library with vectors, matrices, quaternions, and geometric operations essential for 3D graphics, physics, and game development.
3
4
## Capabilities
5
6
### 3D Vectors
7
8
Vector classes for representing positions, directions, and other 3D quantities with full mathematical operations.
9
10
```python { .api }
11
class Vec3:
12
def __init__(self, x: float = 0.0, y: float = 0.0, z: float = 0.0) -> None:
13
"""Create 3D vector with x, y, z components."""
14
15
def __init__(self, other: Vec3) -> None:
16
"""Copy constructor."""
17
18
# Component access
19
def getX(self) -> float:
20
"""Get X component."""
21
22
def getY(self) -> float:
23
"""Get Y component."""
24
25
def getZ(self) -> float:
26
"""Get Z component."""
27
28
def setX(self, x: float) -> None:
29
"""Set X component."""
30
31
def setY(self, y: float) -> None:
32
"""Set Y component."""
33
34
def setZ(self, z: float) -> None:
35
"""Set Z component."""
36
37
def set(self, x: float, y: float, z: float) -> None:
38
"""Set all components."""
39
40
# Vector operations
41
def length(self) -> float:
42
"""Get vector magnitude/length."""
43
44
def lengthSquared(self) -> float:
45
"""Get squared length (more efficient than length)."""
46
47
def normalize(self) -> None:
48
"""Normalize vector in place."""
49
50
def normalized(self) -> Vec3:
51
"""Return normalized copy of vector."""
52
53
def dot(self, other: Vec3) -> float:
54
"""Dot product with another vector."""
55
56
def cross(self, other: Vec3) -> Vec3:
57
"""Cross product with another vector."""
58
59
def distance(self, other: Vec3) -> float:
60
"""Distance to another point."""
61
62
def distanceSquared(self, other: Vec3) -> float:
63
"""Squared distance to another point."""
64
65
# Arithmetic operators (support + - * / with vectors and scalars)
66
def __add__(self, other: Vec3) -> Vec3: ...
67
def __sub__(self, other: Vec3) -> Vec3: ...
68
def __mul__(self, scalar: float) -> Vec3: ...
69
def __truediv__(self, scalar: float) -> Vec3: ...
70
def __neg__(self) -> Vec3: ...
71
72
# Comparison
73
def __eq__(self, other: Vec3) -> bool: ...
74
def __ne__(self, other: Vec3) -> bool: ...
75
76
# String representation
77
def __str__(self) -> str: ...
78
def __repr__(self) -> str: ...
79
80
# Type aliases for different precisions
81
Vec3F = LVector3f # Single precision (default)
82
Vec3D = LVector3d # Double precision
83
```
84
85
### 3D Points
86
87
Point classes for representing positions in 3D space, with similar interface to vectors but semantic differences.
88
89
```python { .api }
90
class Point3:
91
def __init__(self, x: float = 0.0, y: float = 0.0, z: float = 0.0) -> None:
92
"""Create 3D point."""
93
94
def getX(self) -> float: ...
95
def getY(self) -> float: ...
96
def getZ(self) -> float: ...
97
def setX(self, x: float) -> None: ...
98
def setY(self, y: float) -> None: ...
99
def setZ(self, z: float) -> None: ...
100
101
def distance(self, other: Point3) -> float:
102
"""Distance to another point."""
103
104
def distanceSquared(self, other: Point3) -> float:
105
"""Squared distance to another point."""
106
107
# Arithmetic operations with vectors and points
108
def __add__(self, vector: Vec3) -> Point3: ...
109
def __sub__(self, other: Point3) -> Vec3: ... # Point - Point = Vector
110
def __sub__(self, vector: Vec3) -> Point3: ... # Point - Vector = Point
111
112
Point3F = LPoint3f # Single precision (default)
113
Point3D = LPoint3d # Double precision
114
```
115
116
### 4D Vectors
117
118
Extended vectors for homogeneous coordinates and advanced mathematical operations.
119
120
```python { .api }
121
class Vec4:
122
def __init__(self, x: float = 0.0, y: float = 0.0, z: float = 0.0, w: float = 0.0) -> None:
123
"""Create 4D vector."""
124
125
def getX(self) -> float: ...
126
def getY(self) -> float: ...
127
def getZ(self) -> float: ...
128
def getW(self) -> float: ...
129
130
def getXyz(self) -> Vec3:
131
"""Get XYZ components as Vec3."""
132
133
def length(self) -> float: ...
134
def normalize(self) -> None: ...
135
def normalized(self) -> Vec4: ...
136
def dot(self, other: Vec4) -> float: ...
137
138
Vec4F = LVector4f # Single precision
139
Vec4D = LVector4d # Double precision
140
```
141
142
### 4x4 Transformation Matrices
143
144
Matrix operations for 3D transformations including translation, rotation, scaling, and projection.
145
146
```python { .api }
147
class LMatrix4:
148
def __init__(self) -> None:
149
"""Create identity matrix."""
150
151
def __init__(self, other: LMatrix4) -> None:
152
"""Copy constructor."""
153
154
# Matrix creation
155
@staticmethod
156
def identMat() -> LMatrix4:
157
"""Create identity matrix."""
158
159
@staticmethod
160
def zeros() -> LMatrix4:
161
"""Create zero matrix."""
162
163
@staticmethod
164
def translateMat(trans: Vec3) -> LMatrix4:
165
"""Create translation matrix."""
166
167
@staticmethod
168
def scaleMat(scale: Vec3) -> LMatrix4:
169
"""Create scale matrix."""
170
171
@staticmethod
172
def rotateMat(angle: float, axis: Vec3) -> LMatrix4:
173
"""Create rotation matrix around axis."""
174
175
@staticmethod
176
def rotateMatNormaxis(angle: float, axis: Vec3) -> LMatrix4:
177
"""Create rotation matrix around normalized axis."""
178
179
# Element access
180
def getCell(self, row: int, col: int) -> float:
181
"""Get matrix element at row, col."""
182
183
def setCell(self, row: int, col: int, value: float) -> None:
184
"""Set matrix element at row, col."""
185
186
def getRow(self, row: int) -> Vec4:
187
"""Get row as Vec4."""
188
189
def getCol(self, col: int) -> Vec4:
190
"""Get column as Vec4."""
191
192
def setRow(self, row: int, v: Vec4) -> None:
193
"""Set row from Vec4."""
194
195
def setCol(self, col: int, v: Vec4) -> None:
196
"""Set column from Vec4."""
197
198
# Matrix operations
199
def multiply(self, other: LMatrix4) -> LMatrix4:
200
"""Matrix multiplication."""
201
202
def __mul__(self, other: LMatrix4) -> LMatrix4:
203
"""Matrix multiplication operator."""
204
205
def __mul__(self, vector: Vec4) -> Vec4:
206
"""Transform Vec4 by matrix."""
207
208
def xform(self, point: Point3) -> Point3:
209
"""Transform point by matrix."""
210
211
def xformVec(self, vector: Vec3) -> Vec3:
212
"""Transform vector by matrix (no translation)."""
213
214
def xformPoint(self, point: Point3) -> Point3:
215
"""Transform point by matrix."""
216
217
def invertFrom(self, other: LMatrix4) -> bool:
218
"""Invert other matrix and store result."""
219
220
def invert(self) -> bool:
221
"""Invert this matrix in place."""
222
223
def invertInPlace(self) -> bool:
224
"""Invert this matrix in place."""
225
226
def transpose(self) -> None:
227
"""Transpose matrix in place."""
228
229
def transposed(self) -> LMatrix4:
230
"""Return transposed copy."""
231
232
def determinant(self) -> float:
233
"""Calculate matrix determinant."""
234
235
# Transformation composition
236
def compose(self, scale: Vec3, hpr: Vec3, trans: Vec3) -> None:
237
"""Compose transformation from scale, rotation (HPR), and translation."""
238
239
def composeMatrix(self, scale: Vec3, shear: Vec3, hpr: Vec3, trans: Vec3) -> None:
240
"""Compose transformation with shear."""
241
242
def decompose(self) -> Tuple[Vec3, Vec3, Vec3]:
243
"""Decompose into scale, HPR, and translation."""
244
245
# Utility
246
def isIdentity(self) -> bool:
247
"""Check if matrix is identity."""
248
249
def almostEqual(self, other: LMatrix4, threshold: float = 0.001) -> bool:
250
"""Check if matrices are approximately equal."""
251
252
Mat4 = LMatrix4f # Single precision alias (default)
253
Mat4D = LMatrix4d # Double precision
254
```
255
256
### Quaternions
257
258
Quaternion class for smooth rotations and orientation interpolation.
259
260
```python { .api }
261
class LQuaternion:
262
def __init__(self, w: float = 1.0, x: float = 0.0, y: float = 0.0, z: float = 0.0) -> None:
263
"""Create quaternion with w, x, y, z components."""
264
265
def __init__(self, other: LQuaternion) -> None:
266
"""Copy constructor."""
267
268
# Component access
269
def getW(self) -> float: ...
270
def getX(self) -> float: ...
271
def getY(self) -> float: ...
272
def getZ(self) -> float: ...
273
def setW(self, w: float) -> None: ...
274
def setX(self, x: float) -> None: ...
275
def setY(self, y: float) -> None: ...
276
def setZ(self, z: float) -> None: ...
277
278
def set(self, w: float, x: float, y: float, z: float) -> None:
279
"""Set all components."""
280
281
# Quaternion operations
282
def normalize(self) -> None:
283
"""Normalize quaternion in place."""
284
285
def normalized(self) -> LQuaternion:
286
"""Return normalized copy."""
287
288
def conjugate(self) -> LQuaternion:
289
"""Return conjugate quaternion."""
290
291
def invert(self) -> None:
292
"""Invert quaternion in place."""
293
294
def inverted(self) -> LQuaternion:
295
"""Return inverted quaternion."""
296
297
def multiply(self, other: LQuaternion) -> LQuaternion:
298
"""Quaternion multiplication."""
299
300
def __mul__(self, other: LQuaternion) -> LQuaternion: ...
301
302
# Rotation creation and conversion
303
@staticmethod
304
def pureRotation(axis: Vec3, angle: float) -> LQuaternion:
305
"""Create rotation quaternion from axis and angle."""
306
307
def setFromAxisAngle(self, angle: float, axis: Vec3) -> None:
308
"""Set from axis-angle representation."""
309
310
def getAxisAngle(self) -> Tuple[float, Vec3]:
311
"""Get axis-angle representation."""
312
313
def setHpr(self, hpr: Vec3) -> None:
314
"""Set from Heading-Pitch-Roll angles."""
315
316
def getHpr(self) -> Vec3:
317
"""Get as Heading-Pitch-Roll angles."""
318
319
def getMatrix(self) -> LMatrix4:
320
"""Convert to rotation matrix."""
321
322
# Interpolation
323
def slerp(self, other: LQuaternion, t: float) -> LQuaternion:
324
"""Spherical linear interpolation between quaternions."""
325
326
def dot(self, other: LQuaternion) -> float:
327
"""Dot product with another quaternion."""
328
329
def isIdentity(self) -> bool:
330
"""Check if quaternion represents no rotation."""
331
332
def almostEqual(self, other: LQuaternion, threshold: float = 0.001) -> bool:
333
"""Check if quaternions are approximately equal."""
334
335
Quat = LQuaternionf # Single precision alias (default)
336
QuatD = LQuaterniond # Double precision
337
```
338
339
### Geometric Utilities
340
341
Additional mathematical utilities for common 3D operations.
342
343
```python { .api }
344
def deg2Rad(degrees: float) -> float:
345
"""Convert degrees to radians."""
346
347
def rad2Deg(radians: float) -> float:
348
"""Convert radians to degrees."""
349
350
def clamp(value: float, min_val: float, max_val: float) -> float:
351
"""Clamp value between min and max."""
352
353
def lerp(a: float, b: float, t: float) -> float:
354
"""Linear interpolation between a and b."""
355
356
def smoothstep(edge0: float, edge1: float, x: float) -> float:
357
"""Smooth interpolation function."""
358
359
# Vector utility functions
360
def cross(a: Vec3, b: Vec3) -> Vec3:
361
"""Cross product of two vectors."""
362
363
def dot(a: Vec3, b: Vec3) -> float:
364
"""Dot product of two vectors."""
365
366
def distance(a: Point3, b: Point3) -> float:
367
"""Distance between two points."""
368
369
def reflect(incident: Vec3, normal: Vec3) -> Vec3:
370
"""Reflect vector off surface with given normal."""
371
```
372
373
## Usage Examples
374
375
### Basic Vector Operations
376
377
```python
378
from panda3d.core import Vec3, Point3
379
380
# Create vectors
381
a = Vec3(1, 2, 3)
382
b = Vec3(4, 5, 6)
383
384
# Basic operations
385
c = a + b # Vector addition: (5, 7, 9)
386
d = b - a # Vector subtraction: (3, 3, 3)
387
e = a * 2.0 # Scalar multiplication: (2, 4, 6)
388
389
# Vector properties
390
length = a.length() # Get magnitude
391
a.normalize() # Normalize in place
392
unit_a = a.normalized() # Get normalized copy
393
394
# Vector products
395
dot_product = a.dot(b) # Dot product (scalar)
396
cross_product = a.cross(b) # Cross product (vector)
397
398
# Distance calculations
399
p1 = Point3(0, 0, 0)
400
p2 = Point3(3, 4, 0)
401
dist = p1.distance(p2) # Distance: 5.0
402
```
403
404
### Matrix Transformations
405
406
```python
407
from panda3d.core import LMatrix4, Vec3, Point3
408
409
# Create transformation matrices
410
translate_mat = LMatrix4.translateMat(Vec3(5, 0, 0))
411
scale_mat = LMatrix4.scaleMat(Vec3(2, 2, 2))
412
rotate_mat = LMatrix4.rotateMat(45, Vec3(0, 0, 1)) # 45° around Z
413
414
# Combine transformations (order matters!)
415
transform = translate_mat * rotate_mat * scale_mat
416
417
# Apply transformation to points and vectors
418
point = Point3(1, 1, 0)
419
transformed_point = transform.xform(point)
420
421
vector = Vec3(1, 0, 0)
422
transformed_vector = transform.xformVec(vector)
423
424
# Matrix composition (more convenient)
425
final_mat = LMatrix4()
426
final_mat.compose(
427
Vec3(2, 2, 2), # Scale
428
Vec3(0, 0, 45), # HPR rotation
429
Vec3(5, 0, 0) # Translation
430
)
431
```
432
433
### Quaternion Rotations
434
435
```python
436
from panda3d.core import LQuaternion, Vec3
437
import math
438
439
# Create rotation quaternions
440
q1 = LQuaternion()
441
q1.setFromAxisAngle(math.radians(90), Vec3(0, 0, 1)) # 90° around Z
442
443
q2 = LQuaternion()
444
q2.setHpr(Vec3(45, 0, 0)) # From HPR angles
445
446
# Quaternion multiplication (rotation composition)
447
combined = q1 * q2
448
449
# Interpolation between rotations
450
interpolated = q1.slerp(q2, 0.5) # Halfway between q1 and q2
451
452
# Convert to other representations
453
hpr = combined.getHpr() # Get as HPR angles
454
matrix = combined.getMatrix() # Get as rotation matrix
455
angle, axis = combined.getAxisAngle() # Get as axis-angle
456
```
457
458
### 3D Math in Game Logic
459
460
```python
461
from direct.showbase.ShowBase import ShowBase
462
from panda3d.core import Vec3, Point3
463
from direct.task import Task
464
465
class MathDemo(ShowBase):
466
def __init__(self):
467
ShowBase.__init__(self)
468
469
# Create objects
470
self.player = self.loader.loadModel("models/player")
471
self.target = self.loader.loadModel("models/target")
472
473
self.player.reparentTo(self.render)
474
self.target.reparentTo(self.render)
475
476
# Position objects
477
self.player.setPos(0, 0, 0)
478
self.target.setPos(10, 5, 2)
479
480
# Start update task
481
self.taskMgr.add(self.updatePlayer, "update-player")
482
483
def updatePlayer(self, task):
484
"""Make player look at and move toward target."""
485
# Get positions as Point3
486
player_pos = self.player.getPos()
487
target_pos = self.target.getPos()
488
489
# Calculate direction vector
490
direction = target_pos - player_pos
491
distance = direction.length()
492
493
if distance > 0.1: # Not at target yet
494
# Normalize direction for unit vector
495
direction.normalize()
496
497
# Move toward target
498
speed = 5.0 # units per second
499
dt = globalClock.getDt()
500
new_pos = player_pos + direction * speed * dt
501
self.player.setPos(new_pos)
502
503
# Look at target
504
self.player.lookAt(target_pos)
505
506
return task.cont
507
508
app = MathDemo()
509
app.run()
510
```
511
512
## Types
513
514
```python { .api }
515
# Precision variants
516
LVector3f = Vec3F # Single precision 3D vector
517
LVector3d = Vec3D # Double precision 3D vector
518
LVector4f = Vec4F # Single precision 4D vector
519
LVector4d = Vec4D # Double precision 4D vector
520
521
LPoint3f = Point3F # Single precision 3D point
522
LPoint3d = Point3D # Double precision 3D point
523
524
LMatrix4f = Mat4 # Single precision 4x4 matrix
525
LMatrix4d = Mat4D # Double precision 4x4 matrix
526
527
LQuaternionf = Quat # Single precision quaternion
528
LQuaterniond = QuatD # Double precision quaternion
529
530
# Common type aliases used throughout Panda3D
531
Vec3 = LVector3f # Default 3D vector type
532
Point3 = LPoint3f # Default 3D point type
533
Mat4 = LMatrix4f # Default matrix type
534
Quat = LQuaternionf # Default quaternion type
535
```