-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmatrix.go
114 lines (91 loc) · 2.07 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
package skin
import (
"image"
"math"
)
var (
sideMatrix matrix2x2 = rotationMatrix(degToRad(30)).Multiply(skewXMatrix(degToRad(30))).Multiply(scaleYMatrix(0.86603))
frontMatrix matrix2x2 = rotationMatrix(degToRad(-30)).Multiply(skewXMatrix(degToRad(-30))).Multiply(scaleYMatrix(0.86603))
plantMatrix matrix2x2 = rotationMatrix(degToRad(30)).Multiply(skewXMatrix(degToRad(-30))).Multiply(scaleYMatrix(0.86603))
)
type matrix2x2 [4]float64
func (a matrix2x2) Multiply(b matrix2x2) matrix2x2 {
return matrix2x2{
a[0]*b[0] + a[1]*b[2],
a[0]*b[1] + a[1]*b[3],
a[2]*b[0] + a[3]*b[2],
a[2]*b[1] + a[3]*b[3],
}
}
func (a matrix2x2) Determinant() float64 {
return a[0]*a[3] - a[1]*a[2]
}
func (a matrix2x2) Inverse() matrix2x2 {
d := a.Determinant()
return matrix2x2{
a[3] * (1.0 / d),
-a[1] * (1.0 / d),
-a[2] * (1.0 / d),
a[0] * (1.0 / d),
}
}
func scaleYMatrix(a float64) matrix2x2 {
return matrix2x2{
1, 0,
0, a,
}
}
func skewXMatrix(a float64) matrix2x2 {
return matrix2x2{
1, math.Tan(a),
0, 1,
}
}
func rotationMatrix(a float64) matrix2x2 {
return matrix2x2{
math.Cos(a), -math.Sin(a),
math.Sin(a), math.Cos(a),
}
}
func degToRad(a float64) float64 {
return a * (math.Pi / 180.0)
}
func transformRect(m matrix2x2, r image.Rectangle) (output image.Rectangle) {
ps := []image.Point{
{r.Min.X, r.Min.Y},
{r.Max.X, r.Min.Y},
{r.Min.X, r.Max.Y},
{r.Max.X, r.Max.Y},
}
for i, p := range ps {
sxf := float64(p.X)
syf := float64(p.Y)
dxi, dyi := translateCoordinatesWithMatrix(sxf, syf, m)
dx, dy := int(math.Floor(dxi)), int(math.Floor(dyi))
if i == 0 {
output = image.Rectangle{
Min: image.Point{dx + 0, dy + 0},
Max: image.Point{dx + 1, dy + 1},
}
continue
}
if output.Min.X > dx {
output.Min.X = dx
}
dx++
if output.Max.X < dx {
output.Max.X = dx
}
if output.Min.Y > dy {
output.Min.Y = dy
}
dy++
if output.Max.Y < dy {
output.Max.Y = dy
}
}
return output
}
func translateCoordinatesWithMatrix(x, y float64, b matrix2x2) (float64, float64) {
return b[0]*x + b[1]*y, b[2]*x + b[3]*y
}