-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathMathUtil.html
More file actions
4258 lines (3077 loc) · 198 KB
/
MathUtil.html
File metadata and controls
4258 lines (3077 loc) · 198 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html><html><head><meta http-equiv=Content-Type content="text/html; charset=utf-8"><title>MathUtil</title><meta name="viewport" content="width=device-width"><link rel=stylesheet type="text/css" href="/style.css">
<script type="text/x-mathjax-config"> MathJax.Hub.Config({"HTML-CSS": { availableFonts: ["STIX","TeX"], linebreaks: { automatic:true }, preferredFont: "TeX" },
tex2jax: { displayMath: [ ["$$","$$"], ["\\[", "\\]"] ], inlineMath: [ ["$", "$"], ["\\\\(","\\\\)"] ], processEscapes: true } });
</script><script type="text/javascript" async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-AMS_HTML-full"></script></head><body> <div class="header">
<nav><p><a href="#navigation">Menu</a> - <a href="#top">Top</a> - <a href="/">Home</a></nav></div>
<div class="mainarea" id="top">
<h1 id="mathutil">MathUtil</h1>
<p><a href="index.html">Back to documentation index.</a></p>
<p><a name="MathUtil"></a></p>
<h3 id="new-mathutil">new MathUtil()</h3>
<p>A collection of math functions for working
with vectors, matrices, quaternions, and other
mathematical objects of interest to three-dimensional graphics programming.</p>
<p><a id="Vectors"></a>
## Vectors
A vector is a line segment pointing in a certain <em>direction</em> in space and
having a certain <em>length</em> and an unspecified starting point.
A particular vector can instead be treated as describing a position
(by pointing to that position from an <em>origin</em> (0,0,0)), or a color.
In <code>MathUtil</code>, vectors are stored in arrays of numbers (usually
three or four numbers), and functions dealing with vectors begin
with “vec”.
If a 4-element vector describes a position or direction, the elements
are given as X, Y, Z, and W, in that order.
If a 4-element vector describes a color, the elements are given as red, green,
blue, and alpha, in that order (where each element ranges from 0-1).
If a 3D <em>direction</em> is used in a 4-element vector function (one beginning with “vec4”),
use 0 as the fourth element. If a 3D <em>position</em> (point) is used in a 4-element vector
function, the fourth element is generally 1. (If the
fourth element is anything other than 0, the vector is in <em>homogeneous
coordinates</em>, where the 3D position equals the first three elements divided
by the fourth.)
A <em>unit vector</em> is a vector with a length of 1. (A vector’s <em>length</em>, or <em>norm</em>, is the square root
of the sum of the squares of its components.) A vector can be “normalized” to
a unit vector by dividing each of its components by its length (doing so won’t change
the vector’s direction). The following functions normalize vectors and find their length: <a href="MathUtil.html#MathUtil.vec3normalize">MathUtil.vec3normalize</a> converts a 3-element vector to a unit vector; <a href="MathUtil.html#MathUtil.vec4normalize">MathUtil.vec4normalize</a> converts a 4-element vector to a unit vector; <a href="MathUtil.html#MathUtil.vec3length">MathUtil.vec3length</a> finds a 3-element vector’s length; <a href="MathUtil.html#MathUtil.vec4length">MathUtil.vec4length</a> finds a 4-element vector’s length. Note that due to rounding error, normalizing a vector with a <code>MathUtil</code> method might not necessarily result in a vector with a length of 1.
<a id="Matrices"></a>
## Matrices
A matrix is a rectangular array that can describe a
transformation from one coordinate system to another. Transformations
that matrices can describe include translation (shifting), scaling, and rotation.
Functions dealing with matrices begin with “mat”.
A 3 × 3 or 4 × 4 matrix has 9 or 16 elements, respectively. In mathematical publications,
matrices are often notated in column-major order, in which each
element of the matrix is placed in columns as opposed to rows, as in the following example:</p>
<math>
<mfenced open="[" close="]">
<mtable>
<mtr>
<mtd><mi>matrix[0]</mi></mtd>
<mtd><mi>matrix[4]</mi></mtd>
<mtd><mi>matrix[8]</mi></mtd>
<mtd><mi>matrix[12]</mi></mtd>
</mtr>
<mtr>
<mtd><mi>matrix[1]</mi></mtd>
<mtd><mi>matrix[5]</mi></mtd>
<mtd><mi>matrix[9]</mi></mtd>
<mtd><mi>matrix[13]</mi></mtd>
</mtr>
<mtr>
<mtd><mi>matrix[2]</mi></mtd>
<mtd><mi>matrix[6]</mi></mtd>
<mtd><mi>matrix[10]</mi></mtd>
<mtd><mi>matrix[14]</mi></mtd>
</mtr>
<mtr>
<mtd><mi>matrix[3]</mi></mtd>
<mtd><mi>matrix[7]</mi></mtd>
<mtd><mi>matrix[11]</mi></mtd>
<mtd><mi>matrix[15]</mi></mtd>
</mtr>
</mtable>
</mfenced>
</math>
<p>The numbers in brackets in the matrix above are the zero-based indices
into the matrix arrays passed to <code>MathUtil</code>’s matrix methods.
For 3 × 3 matrices, the elements are arranged in the following order:</p>
<math>
<mfenced open="[" close="]">
<mtable>
<mtr>
<mtd><mi>matrix[0]</mi></mtd>
<mtd><mi>matrix[3]</mi></mtd>
<mtd><mi>matrix[6]</mi></mtd>
</mtr>
<mtr>
<mtd><mi>matrix[1]</mi></mtd>
<mtd><mi>matrix[4]</mi></mtd>
<mtd><mi>matrix[7]</mi></mtd>
</mtr>
<mtr>
<mtd><mi>matrix[2]</mi></mtd>
<mtd><mi>matrix[5]</mi></mtd>
<mtd><mi>matrix[8]</mi></mtd>
</mtr>
</mtable>
</mfenced>
</math>
<p><b>A Matrix Transforms Between Coordinate Systems:</b> A transformed 3D coordinate system is made up of an x-, y-, and z-axes, and a center of the coordinate system. These are four 3-element vectors that describe how the three axes and the center map to the new coordinate system in relation to the old coordinate system.
The following depiction of a 4 × 4 matrix illustrates the meaning of each of its elements. To keep things
simple, this matrix’s transformation is one that keeps straight lines straight and parallel lines parallel.</p>
<math>
<mfenced open="[" close="]">
<mtable>
<mtr>
<mtd><mi>[0] x-axis X</mi></mtd>
<mtd><mi>[4] y-axis X</mi></mtd>
<mtd><mi>[8] z-axis X</mi></mtd>
<mtd><mi>[12] Center X</mi></mtd>
</mtr>
<mtr>
<mtd><mi>[1] x-axis Y</mi></mtd>
<mtd><mi>[5] y-axis Y</mi></mtd>
<mtd><mi>[9] z-axis Y</mi></mtd>
<mtd><mi>[13] Center Y</mi></mtd>
</mtr>
<mtr>
<mtd><mi>[2] x-axis Z</mi></mtd>
<mtd><mi>[6] y-axis Z</mi></mtd>
<mtd><mi>[10] z-axis Z</mi></mtd>
<mtd><mi>[14] Center Z</mi></mtd>
</mtr>
<mtr>
<mtd><mi>[3] 0</mi></mtd>
<mtd><mi>[7] 0</mi></mtd>
<mtd><mi>[11] 0</mi></mtd>
<mtd><mi>[15] 1</mi></mtd>
</mtr>
</mtable>
</mfenced>
</math>
<p>The following is an example of a transformation matrix.</p>
<math>
<mfenced open="[" close="]">
<mtable>
<mtr>
<mtd><mn>1</mn></mtd>
<mtd><mn>0</mn></mtd>
<mtd><mn>0</mn></mtd>
<mtd><mn>2</mn></mtd>
</mtr>
<mtr>
<mtd><mn>0</mn></mtd>
<mtd><mi>0.5</mi></mtd>
<mtd><mo>-0.866025</mtd>
<mtd><mn>3</mn></mtd>
</mtr>
<mtr>
<mtd><mn>0</mn></mtd>
<mtd><mi>0.866025</mtd>
<mtd><mi>0.5</mtd>
<mtd><mn>4</mn></mtd>
</mtr>
<mtr>
<mtd><mi>0</mi></mtd>
<mtd><mi>0</mi></mtd>
<mtd><mi>0</mi></mtd>
<mtd><mn>1</mn></mtd>
</mtr>
</mtable>
</mfenced>
</math>
Here, the first column shows an x-axis vector at (1, 0, 0),
the second column shows a y-axis vector at (0, 0.5, 0.866025),
the third column shows a z-axis vector at (0, -0.866025, 0.5),
and the fourth column centers the coordinate system at (2, 3, 4).
Provided the matrix can be inverted (see the documentation for mat4invert), the three axis vectors are
_basis vectors_ of the coordinate system.
\*Why a 4 × 4 matrix?\*\* A matrix can describe _linear transformations_ from one vector in space
to another. These transformations, which include [\*\*scaling\*\*](#Scaling),
[\*\*rotation\*\*](#Rotation), and shearing, can change where a vector points _at_,
but not where it points _from_. It's enough to use a 3 × 3 matrix to describe
linear transformations in 3D space.
But certain other transformations, such as [\*\*translation\*\*](#Translation) and
[\*\*perspective\*\*](#Projective_Transformations), are common in 3D computer graphics.
To describe translation and perspective in 3D, the 3 × 3 matrix must be
augmented by an additional row and column, turning it into a 4 × 4 matrix.
A 4 × 4 matrix can describe linear transformations in 4D space and
transform 4-element vectors. A 4-element vector has four components:
X, Y, Z, and W. If a 4-element vector represents a 3D point, these
components are the point's _homogeneous coordinates_ (unless the
vector's W is 0). To convert these coordinates back to 3D, divide
X, Y, and Z by W. This is usually only required, however, if the
matrix describes a perspective projection (see
[\*\*"Projective Transformations"\*\*](#Projective_Transformations)).
A similar situation applies in 2D between 2 × 2 and 3 × 3 matrices as it does
in 3D between 3 × 3 and 4 × 4 matrices.
\*Transforming points.\*\* The transformation formula multiplies a matrix by a 3D point to change that point's
position:
\*\*a′\*\*<sub>_x_</sub> = matrix[0] ⋅ \*\*a\*\*<sub>_x_</sub> + matrix[4] ⋅ \*\*a\*\*<sub>_y_</sub> + matrix[8] ⋅ \*\*a\*\*<sub>_z_</sub> + matrix[12] ⋅ \*\*a\*\*<sub>_w_</sub>
\*\*a′\*\*<sub>_y_</sub> = matrix[1] ⋅ \*\*a\*\*<sub>_x_</sub> + matrix[5] ⋅ \*\*a\*\*<sub>_y_</sub> + matrix[9] ⋅ \*\*a\*\*<sub>_z_</sub> + matrix[13] ⋅ \*\*a\*\*<sub>_w_</sub>
\*\*a′\*\*<sub>_z_</sub> = matrix[2] ⋅ \*\*a\*\*<sub>_x_</sub> + matrix[6] ⋅ \*\*a\*\*<sub>_y_</sub> + matrix[10] ⋅ \*\*a\*\*<sub>_z_</sub> + matrix[14] ⋅ \*\*a\*\*<sub>_w_</sub>
\*\*a′\*\*<sub>_w_</sub> = matrix[3] ⋅ \*\*a\*\*<sub>_x_</sub> + matrix[7] ⋅ \*\*a\*\*<sub>_y_</sub> + matrix[11] ⋅ \*\*a\*\*<sub>_z_</sub> + matrix[15] ⋅ \*\*a\*\*<sub>_w_</sub>
For more on why \*\*a′\*\*<sub>_w_</sub> appears here, see \*\*"Why a 4 × 4 Matrix?"\*\*, earlier. In each formula that follows, \*\*a\*\*<sub>_w_</sub> is assumed to be 1 (indicating a conventional 3D point).
\* Scaling.\*\* Scaling changes an object's size.
To create a scaling matrix, use <a href="MathUtil.html#MathUtil.mat4scaled">MathUtil.mat4scaled()</a>,
and specify the scaling factors for the x-, y-, and z-axes. Each point is multiplied by the scaling
factors to change the object's size. For example, a Y-factor of 2 doubles an object's height.
To multiply an existing matrix by a scaling, use
<a href="MathUtil.html#MathUtil.mat4scale">MathUtil.mat4scale()</a>. This will put the scaling
before the other transformations.
Scaling uses the 1st, 6th, and 11th elements of the matrix as seen here:
<math>
<mfenced open="[" close="]">
<mtable>
<mtr>
<mtd><mi>sx</mi></mtd>
<mtd><mn>0</mn></mtd>
<mtd><mn>0</mn></mtd>
<mtd><mn>0</mn></mtd>
</mtr>
<mtr>
<mtd><mn>0</mn></mtd>
<mtd><mi>sy</mi></mtd>
<mtd><mn>0</mn></mtd>
<mtd><mn>0</mn></mtd>
</mtr>
<mtr>
<mtd><mn>0</mn></mtd>
<mtd><mn>0</mn></mtd>
<mtd><mi>sz</mi></mtd>
<mtd><mn>0</mn></mtd>
</mtr>
<mtr>
<mtd><mi>0</mi></mtd>
<mtd><mi>0</mi></mtd>
<mtd><mi>0</mi></mtd>
<mtd><mn>1</mn></mtd>
</mtr>
</mtable>
</mfenced>
</math>
where the x-coordinate is multiplied by `sx`, the y-coordinate is multiplied by `sy`, and
the z-coordinate is multiplied by `sz`.
The scaling formula would look like:
\*\*a′\*\*<sub>_x_</sub> = sx ⋅ \*\*a\*\*<sub>_x_</sub> + 0 ⋅ \*\*a\*\*<sub>_y_</sub> + 0 ⋅ \*\*a\*\*<sub>_z_</sub> + 0
\*\*a′\*\*<sub>_y_</sub> = 0 ⋅ \*\*a\*\*<sub>_x_</sub> + sy ⋅ \*\*a\*\*<sub>_y_</sub> + 0 ⋅ \*\*a\*\*<sub>_z_</sub> + 0
\*\*a′\*\*<sub>_z_</sub> = 0 ⋅ \*\*a\*\*<sub>_x_</sub> + 0 ⋅ \*\*a\*\*<sub>_y_</sub> + sz ⋅ \*\*a\*\*<sub>_z_</sub> + 0
\*\*a′\*\*<sub>_w_</sub> = 0 ⋅ \*\*a\*\*<sub>_x_</sub> + 0 ⋅ \*\*a\*\*<sub>_y_</sub> + 0 ⋅ \*\*a\*\*<sub>_z_</sub> + 1 = 1
For example, we multiply the input x by `sx` to get the output x. If `sx` is 1, x
remains unchanged. Likewise for y (`sy`) and z (`sz`).
If `sx`, `sy`, or `sz` is -1, that coordinate is _reflected_ along the corresponding axis.
If `sx`, `sy`, and `sz` are all 1, we have an _identity matrix_, where the input vector
is equal to the output vector.
When the transformed X, Y, or z-axis has a length other than 1, the coordinate
system will be scaled up or down along that axis. The scalings given
here will scale the lengths of the corresponding axes. For example,
if `sx` is 2, the x-axis will be (2, 0, 0) and thus have a length of 2.
\*\*Translation.\*\* A translation is a shifting of an object's position.
To create a translation matrix, use <a href="MathUtil.html#MathUtil.mat4translated">MathUtil.mat4translated()</a>,
and specify the X-offset, the Y-offset, and the Z-offset. For example, an X-offset of 1 moves
an object 1 unit to the right, and a Y offset of -1 moves it 1 unit down.
To multiply an existing matrix by a translation, use
<a href="MathUtil.html#MathUtil.mat4translate">MathUtil.mat4translate()</a>. This will put the translation
before the other transformations. In a transformation matrix,
translation effectively occurs after all other transformations such as scaling and rotation.
It uses the 13th, 14th, and 15th elements of the matrix as seen here:
<math>
<mfenced open="[" close="]">
<mtable>
<mtr>
<mtd><mn>1</mn></mtd>
<mtd><mn>0</mn></mtd>
<mtd><mn>0</mn></mtd>
<mtd><mn>tx</mn></mtd>
</mtr>
<mtr>
<mtd><mn>0</mn></mtd>
<mtd><mn>1</mn></mtd>
<mtd><mn>0</mn></mtd>
<mtd><mn>ty</mn></mtd>
</mtr>
<mtr>
<mtd><mn>0</mn></mtd>
<mtd><mn>0</mn></mtd>
<mtd><mn>1</mn></mtd>
<mtd><mn>tz</mn></mtd>
</mtr>
<mtr>
<mtd><mi>0</mi></mtd>
<mtd><mi>0</mi></mtd>
<mtd><mi>0</mi></mtd>
<mtd><mn>1</mn></mtd>
</mtr>
</mtable>
</mfenced>
</math>
where `tx` is added to the x-coordinate, `ty` is added to the y-coordinate, and
`tz` is added to the z-coordinate. The transformation formulas would look like:
\*\*a′\*\*<sub>_x_</sub> = 1 ⋅ \*\*a\*\*<sub>_x_</sub> + 0 ⋅ \*\*a\*\*<sub>_y_</sub> + 0 ⋅ \*\*a\*\*<sub>_z_</sub> + tx
\*\*a′\*\*<sub>_y_</sub> = 0 ⋅ \*\*a\*\*<sub>_x_</sub> + 1 ⋅ \*\*a\*\*<sub>_y_</sub> + 0 ⋅ \*\*a\*\*<sub>_z_</sub> + ty
\*\*a′\*\*<sub>_z_</sub> = 0 ⋅ \*\*a\*\*<sub>_x_</sub> + 0 ⋅ \*\*a\*\*<sub>_y_</sub> + 1 ⋅ \*\*a\*\*<sub>_z_</sub> + tz
\*\*a′\*\*<sub>_w_</sub> = 0 ⋅ \*\*a\*\*<sub>_x_</sub> + 0 ⋅ \*\*a\*\*<sub>_y_</sub> + 0 ⋅ \*\*a\*\*<sub>_z_</sub> + 1 = 1
For example, we add the input x and `tx` to get the output x. If `tx` is 0, x
remains unchanged. Likewise for y (`ty`) and z (`tz`).
\*Rotation.\*\* Rotation changes an object's orientation.
To create a rotation matrix, use <a href="MathUtil.html#MathUtil.mat4rotated">MathUtil.mat4rotated()</a>,
and specify the angle (in degrees) to rotate, and the [\*\*axis of rotation\*\*](#Axis_of_Rotation). For example:
Specifying `(45, [1, 0, 0])` means a 45-degree rotation of the point around the x-axis.
Specifying `(80, [0, 2, 3])` means a 45-degree rotation of the point around the axis that
starts at the origin (0, 0, 0) and points toward the point (0, 2, 3).
When describing an axis of rotation, <code>[1, 0, 0]</code> is the x-axis,
<code>[0, 1, 0]</code> is the y-axis, and <code>[0, 0, 1]</code> is the z-axis.
To multiply an existing matrix by a rotation, use
<a href="MathUtil.html#MathUtil.mat4rotate">MathUtil.mat4rotate()</a>. This will put the rotation
before the other transformations.
Given an angle of rotation, θ,
the transformation matrix for rotating 3D points is as follows. (For a list of common
sines and cosines, see the end of this section.)
<figure>
<math>
<mfenced open="[" close="]">
<mtable>
<mtr>
<mtd><mn>1</mn></mtd>
<mtd><mn>0</mn></mtd>
<mtd><mn>0</mn></mtd>
<mtd><mn>0</mn></mtd>
</mtr>
<mtr>
<mtd><mn>0</mn></mtd>
<mtd><mi>cos</mi><mi>θ</mi></mtd>
<mtd><mo>-</mo><mi>sin</mi><mi>θ</mi></mtd>
<mtd><mn>0</mn></mtd>
</mtr>
<mtr>
<mtd><mn>0</mn></mtd>
<mtd><mi>sin</mi><mi>θ</mi></mtd>
<mtd><mi>cos</mi><mi>θ</mi></mtd>
<mtd><mn>0</mn></mtd>
</mtr>
<mtr>
<mtd><mi>0</mi></mtd>
<mtd><mi>0</mi></mtd>
<mtd><mi>0</mi></mtd>
<mtd><mn>1</mn></mtd>
</mtr>
</mtable>
</mfenced>
</math>
<figcaption>Rotation about the x-axis.</figcaption></figure>
<figure>
<math>
<mfenced open="[" close="]">
<mtable>
<mtr>
<mtd><mi>cos</mi><mi>θ</mi></mtd>
<mtd><mn>0</mn></mtd>
<mtd><mi>sin</mi><mi>θ</mi></mtd>
<mtd><mn>0</mn></mtd>
</mtr>
<mtr>
<mtd><mn>0</mn></mtd>
<mtd><mn>1</mn></mtd>
<mtd><mn>0</mn></mtd>
<mtd><mn>0</mn></mtd>
</mtr>
<mtr>
<mtd><mo>-</mo><mi>sin</mi><mi>θ</mi></mtd>
<mtd><mn>0</mn></mtd>
<mtd><mi>cos</mi><mi>θ</mi></mtd>
<mtd><mn>0</mn></mtd>
</mtr>
<mtr>
<mtd><mi>0</mi></mtd>
<mtd><mi>0</mi></mtd>
<mtd><mi>0</mi></mtd>
<mtd><mn>1</mn></mtd>
</mtr>
</mtable>
</mfenced>
</math>
<figcaption>Rotation about the y-axis.</figcaption></figure>
<figure>
<math>
<mfenced open="[" close="]">
<mtable>
<mtr>
<mtd><mi>cos</mi><mi>θ</mi></mtd>
<mtd><mo>-</mo><mi>sin</mi><mi>θ</mi></mtd>
<mtd><mn>0</mn></mtd>
<mtd><mn>0</mn></mtd>
</mtr>
<mtr>
<mtd><mi>sin</mi><mi>θ</mi></mtd>
<mtd><mi>cos</mi><mi>θ</mi></mtd>
<mtd><mn>0</mn></mtd>
<mtd><mn>0</mn></mtd>
</mtr>
<mtr>
<mtd><mn>0</mn></mtd>
<mtd><mn>0</mn></mtd>
<mtd><mn>1</mn></mtd>
<mtd><mn>0</mn></mtd>
</mtr>
<mtr>
<mtd><mi>0</mi></mtd>
<mtd><mi>0</mi></mtd>
<mtd><mi>0</mi></mtd>
<mtd><mn>1</mn></mtd>
</mtr>
</mtable>
</mfenced>
</math>
<figcaption>Rotation about the z-axis.</figcaption></figure>
Note that:
When we rotate a point about the x-axis, the x-coordinate is unchanged
and the y- and z-coordinates adjust in the rotation. For rotations about the
y-axis or the z-axis, the Y or z-coordinate, respectively, is likewise unchanged.
If the axis of rotation points backward from the "eye", positive rotations mean
counterclockwise rotation in right-handed coordinate systems. For example,
60 degrees about the axis means
60 degrees counterclockwise, and negative 60 degrees means 60 degrees
clockwise.
Rotating a point around an arbitrary axis of rotation is more complicated to describe.
When describing an axis of rotation, <code>[1, 0, 0]</code> is the x-axis,
<code>[0, 1, 0]</code> is the y-axis, and <code>[0, 0, 1]</code> is the z-axis.
See [\*\*"Rotation example"\*\*](#Rotation_Example) for an illustration of a rotation
transformation.
Related functions:
<a href="MathUtil.html#MathUtil.mat4rotated">MathUtil.mat4rotated()</a> -
Returns a rotation matrix
<a href="MathUtil.html#MathUtil.mat4rotate">MathUtil.mat4rotate()</a> -
Multiplies a matrix by a translation.
A list of common sines and cosines follows. Values
shown with three decimal places are approximate.
| | 0°| 22.5°| 30°| 45°| 60°| 67.5°| 90°| 112.5°| 120°| 135°| 150°| 157.5°| 180°|
-------|---|------|----|----|----|------|----|------|-----|-----|-----|-------|-----|
| sin | 0 | 0.383 | 0.5 | 0.707 | 0.866 | 0.924 | 1 | 0.924 | 0.866 | 0.707 | 0.5 | 0.383 | 0 |
| cos | 1 | 0.924 | 0.866 | 0.707 | 0.5 | 0.383 | 0 | -0.383 | -0.5 | -0.707 | -0.866 | -0.924 | -1 |
| | 180°| 202.5°| 210°| 225°| 240°| 247.5°| 270°| 292.5°| 300°| 315°| 330°| 337.5°| 360°|
-------|---|------|----|----|----|------|----|------|-----|-----|-----|-------|-----|
| sin | 0 | -0.383 | -0.5 | -0.707 | -0.866 | -0.924 | -1 | -0.924 | -0.866 | -0.707 | -0.5 | -0.383 | 0 |
| cos | -1 | -0.924 | -0.866 | -0.707 | -0.5 | -0.383 | 0 | 0.383 | 0.5 | 0.707 | 0.866 | 0.924 | 1 |
<a id="Matrix_Multiplication"></a>
### Matrix Multiplication
The order in which you do transforms is important. In general, scaling then translating is
not the same as translating then scaling. Assuming your geometry is centered at the origin
(0, 0, 0), you should create a transformation in this order:
Call <a href="MathUtil.html#MathUtil.mat4identity">`MathUtil.mat4identity()`</a>, creating a matrix without a transformation.
Do your translations if needed, using <a href="MathUtil.html#MathUtil.mat4translate">`mat4translate()`</a>.
Do your rotations if needed, using <a href="MathUtil.html#MathUtil.mat4rotate">`mat4rotate()`</a>.
Do your scalings if needed, using <a href="MathUtil.html#MathUtil.mat4scale">`mat4scale()`</a>.
This way, the scalings and rotations will affect the object while it's still centered, and
before the translations (shifts) take place.
You can also multiply transforms using <a href="MathUtil.html#MathUtil.mat4multiply">MathUtil.mat4multiply()</a>.
This takes two matrices and returns one combined matrix. The combined matrix will have the effect
of doing the second matrix's transform, then the first matrix's transform.
When two matrices are multiplied, the combined matrix will be such
that the transformations they describe happen in reverse
order. For example, if the first matrix (input matrix) describes a translation and the second
matrix describes a scaling, the multiplied matrix will
describe the effect of scaling then translation.
Matrix multiplication is not commutative; the order of multiplying matrices is important.
To get an insight of how matrix multiplication works, treat the second matrix as a group
of column vectors (with the same number of rows as the number of columns in the
first matrix). Multiplying the two matrices transforms these vectors to new ones in the
same way as if the column vectors were transformed individually. (This also explains why there can
be one or more column vectors in the second matrix and not just four in the case of a 4 × 4 matrix,
and also why transforming a 4-element column vector is the same as multiplying a 4 × 4 matrix by a
matrix with one column and four rows.\*)
This insight reveals a practical use of matrix multiplication: transforming four 4-element
vectors at once using a single matrix operation involving two 4 × 4 matrices. After the
matrix multiplication, each of the transformed vectors will be contained in one of the four columns
of the output matrix.
The methods `mat4multiply`, `mat4scale`, `mat4scaleInPlace`, `mat4translate`, and
mat4rotate involve multiplying 4 × 4 matrices.
Related functions:
<a href="MathUtil.html#MathUtil.mat4multiply">MathUtil.mat4multiply()</a> -
Multiplies two matrices
\\* Reading the [\*\*tutorial by Dmitry Sokolov\*\*](https://github.com/ssloy/tinyrenderer/wiki/Lesson-4:-Perspective-projection) led me to this useful insight.
\*Projective transformations.\*\* In all the transformations described earlier, the last row in the transformation matrix is
(0, 0, 0, 1). (Such transformations are called _affine transformations_, those that
keep straight lines straight and parallel lines parallel.) However, this is not the case for
some transformations in the `MathUtil` class.
Transformations that don't necessarily preserve parallelism of lines are called _projective transformations_.
An NxN matrix can describe certain projective transformations if it has one more row and one more column
than the number of dimensions. For example, a 4 × 4 matrix can describe 3D projective transformations
in the form of linear transformations on homogeneous coordinates (see
[\*\*"Why a 4 × 4 Matrix?"\*\*](#Why_a_4x4_Matrix)). For a 3D projective transformation, the last row
in the matrix is not necessarily (0, 0, 0, 1).
One example of a projective transformation is found in a _perspective projection_ matrix,
as returned by <a href="MathUtil.html#MathUtil.mat4perspective">MathUtil.mat4perspective</a> or <a href="MathUtil.html#MathUtil.mat4frustum">MathUtil.mat4frustum</a>. When a 4-element vector is transformed with this matrix, its W component is generated by setting it to the negative z-coordinate in _eye space_, or more specifically, as follows:
\*\*a′\*\*<sub>_w_</sub> = 0 ⋅ \*\*a\*\*<sub>_x_</sub> + 0 ⋅ \*\*a\*\*<sub>_y_</sub> + -1 ⋅ \*\*a\*\*<sub>_z_</sub> + 0
For more on perspective projections, see <a href="tutorial-camera.html">_The "Camera" and Geometric Transforms_</a>.
Related functions:
<a href="MathUtil.html#MathUtil.mat4frustum">MathUtil.mat4frustum()</a> -
Returns a frustum matrix
<a href="MathUtil.html#MathUtil.mat4perspective">MathUtil.mat4perspective()</a> -
Returns a field-of-view perspective matrix
## Rotation Example
As an example, say we rotate 60 degrees about the x-axis (`mat4rotated(60, 1, 0, 0)`,
θ = 60°). First, we find the rotation formula for the x-axis:
\*\*a′\*\*<sub>_x_</sub> = 1 ⋅ \*\*a\*\*<sub>_x_</sub> + 0 ⋅ \*\*a\*\*<sub>_y_</sub> + 0 ⋅ \*\*a\*\*<sub>_z_</sub> + 0
\*\*a′\*\*<sub>_y_</sub> = 0 ⋅ \*\*a\*\*<sub>_x_</sub> + (cos θ) ⋅ \*\*a\*\*<sub>_y_</sub> + -(sin θ) ⋅ \*\*a\*\*<sub>_z_</sub> + 0
\*\*a′\*\*<sub>_z_</sub> = 0 ⋅ \*\*a\*\*<sub>_x_</sub> + (sin θ) ⋅ \*\*a\*\*<sub>_y_</sub> + (cos θ) ⋅ \*\*a\*\*<sub>_z_</sub> + 0
\*\*a′\*\*<sub>_w_</sub> = 0 ⋅ \*\*a\*\*<sub>_x_</sub> + 0 ⋅ \*\*a\*\*<sub>_y_</sub> + 0 ⋅ \*\*a\*\*<sub>_z_</sub> + 1 = 1
We calculate <i>cos θ</i> as 0.5 and <i>sin θ</i> as about 0.866025.
We plug those numbers into the rotation formula to get a formula for rotating a
point 60 degrees about the x-axis.
\*\*a′\*\*<sub>_x_</sub> = 1 ⋅ \*\*a\*\*<sub>_x_</sub> + 0 ⋅ \*\*a\*\*<sub>_y_</sub> + 0 ⋅ \*\*a\*\*<sub>_z_</sub> + 0 = \*\*a\*\*<sub>_x_</sub>
\*\*a′\*\*<sub>_y_</sub> ~= 0 ⋅ \*\*a\*\*<sub>_x_</sub> + 0.5 ⋅ \*\*a\*\*<sub>_y_</sub> + -0.866025 ⋅ \*\*a\*\*<sub>_z_</sub> + 0
\*\*a′\*\*<sub>_z_</sub> ~= 0 ⋅ \*\*a\*\*<sub>_x_</sub> + 0.866025 ⋅ \*\*a\*\*<sub>_y_</sub> + 0.5 ⋅ \*\*a\*\*<sub>_z_</sub> + 0
\*\*a′\*\*<sub>_w_</sub> = 0 ⋅ \*\*a\*\*<sub>_x_</sub> + 0 ⋅ \*\*a\*\*<sub>_y_</sub> + 0 ⋅ \*\*a\*\*<sub>_z_</sub> + 1 = 1
If a point is located at (10, 20, 30), the rotated point would now be:
\*\*a′\*\*<sub>_x_</sub> = 1 ⋅ 10 + 0 ⋅ 20 + 0 ⋅ 30 + 0
= 1 ⋅ 10
= 10
\*\*a′\*\*<sub>_y_</sub> ~= 0 ⋅ 10 + 0.5 ⋅ 20 + -0.866025 ⋅ 30 + 0
~= 0.5 ⋅ 20 + -0.866025 ⋅ 30
~= 10 + -25.98075
~= -15.98075
\*\*a′\*\*<sub>_z_</sub> ~= 0 ⋅ 10 + 0.866025 ⋅ 20 + 0.5 ⋅ 30 + 0
~= 0.866025 ⋅ 20 + 0.5 ⋅ 30
~= 17.3205 + 15
~= 32.3205
\*\*a′\*\*<sub>_w_</sub> = 0 ⋅ 10 + 0 ⋅ 20 + 0 ⋅ 30 + 1
= 1
So the rotated point would be at about (10, -15.98075, 32.3205).
## Describing Rotations
Rotations in 3D space can be described in many ways, including
quaternions, Tait-Bryan angles, and an angle and axis.
<a id="Axis_of_Rotation"></a>
### Axis of Rotation
A rotation of vectors or points can be described using an _angle_
and an _axis of rotation_, for example, in the <a href="MathUtil.html#MathUtil.mat4rotate">MathUtil.mat4rotate</a> method.
An axis of rotation is a vector pointing in a certain direction. When a point (or vector)
is rotated at any angle around this axis, the new point (or vector) will lie
on the same plane as the previous point. The axis of rotation describes
a vector that is perpendicular to that plane's surface (the plane's _normal_).
Here are examples of an axis of rotation.
The x-axis of rotation (upward or downward turn) is (1, 0, 0).
The y-axis of rotation (leftward or rightward turn) is (0, 1, 0).
The z-axis of rotation (side-by-side sway) is (0, 0, 1).
While the axis of rotation points backward from the "eye", if the angle's value
is positive and the [\*\*coordinate system\*\*](#Coordinate_Systems) is...
...right handed, then the angle runs counterclockwise.
...left handed, then the angle runs clockwise.
While the axis of rotation points backward from the "eye", if the angle's value
is negative, then the angle runs in the opposite direction.
Vectors that point in the same direction (for example, vectors (1, 0, 0) and (2, 0, 0))
describe the same axis of rotation.
Unless stated otherwise, an axis of rotation passed to a `MathUtil`
method need not be a [\*\*unit vector\*\*](#Unit_Vectors).
### Quaternions
A quaternion is a 4-element vector that can describe a 3D rotation. Functions dealing with quaternions begin with "quat". Functions that generate quaternions include: <a href="MathUtil.html#MathUtil.quatIdentity">MathUtil.quatIdentity</a>, which generates a quaternion describing an
absence of rotations; <a href="MathUtil.html#MathUtil.quatFromVectors">MathUtil.quatFromVectors</a>, which generates a quaternion describing
a rotation from one vector to another; <a href="MathUtil.html#MathUtil.quatFromMat4">MathUtil.quatFromMat4</a>, which generates a quaternion from a [\*\*4 × 4 matrix\*\*](#Matrices); <a href="MathUtil.html#MathUtil.quatFromAxisAngle">MathUtil.quatFromAxisAngle</a>, which generates a quaternion from an angle and [\*\*axis of rotation\*\*](#Axis_of_Rotation); MathUtil.quatFromTaitBryan, which generates a quaternion from Tait-Bryan angles.
<a id="Using_Quaternions"></a>
#### Using Quaternions
For best results when using quaternions:
- Store the rotation of each object as a single quaternion.
- As rotations occur each frame, convert the rotation (which may be
in pitch/yaw/roll or another form, depending on the input device) to a quaternion
(see [\*\*"Generating Quaternions"\*\*](#Generating_Quaternions)
and <a href="MathUtil.html#MathUtil.quatMultiply">multiply</a> that quaternion by the current
quaternion to get the object's new rotation.
- Normalize the rotation quaternion (using <a href="MathUtil.html#MathUtil.quatNormalize">`quatNormalize()`</a>
or <a href="MathUtil.html#MathUtil.quatNormalizeInPlace">`quatNormalizeInPlace()`</a>)
every few frames. (Quaternions that describe a 3D rotation should be [\*\*unit vectors\*\*](#Unit_Vectors).)
<a id="Multiplying_Quaternions"></a>
#### Multiplying Quaternions
When two quaternions are multiplied (for example, with {@MathUtil.quatMultiply}),
the result is a combined rotation in which the second rotation happens
before the first rotation (when applied in the global coordinate frame).
Like matrix multiplication, the order in which you multiply quaternions is important.
<a id="Tait_Bryan_angles"></a>
### Tait-Bryan angles
Pitch-yaw-roll angles (also called Tait-Bryan angles) describe three different rotations
of the same vector around three different axes, called the pitch, yaw, and roll axes
(or the X, Y, z-axes, respectively), which occur one after the other. However:
There are multiple conventions for pitch-yaw-roll angles, including the order of
rotations (for example: pitch-roll-yaw, roll-pitch-yaw), and whether the rotations occur
around the object's original axes ("extrinsic") or its new axes ("intrinsic").
Rotations are multiplied like in quaternions and matrices, so the order the rotations
occur is important. For example, a 30-degree pitch followed by a 20-degree
roll is not the same as a 20-degree pitch followed by a 30-degree roll.
Pitch-yaw-roll angles can cause a problem called "gimbal lock", in which a rotation along
one axis (say, a pitch) can cause a vector to be parallel to another axis (say, the roll
axis), so that a rotation along that axis will do nothing.
Related functions:
MathUtil.quatFromTaitBryan() -
Converts from Tait-Bryan angles to a quaternion
<a id=4 × 4_Matrices></a>
### 4 × 4 Matrices
A 4 × 4 matrix can describe a 3D vector rotation; see [\*\*"Rotation", earlier\*\*](#Rotation).
<a id="Planes"></a>
## Planes
A 4-element array can describe a plane in the following manner:
The 4 elements, labeled A, B, C, and D in that order, describe a plane
whose points satisfy the equation—
Ax + By + Cz + D = 0
where x, y, and z are the
coordinates of any point lying on the plane.
A, B, and C are
the X, Y, and Z components of the plane's normal vector.
D is the signed distance from the plane to the origin (0,0,0).
It's positive if the plane's normal points toward the origin, and
negative if it points away from the origin.
D is the negative dot product of the
plane's normal and any point on the plane.
There is one method that deals with planes:
<a href="MathUtil.html#MathUtil.planeNormalizeInPlace">MathUtil.planeNormalizeInPlace</a> - Converts the plane to a form in which
its normal has a length of 1.
<a id="Boxes"></a>
## Boxes
An array of six numbers can describe an axis-aligned bounding box (AABB).
If it does, the first three numbers are the box's minimum x-, y-, and z-coordinates,
and the last three numbers are the box's maximum x-, y-, and z-coordinates.
If a minimum coordinate is greater than a maximum coordinate, then the
box is considered empty.
Methods that deal with boxes include:
<a href="MathUtil.html#MathUtil.boxCenter">MathUtil.boxCenter</a> - Finds a box's center.
<a href="MathUtil.html#MathUtil.boxDimensions">MathUtil.boxDimensions</a> - Finds a box's dimensions.
<a href="MathUtil.html#MathUtil.boxIsEmpty">MathUtil.boxIsEmpty</a> - Determines whether a box is empty.
<a id="Coordinate_Systems"></a>
## Coordinate Systems
There are two conventions of 3D coordinate systems, left-handed and
right-handed:
In a _left-handed_ coordinate system, the positive z-axis points _forward from the "eye"_ whenever the positive x-axis points to the right and the positive y-axis points up.
In a _right-handed_ coordinate system, the positive z-axis points _backward from the "eye"_ whenever the positive x-axis points to the right and the positive y-axis points up.
To show this more visually, point one hand's thumb to your right and
its index finger up, and bend the other three fingers halfway down. In a
coordinate system named after that hand (left-handed or
right-handed), if the positive x-axis points in the thumb's
direction and the positive y-axis points in the index finger's direction, the z-axis will
point in the direction the other three fingers point.
As used here, the z-axis is the <a href="MathUtil.html#MathUtil.vec3cross">cross product</a>
of two perpendicular axes, namely the x-axis and the y-axis, in that order.
Which of the X, Y, or z-axes is the right, up, or forward axis is
arbitrary; for example, some conventions may have the z-axis, rather than Y,
be the up axis. Therefore, these three axes are defined here to avoid
confusion.
<a id="Differences_in_Behavior"></a>
### Differences in Behavior
<a id="Projection_and_view_matrices"></a>
#### Projection and view matrices
The difference between a left-handed and right-handed coordinate system
affects how 3D points are transformed, mainly in the projection and view
matrices. The projection and view matrices returned by Math
matrix methods are designed for a right-handed coordinate system. Their
documentation describes how to adjust them for a left-handed coordinate system.
<a id="Rotation_angles_such_as_used_in_mat4rotate_and_quatRotate"></a>
#### Rotation angles (such as used in `mat4rotate` and `quatRotate`)
While the [\*\*axis of rotation\*\*](#Axis_of_Rotation) points backward from the "eye", if the angle's value
is positive and the [\*\*coordinate system\*\*](#Coordinate_Systems) is...
...right handed, then the angle runs counterclockwise.
...left handed, then the angle runs clockwise.
While the axis of rotation points backward from the "eye", if the angle's value
is negative, then the angle runs in the opposite direction.
<a id="Cross_product_vec3cross_and_normals"></a>
#### Cross product (`vec3cross`) and normals
Given a triangle formed by...
- points (A minus C), (B minus C), and C, in that order, or
- points A, B, and (0, 0, 0), in that order,
the <a href="MathUtil.html#MathUtil.vec3cross">cross product</a> of the first point with the second,
in that order, is a _normal_ of that triangle (a vector that's perpendicular to the triangle's surface).
While this particular normal points backward from the "eye", the triangle's vertices
run in a counterclockwise path for right-handed coordinate systems, or a clockwise path
for left-handed systems. (In general, there are two possible choices for normals, which each
point in opposite directions.)
<a id="Winding_and_face_classification"></a>
### Winding and face classification
A two-dimensional triangle has counterclockwise _winding_ if its vertices are ordered in a counterclockwise path from the first to second to third to first vertex. Otherwise, it has clockwise winding. If the triangle is in 3D space, it's first transformed into 2D _window coordinates_ before its winding is found. (Window coordinates roughly correspond to screen pixels.)
By default, in the WebGL pipeline, triangles with counterclockwise winding are _front faces_, and
other triangles are _back faces_.
<a id="Finding_a_triangle_s_winding"></a>
#### Finding a triangle's winding
To find a triangle's winding, do the following calculation (X1, X2, X3 and Y1, Y2, Y3 are the window coordinates of its vertices). Note that half of the result will be the triangle's signed area.
(X3 - X1) \* (Y3 - Y2) - (X3 - X2) \* (Y3 - Y1)
If the result is positive, and the window space x-axis points right and the positive y-axis points...
...up (which is the case in WebGL), then the triangle
has counterclockwise winding.
...down, then the triangle has clockwise winding.
If the result is negative, then the triangle has the opposite winding.
### Members
* [GlobalPitchRollYaw](#MathUtil.GlobalPitchRollYaw)<br />Indicates that a vector's rotation occurs as a pitch, then roll, then yaw (each rotation around the original axes).
* [GlobalPitchYawRoll](#MathUtil.GlobalPitchYawRoll)<br />Indicates that a vector's rotation occurs as a pitch, then yaw, then roll (each rotation around the original axes).
* [GlobalRollPitchYaw](#MathUtil.GlobalRollPitchYaw)<br />Indicates that a vector's rotation occurs as a roll, then pitch, then yaw (each rotation around the original axes).
* [GlobalRollYawPitch](#MathUtil.GlobalRollYawPitch)<br />Indicates that a vector's rotation occurs as a roll, then yaw, then pitch (each rotation around the original axes).
* [GlobalYawPitchRoll](#MathUtil.GlobalYawPitchRoll)<br />Indicates that a vector's rotation occurs as a yaw, then pitch, then roll (each rotation around the original axes).
* [GlobalYawRollPitch](#MathUtil.GlobalYawRollPitch)<br />Indicates that a vector's rotation occurs as a yaw, then roll, then pitch (each rotation around the original axes).
* [HalfPi](#MathUtil.HalfPi)<br />Closest approximation to pi divided by 2, or a 90-degree turn in radians.
* [LocalPitchRollYaw](#MathUtil.LocalPitchRollYaw)<br />Indicates that a vector's rotation occurs as a pitch, then roll, then yaw, where the roll and yaw
occur around the rotated object's new axes and not necessarily the original axes.
* [LocalPitchYawRoll](#MathUtil.LocalPitchYawRoll)<br />Indicates that a vector's rotation occurs as a pitch, then yaw, then roll, where the yaw and roll
occur around the rotated object's new axes and not necessarily the original axes.
* [LocalRollPitchYaw](#MathUtil.LocalRollPitchYaw)<br />Indicates that a vector's rotation occurs as a roll, then pitch, then yaw, where the pitch and yaw
occur around the rotated object's new axes and not necessarily the original axes.
* [LocalRollYawPitch](#MathUtil.LocalRollYawPitch)<br />Indicates that a vector's rotation occurs as a roll, then yaw, then pitch, where the yaw and pitch
occur around the rotated object's new axes and not necessarily the original axes.
* [LocalYawPitchRoll](#MathUtil.LocalYawPitchRoll)<br />Indicates that a vector's rotation occurs as a yaw, then pitch, then roll, where the pitch and roll
occur around the rotated object's new axes and not necessarily the original axes.
* [LocalYawRollPitch](#MathUtil.LocalYawRollPitch)<br />Indicates that a vector's rotation occurs as a yaw, then roll, then pitch, where the roll and pitch
occur around the rotated object's new axes and not necessarily the original axes.
* [Num180DividedByPi](#MathUtil.Num180DividedByPi)<br />Closest approximation to 180 divided by pi, or the number of
degrees in a radian.
* [PiDividedBy180](#MathUtil.PiDividedBy180)<br />Closest approximation to pi divided by 180, or the number
of radians in a degree.
* [PiTimes2](#MathUtil.PiTimes2)<br />Closest approximation to pi times 2, or a 360-degree turn in radians.
* [ToDegrees](#MathUtil.ToDegrees)<br />Closest approximation to 180 divided by pi, or the number of
degrees in a radian.
* [ToRadians](#MathUtil.ToRadians)<br />Closest approximation to pi divided by 180, or the number
of radians in a degree.
### Methods
* [boxCenter](#MathUtil.boxCenter)<br />Finds the center of a 3D bounding box.
* [boxDimensions](#MathUtil.boxDimensions)<br />Finds the dimensions of a 3D bounding box.
* [boxIsEmpty](#MathUtil.boxIsEmpty)<br />Determines whether a 3D bounding box is empty.
* [colorToLinear](#MathUtil.colorToLinear)<br />Converts a color from encoded sRGB to linear sRGB using the sRGB transfer function, and returns
a new vector with the result.
* [colorTosRGB](#MathUtil.colorTosRGB)<br />Converts a color from linear sRGB to encoded sRGB using the sRGB transfer function, and returns
a new vector with the result.
* [frustumHasBox](#MathUtil.frustumHasBox)<br />Determines whether an axis-aligned bounding box
is at least partially inside a view frustum.
* [frustumHasPoint](#MathUtil.frustumHasPoint)<br />Determines whether a point is
outside or inside a view frustum.
* [frustumHasSphere](#MathUtil.frustumHasSphere)<br />Determines whether a sphere is at least
partially inside a view frustum.
* [interpCubicBezier](#MathUtil.interpCubicBezier)<br />An interpolation timing function based on the path of a
cubic Bézier
curve with end points (0, 0) and (1, 1) and with two
configurable control points.
* [mat3copy](#MathUtil.mat3copy)<br />Returns a copy of a 3 × 3 matrix.
* [mat3identity](#MathUtil.mat3identity)<br />Returns the identity 3 × 3 matrix (a matrix that keeps
vectors unchanged when they are transformed with this matrix).
* [mat3invert](#MathUtil.mat3invert)<br />Finds the inverse of a 3 × 3 matrix, describing a transformation that undoes the specified transformation.
* [mat3multiply](#MathUtil.mat3multiply)<br />Multiplies two 3 × 3 matrices.
* [mat3transform](#MathUtil.mat3transform)<br />Transforms a 3-element vector with a 3 × 3 matrix and returns
the transformed vector.
* [mat3transpose](#MathUtil.mat3transpose)<br />Returns the transpose of a 3 × 3 matrix.
* [mat3transposeInPlace](#MathUtil.mat3transposeInPlace)<br />Transposes a 3 × 3 matrix in place without creating
a new matrix.
* [mat4copy](#MathUtil.mat4copy)<br />Returns a copy of a 4 × 4 matrix.
* [mat4frustum](#MathUtil.mat4frustum)<br />Returns a 4 × 4 matrix representing a <a href="tutorial-camera.html">perspective projection</a>
in the form of a view frustum, or the limits in the "eye"'s view.
* [mat4identity](#MathUtil.mat4identity)<br />Returns the identity 4 × 4 matrix (a matrix that keeps
vectors unchanged when they are transformed with this matrix).
* [mat4inverseTranspose3](#MathUtil.mat4inverseTranspose3)<br />Returns the transposed result of the inverted 3 × 3 upper-left corner of
the specified 4 × 4 matrix.
* [mat4invert](#MathUtil.mat4invert)<br />Finds the inverse of a 4 × 4 matrix.
* [mat4isIdentity](#MathUtil.mat4isIdentity)<br />Returns whether a 4 × 4 matrix is the identity matrix.
* [mat4lookat](#MathUtil.mat4lookat)<br />Returns a 4 × 4 matrix that represents a "camera" view,
transforming world space coordinates, shared by every object in a scene, to coordinates in <i>eye space</i>
(also called <i>camera space</i> or <i>view space</i>).
* [mat4multiply](#MathUtil.mat4multiply)<br />Multiplies two 4 × 4 matrices.
* [mat4oblique](#MathUtil.mat4oblique)<br />Returns a 4 × 4 view matrix representing an oblique "eye" view,
when used in conjunction with an <a href="MathUtil.html#MathUtil.mat4ortho">orthographic projection</a>.
* [mat4ortho](#MathUtil.mat4ortho)<br />Returns a 4 × 4 matrix representing an <a href="tutorial-camera.html">orthographic projection</a>.
* [mat4ortho2d](#MathUtil.mat4ortho2d)<br />Returns a 4 × 4 matrix representing a 2D <a href="tutorial-camera.html">orthographic projection</a>.
* [mat4ortho2dAspect](#MathUtil.mat4ortho2dAspect)<br />Returns a 4 × 4 matrix representing a 2D <a href="tutorial-camera.html">orthographic projection</a>,
retaining the view rectangle's aspect ratio.
* [mat4orthoAspect](#MathUtil.mat4orthoAspect)<br />Returns a 4 × 4 matrix representing an <a href="tutorial-camera.html">orthographic projection</a>,
retaining the view rectangle's aspect ratio.
* [mat4perspective](#MathUtil.mat4perspective)<br />Returns a 4 × 4 matrix representing a <a href="tutorial-camera.html">perspective projection</a>.
* [mat4perspectiveHorizontal](#MathUtil.mat4perspectiveHorizontal)<br />Returns a 4 × 4 matrix representing a <a href="tutorial-camera.html">perspective projection</a>,
given an x-axis field of view.
* [mat4pickMatrix](#MathUtil.mat4pickMatrix)<br />Returns a 4 × 4 matrix that transforms the view to the center of the viewport.
* [mat4projectVec3](#MathUtil.mat4projectVec3)<br />Transforms a 3-element vector with a 4 × 4 matrix and returns
a perspective-correct version of the vector as a 3D point.
* [mat4rotate](#MathUtil.mat4rotate)<br />Multiplies a 4 × 4 matrix by a rotation transformation that rotates vectors
by the specified rotation angle and around the specified glmath,
and returns a new matrix.
* [mat4rotated](#MathUtil.mat4rotated)<br />Returns a 4 × 4 matrix representing a rotation transformation that rotates vectors
by the specified rotation angle and around the specified glmath.
* [mat4scale](#MathUtil.mat4scale)<br />Multiplies a 4 × 4 matrix by a scaling transformation.
* [mat4scaleInPlace](#MathUtil.mat4scaleInPlace)<br />Modifies a 4 × 4 matrix by multiplying it by a
scaling transformation.
* [mat4scaled](#MathUtil.mat4scaled)<br />Returns a 4 × 4 matrix representing a scaling transformation.
* [mat4toFrustumPlanes](#MathUtil.mat4toFrustumPlanes)<br />Finds the six clipping planes of a view frustum defined
by a 4 × 4 matrix.
* [mat4toMat3](#MathUtil.mat4toMat3)<br />Returns the upper-left part of a 4 × 4 matrix as a new
3 × 3 matrix.
* [mat4transform](#MathUtil.mat4transform)<br />Transforms a 4-element vector with a 4 × 4 matrix and returns
the transformed vector.
* [mat4transformVec3](#MathUtil.mat4transformVec3)<br />Transforms a 3-element vector with a 4 × 4 matrix as though it were
an affine transformation matrix (without perspective) and returns the transformed vector.
* [mat4translate](#MathUtil.mat4translate)<br />Multiplies a 4 × 4 matrix by a translation transformation.
* [mat4translated](#MathUtil.mat4translated)<br />Returns a 4 × 4 matrix representing a translation.
* [mat4transpose](#MathUtil.mat4transpose)<br />Returns the transpose of a 4 × 4 matrix.
* [mat4transposeInPlace](#MathUtil.mat4transposeInPlace)<br />Transposes a 4 × 4 matrix in place without creating
a new matrix.
* [planeFromNormalAndPoint](#MathUtil.planeFromNormalAndPoint)<br />Creates a plane from a normal vector and a point on the plane.
* [planeNormalize](#MathUtil.planeNormalize)<br />Normalizes this plane so that its normal is a unit vector,
unless all the normal's components are 0, and returns a new plane with the result.
* [planeNormalizeInPlace](#MathUtil.planeNormalizeInPlace)<br />Normalizes this plane so that its normal is a unit vector,
unless all the normal's components are 0, and sets this plane to the result.
* [quatConjugate](#MathUtil.quatConjugate)<br />Returns a quaternion that describes a rotation that undoes the specified rotation (an "inverted" rotation); this is done by reversing the sign of the X, Y, and Z components (which describe the quaternion's glmath).
* [quatCopy](#MathUtil.quatCopy)<br />Returns a copy of a quaternion.
* [quatDot](#MathUtil.quatDot)<br />Finds the dot product of two quaternions.
* [quatFromAxisAngle](#MathUtil.quatFromAxisAngle)<br />Generates a quaternion from a rotation transformation that rotates vectors
by the specified rotation angle and around the specified glmath,
* [quatFromMat4](#MathUtil.quatFromMat4)<br />Generates a quaternion from the vector rotation described in a 4 × 4 matrix.
* [quatFromVectors](#MathUtil.quatFromVectors)<br />Generates a quaternion describing a rotation between
two 3-element vectors.
* [quatIdentity](#MathUtil.quatIdentity)<br />Returns the identity quaternion of multiplication, (0, 0, 0, 1).
* [quatInvert](#MathUtil.quatInvert)<br />Returns a quaternion that describes a rotation that undoes the specified rotation (an "inverted" rotation) and is converted to a unit vector.
* [quatIsIdentity](#MathUtil.quatIsIdentity)<br />Returns whether this quaternion is the identity quaternion, (0, 0, 0, 1).
* [quatLength](#MathUtil.quatLength)<br />Returns the distance of this quaternion from the origin.
* [quatMultiply](#MathUtil.quatMultiply)<br />Multiplies two quaternions, creating a composite rotation.
* [quatNlerp](#MathUtil.quatNlerp)<br />Returns a quaternion that lies along the shortest path between the specified two quaternion rotations, using a linear interpolation function, and converts
it to a unit vector.
* [quatNormalize](#MathUtil.quatNormalize)<br />Converts a quaternion to a unit vector; returns a new quaternion.
* [quatNormalizeInPlace](#MathUtil.quatNormalizeInPlace)<br />Converts a quaternion to a unit vector.
* [quatRotate](#MathUtil.quatRotate)<br />Multiplies a quaternion by a rotation transformation that rotates vectors
by the specified rotation angle and around the specified glmath.
* [quatScale](#MathUtil.quatScale)<br />Multiplies each element of a quaternion by a factor
and returns the result as a new quaternion.
* [quatScaleInPlace](#MathUtil.quatScaleInPlace)<br />Multiplies each element of a quaternion by a factor
and stores the result in that quaternion.
* [quatSlerp](#MathUtil.quatSlerp)<br />Returns a quaternion that lies along the shortest path between the specified two quaternion rotations, using a spherical interpolation function.
* [quatToAxisAngle](#MathUtil.quatToAxisAngle)<br />Calculates the vector rotation for this quaternion in the form
of the angle to rotate the vector by and an glmath to
rotate that vector around.
* [quatToMat4](#MathUtil.quatToMat4)<br />Generates a 4 × 4 matrix describing the rotation
described by this quaternion.
* [quatTransform](#MathUtil.quatTransform)<br />Transforms a 3- or 4-element vector using a
quaternion's vector rotation.
* [vec2abs](#MathUtil.vec2abs)<br />Returns a new 2-element
vector with the absolute value of each of its components.
* [vec2absInPlace](#MathUtil.vec2absInPlace)<br />Sets each component of the specified 2-element
vector to its absolute value.
* [vec2add](#MathUtil.vec2add)<br />Adds two 2-element vectors and returns a new
vector with the result.
* [vec2addInPlace](#MathUtil.vec2addInPlace)<br />Adds two 2-element vectors and stores
the result in the first vector.
* [vec2assign](#MathUtil.vec2assign)<br />Assigns the values of a 2-element vector into another
2-element vector.
* [vec2clamp](#MathUtil.vec2clamp)<br />Returns a 2-element vector in which each element of the specified 2-element vector is clamped
so it's not less than one value or greater than another value.
* [vec2clampInPlace](#MathUtil.vec2clampInPlace)<br />Clamps each element of the specified 2-element vector
so it's not less than one value or greater than another value.
* [vec2copy](#MathUtil.vec2copy)<br />Returns a copy of a 2-element vector.
* [vec2dist](#MathUtil.vec2dist)<br />Finds the straight-line distance from one three-element vector
to another, treating both as 3D points.
* [vec2dot](#MathUtil.vec2dot)<br />Finds the dot product of two 2-element vectors.
* [vec2length](#MathUtil.vec2length)<br />Returns the distance of this 2-element vector from the origin,
also known as its <i>length</i> or <i>magnitude</i>.
* [vec2lerp](#MathUtil.vec2lerp)<br />Does a linear interpolation between two 2-element vectors;
returns a new vector.
* [vec2mul](#MathUtil.vec2mul)<br />Multiplies each of the components of two 2-element vectors and returns a new
vector with the result.
* [vec2mulInPlace](#MathUtil.vec2mulInPlace)<br />Multiplies each of the components of two 2-element vectors and stores
the result in the first vector.
* [vec2negate](#MathUtil.vec2negate)<br />Negates a 2-element vector and returns a new
vector with the result, which is generally a vector with
the same length but opposite direction.
* [vec2negateInPlace](#MathUtil.vec2negateInPlace)<br />Negates a 2-element vector in place, generally resulting in a vector with
the same length but opposite direction.
* [vec2normalize](#MathUtil.vec2normalize)<br />Converts a 2-element vector to a unit vector; returns a new vector.
* [vec2normalizeInPlace](#MathUtil.vec2normalizeInPlace)<br />Converts a 2-element vector to a unit vector.
* [vec2perp](#MathUtil.vec2perp)<br />Returns an arbitrary 2-element vector that is perpendicular
(orthogonal) to the specified 2-element vector.
* [vec2proj](#MathUtil.vec2proj)<br />Returns the projection of a 2-element vector on the specified
reference vector.
* [vec2reflect](#MathUtil.vec2reflect)<br />Returns a vector that reflects off a surface.
* [vec2scale](#MathUtil.vec2scale)<br />Multiplies each element of a 2-element vector by a factor.
* [vec2scaleInPlace](#MathUtil.vec2scaleInPlace)<br />Multiplies each element of a 2-element vector by a factor, so
that the vector is parallel to the old vector
but its length is multiplied by the specified factor.
* [vec2sub](#MathUtil.vec2sub)<br />Subtracts the second vector from the first vector and returns a new
vector with the result.
* [vec2subInPlace](#MathUtil.vec2subInPlace)<br />Subtracts the second vector from the first vector and stores
the result in the first vector.
* [vec3abs](#MathUtil.vec3abs)<br />Returns a new 3-element
vector with the absolute value of each of its components.
* [vec3absInPlace](#MathUtil.vec3absInPlace)<br />Sets each component of the specified 3-element
vector to its absolute value.
* [vec3add](#MathUtil.vec3add)<br />Adds two 3-element vectors and returns a new
vector with the result.
* [vec3addInPlace](#MathUtil.vec3addInPlace)<br />Adds two 3-element vectors and stores
the result in the first vector.
* [vec3assign](#MathUtil.vec3assign)<br />Assigns the values of a 3-element vector into another
3-element vector.
* [vec3clamp](#MathUtil.vec3clamp)<br />Returns a 3-element vector in which each element of the specified 3-element vector is clamped
so it's not less than one value or greater than another value.
* [vec3clampInPlace](#MathUtil.vec3clampInPlace)<br />Clamps each element of the specified 3-element vector
so it's not less than one value or greater than another value.
* [vec3copy](#MathUtil.vec3copy)<br />Returns a copy of a 3-element vector.
* [vec3cross](#MathUtil.vec3cross)<br />Finds the cross product of two 3-element vectors (called A and B).
* [vec3dist](#MathUtil.vec3dist)<br />Finds the straight-line distance from one three-element vector
to another, treating both as 3D points.
* [vec3dot](#MathUtil.vec3dot)<br />Finds the dot product of two 3-element vectors.
* [vec3fromWindowPoint](#MathUtil.vec3fromWindowPoint)<br />Unprojects the <i>window coordinates</i> given in a
3-element vector,
using the specified transformation matrix and viewport
rectangle.
* [vec3length](#MathUtil.vec3length)<br />Returns the distance of this 3-element vector from the origin,
also known as its <i>length</i> or <i>magnitude</i>.
* [vec3lerp](#MathUtil.vec3lerp)<br />Does a linear interpolation between two 3-element vectors;
returns a new vector.
* [vec3mul](#MathUtil.vec3mul)<br />Multiplies each of the components of two 3-element vectors and returns a new
vector with the result.
* [vec3mulInPlace](#MathUtil.vec3mulInPlace)<br />Multiplies each of the components of two 3-element vectors and stores
the result in the first vector.
* [vec3negate](#MathUtil.vec3negate)<br />Negates a 3-element vector and returns a new
vector with the result, which is generally a vector with
the same length but opposite direction.
* [vec3negateInPlace](#MathUtil.vec3negateInPlace)<br />Negates a 3-element vector in place, generally resulting in a vector with
the same length but opposite direction.
* [vec3normalize](#MathUtil.vec3normalize)<br />Converts a 3-element vector to a unit vector; returns a new vector.
* [vec3normalizeInPlace](#MathUtil.vec3normalizeInPlace)<br />Converts a 3-element vector to a unit vector.
* [vec3perp](#MathUtil.vec3perp)<br />Returns an arbitrary 3-element vector that is perpendicular
(orthogonal) to the specified 3-element vector.
* [vec3proj](#MathUtil.vec3proj)<br />Returns the projection of a 3-element vector on the specified
reference vector.
* [vec3reflect](#MathUtil.vec3reflect)<br />Returns a vector that reflects off a surface.
* [vec3scale](#MathUtil.vec3scale)<br />Multiplies each element of a 3-element vector by a factor.
* [vec3scaleInPlace](#MathUtil.vec3scaleInPlace)<br />Multiplies each element of a 3-element vector by a factor, so
that the vector is parallel to the old vector
but its length is multiplied by the specified factor.
* [vec3sub](#MathUtil.vec3sub)<br />Subtracts the second vector from the first vector and returns a new
vector with the result.
* [vec3subInPlace](#MathUtil.vec3subInPlace)<br />Subtracts the second vector from the first vector and stores
the result in the first vector.
* [vec3toWindowPoint](#MathUtil.vec3toWindowPoint)<br />Transforms the 3D point specified in this 3-element vector to its
<i>window coordinates</i>
using the specified transformation matrix and viewport rectangle.
* [vec3triple](#MathUtil.vec3triple)<br />Finds the scalar triple product of three vectors (A, B, and C).
* [vec4abs](#MathUtil.vec4abs)<br />Returns a new 4-element
vector with the absolute value of each of its components.
* [vec4absInPlace](#MathUtil.vec4absInPlace)<br />Sets each component of the specified 4-element
vector to its absolute value.
* [vec4add](#MathUtil.vec4add)<br />Adds two 4-element vectors and returns a new
vector with the result.
* [vec4addInPlace](#MathUtil.vec4addInPlace)<br />Adds two 4-element vectors and stores
the result in the first vector.
* [vec4assign](#MathUtil.vec4assign)<br />Assigns the values of a 4-element vector into another
4-element vector.
* [vec4clamp](#MathUtil.vec4clamp)<br />Returns a 4-element vector in which each element of the specified 4-element vector is clamped
* [vec4clampInPlace](#MathUtil.vec4clampInPlace)<br />Clamps each element of the specified 4-element vector
so it's not less than one value or greater than another value.
* [vec4copy](#MathUtil.vec4copy)<br />Returns a copy of a 4-element vector.
* [vec4dot](#MathUtil.vec4dot)<br />Finds the dot product of two 4-element vectors.
* [vec4length](#MathUtil.vec4length)<br />Returns the distance of this 4-element vector from the origin,
also known as its <i>length</i> or <i>magnitude</i>.
* [vec4lerp](#MathUtil.vec4lerp)<br />Does a linear interpolation between two 4-element vectors;
returns a new vector.
* [vec4negate](#MathUtil.vec4negate)<br />Negates a 4-element vector and returns a new
vector with the result, which is generally a vector with
the same length but opposite direction.
* [vec4negateInPlace](#MathUtil.vec4negateInPlace)<br />Negates a 4-element vector in place, generally resulting in a vector with
the same length but opposite direction.
* [vec4normalize](#MathUtil.vec4normalize)<br />Converts a 4-element vector to a unit vector; returns a new vector.
* [vec4normalizeInPlace](#MathUtil.vec4normalizeInPlace)<br />Converts a 4-element vector to a unit vector.
* [vec4proj](#MathUtil.vec4proj)<br />Returns the projection of a 4-element vector on the specified
reference vector.
* [vec4scale](#MathUtil.vec4scale)<br />Multiplies each element of a 4-element vector by a factor, returning
a new vector that is parallel to the old vector
but with its length multiplied by the specified factor.
* [vec4scaleInPlace](#MathUtil.vec4scaleInPlace)<br />Multiplies each element of a 4-element vector by a factor, so
that the vector is parallel to the old vector
but its length is multiplied by the specified factor.
* [vec4sub](#MathUtil.vec4sub)<br />Subtracts the second vector from the first vector and returns a new
vector with the result.
* [vec4subInPlace](#MathUtil.vec4subInPlace)<br />Subtracts the second vector from the first vector and stores
the result in the first vector.
<a name="MathUtil.GlobalPitchRollYaw"></a>
### MathUtil.GlobalPitchRollYaw (constant)
Indicates that a vector's rotation occurs as a pitch, then roll, then yaw (each rotation around the original axes).
<a name="MathUtil.GlobalPitchYawRoll"></a>
### MathUtil.GlobalPitchYawRoll (constant)
Indicates that a vector's rotation occurs as a pitch, then yaw, then roll (each rotation around the original axes).
<a name="MathUtil.GlobalRollPitchYaw"></a>
### MathUtil.GlobalRollPitchYaw (constant)
Indicates that a vector's rotation occurs as a roll, then pitch, then yaw (each rotation around the original axes).
<a name="MathUtil.GlobalRollYawPitch"></a>
### MathUtil.GlobalRollYawPitch (constant)
Indicates that a vector's rotation occurs as a roll, then yaw, then pitch (each rotation around the original axes).
<a name="MathUtil.GlobalYawPitchRoll"></a>
### MathUtil.GlobalYawPitchRoll (constant)