2016-02-19 19:16:40 +01:00
|
|
|
package gg
|
|
|
|
|
|
|
|
import "math"
|
|
|
|
|
|
|
|
type Matrix struct {
|
|
|
|
XX, YX, XY, YY, X0, Y0 float64
|
|
|
|
}
|
|
|
|
|
|
|
|
func Identity() Matrix {
|
|
|
|
return Matrix{
|
|
|
|
1, 0,
|
|
|
|
0, 1,
|
|
|
|
0, 0,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func Translate(x, y float64) Matrix {
|
|
|
|
return Matrix{
|
|
|
|
1, 0,
|
|
|
|
0, 1,
|
|
|
|
x, y,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func Scale(x, y float64) Matrix {
|
|
|
|
return Matrix{
|
|
|
|
x, 0,
|
|
|
|
0, y,
|
|
|
|
0, 0,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-20 20:45:17 +01:00
|
|
|
func ScaleAbout(sx, sy, x, y float64) Matrix {
|
|
|
|
a := Translate(-x, -y)
|
|
|
|
b := Scale(sx, sy)
|
|
|
|
c := Translate(x, y)
|
|
|
|
return a.Multiply(b).Multiply(c)
|
|
|
|
}
|
|
|
|
|
2016-02-19 19:16:40 +01:00
|
|
|
func Rotate(angle float64) Matrix {
|
|
|
|
c := math.Cos(angle)
|
|
|
|
s := math.Sin(angle)
|
|
|
|
return Matrix{
|
|
|
|
c, s,
|
|
|
|
-s, c,
|
|
|
|
0, 0,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func RotateAbout(angle, x, y float64) Matrix {
|
2016-02-19 19:34:04 +01:00
|
|
|
a := Translate(-x, -y)
|
2016-02-19 19:16:40 +01:00
|
|
|
b := Rotate(angle)
|
2016-02-19 19:34:04 +01:00
|
|
|
c := Translate(x, y)
|
|
|
|
return a.Multiply(b).Multiply(c)
|
2016-02-19 19:16:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func Shear(x, y float64) Matrix {
|
|
|
|
return Matrix{
|
2016-02-20 20:53:33 +01:00
|
|
|
1, y,
|
|
|
|
x, 1,
|
2016-02-19 19:16:40 +01:00
|
|
|
0, 0,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-20 20:53:33 +01:00
|
|
|
func ShearAbout(sx, sy, x, y float64) Matrix {
|
|
|
|
a := Translate(-x, -y)
|
|
|
|
b := Shear(sx, sy)
|
|
|
|
c := Translate(x, y)
|
|
|
|
return a.Multiply(b).Multiply(c)
|
|
|
|
}
|
|
|
|
|
2016-02-19 19:16:40 +01:00
|
|
|
func (a Matrix) Multiply(b Matrix) Matrix {
|
|
|
|
return Matrix{
|
|
|
|
a.XX*b.XX + a.YX*b.XY,
|
|
|
|
a.XX*b.YX + a.YX*b.YY,
|
|
|
|
a.XY*b.XX + a.YY*b.XY,
|
|
|
|
a.XY*b.YX + a.YY*b.YY,
|
|
|
|
a.X0*b.XX + a.Y0*b.XY + b.X0,
|
|
|
|
a.X0*b.YX + a.Y0*b.YY + b.Y0,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a Matrix) TransformVector(x, y float64) (tx, ty float64) {
|
|
|
|
tx = a.XX*x + a.XY*y
|
|
|
|
ty = a.YX*x + a.YY*y
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a Matrix) TransformPoint(x, y float64) (tx, ty float64) {
|
|
|
|
tx = a.XX*x + a.XY*y + a.X0
|
|
|
|
ty = a.YX*x + a.YY*y + a.Y0
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a Matrix) Translate(x, y float64) Matrix {
|
|
|
|
return Translate(x, y).Multiply(a)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a Matrix) Scale(x, y float64) Matrix {
|
|
|
|
return Scale(x, y).Multiply(a)
|
|
|
|
}
|
|
|
|
|
2016-02-20 20:45:17 +01:00
|
|
|
func (a Matrix) ScaleAbout(sx, sy, x, y float64) Matrix {
|
|
|
|
return ScaleAbout(sx, sy, x, y).Multiply(a)
|
|
|
|
}
|
|
|
|
|
2016-02-19 19:16:40 +01:00
|
|
|
func (a Matrix) Rotate(angle float64) Matrix {
|
|
|
|
return Rotate(angle).Multiply(a)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a Matrix) RotateAbout(angle, x, y float64) Matrix {
|
|
|
|
return RotateAbout(angle, x, y).Multiply(a)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a Matrix) Shear(x, y float64) Matrix {
|
|
|
|
return Shear(x, y).Multiply(a)
|
|
|
|
}
|
2016-02-20 20:53:33 +01:00
|
|
|
|
|
|
|
func (a Matrix) ShearAbout(sx, sy, x, y float64) Matrix {
|
|
|
|
return ShearAbout(sx, sy, x, y).Multiply(a)
|
|
|
|
}
|