/
matrix.go
115 lines (94 loc) · 2.81 KB
/
matrix.go
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
package f32
import (
"golang.org/x/image/math/f32"
"math"
)
type Mat3 f32.Mat3
type Mat4 f32.Mat4
// SetCol sets a Column within the Matrix, so it mutates the calling matrix.
func (m *Mat3) SetCol(col int, v Vec3) {
m[col*3+0], m[col*3+1], m[col*3+2] = v[0], v[1], v[2]
}
// SetRow sets a Row within the Matrix, so it mutates the calling matrix.
func (m *Mat3) SetRow(row int, v Vec3) {
m[row+0], m[row+3], m[row+6] = v[0], v[1], v[2]
}
// Diag returns main diagonal (meaning all elements such that row==col).
func (m Mat3) Diag() Vec3 {
return Vec3{m[0], m[4], m[8]}
}
// Transform transforms (x, y) to (x1, y).
//
// matrix multiplication carried out on paper:
// |1 x| |c -s | |sx | | 1 ky | |1 -ox|
// | 1 y| |s c | | sy | |kx 1 | | 1 -oy|
// | 1| | 1| | 1| | 1| | 1 |
// move rotate scale skew origin
func (m Mat3) Transform(x, y float32) (x1, y1 float32) {
x1 = m[0]*x + m[3]*y + m[6]
y1 = m[1]*x + m[4]*y + m[7]
return
}
// Initialize defines a 3-D Matrix.
// | x |
// | y |
// | 1 |
// | e0 e3 e6 |
// | e1 e4 e7 |
// | e2 e5 e8 |
func (m *Mat3) Initialize(x, y, angle, sx, sy, ox, oy, kx, ky float32) {
c, s := cos(angle), sin(angle)
m[0] = c * sx - ky * s * sy // = a
m[1] = s * sx + ky * c * sy // = b
m[3] = kx * c * sx - s * sy // = c
m[4] = kx * s * sx + c * sy // = d
m[6] = x - ox * m[0] - oy * m[3]
m[7] = y - ox * m[1] - oy * m[4]
m[2], m[5] = 0, 0
m[8] = 1.0
}
func (m *Mat3) InitializeScale1(x, y, angle, ox, oy float32) {
c, s := cos(angle), sin(angle)
m[0] = c // = a
m[1] = s // = b
m[3] = - s // = c
m[4] = + c // = d
m[6] = x - ox * m[0] - oy * m[3]
m[7] = y - ox * m[1] - oy * m[4]
m[2], m[5] = 0, 0
m[8] = 1.0
}
func sin(r float32) float32 {
return float32(math.Sin(float64(r)))
}
func cos(r float32) float32 {
return float32(math.Cos(float64(r)))
}
// Ident3 returns the 3x3 identity matrix.
func Ident3() Mat3 {
return Mat3{1, 0, 0, 0, 1, 0, 0, 0, 1}
}
// SetCol sets a Column within the Matrix.
func (m *Mat4) SetCol(col int, v Vec4) {
m[col*4+0], m[col*4+1], m[col*4+2], m[col*4+3] = v[0], v[1], v[2], v[3]
}
// SetRow sets a Row within the Matrix.
func (m *Mat4) SetRow(row int, v Vec4) {
m[row+0], m[row+4], m[row+8], m[row+12] = v[0], v[1], v[2], v[3]
}
// Diag returns main diagonal (meaning all elements such that row==col).
func (m Mat4) Diag() Vec4 {
return Vec4{m[0], m[5], m[10], m[15]}
}
// Ident4 returns the 4x4 identity matrix.
func Ident4() Mat4 {
return Mat4{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}
}
// At returns the matrix element at the given row and column.
func (m Mat4) At(row, col int) float32 {
return m[col*4+row]
}
// Set sets the corresponding matrix element at the given row and column.
func (m *Mat4) Set(row, col int, value float32) {
m[col*4+row] = value
}