2014-10-02 23:25:48 +00:00
|
|
|
|
// Copyright 2014 The Go Authors. All rights reserved.
|
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
|
|
package f32
|
|
|
|
|
|
|
|
|
|
import "fmt"
|
|
|
|
|
|
|
|
|
|
// An Affine is a 3x3 matrix of float32 values for which the bottom row is
|
|
|
|
|
// implicitly always equal to [0 0 1].
|
|
|
|
|
// Elements are indexed first by row then column, i.e. m[row][column].
|
|
|
|
|
type Affine [2]Vec3
|
|
|
|
|
|
2014-10-03 02:33:49 +00:00
|
|
|
|
func (m Affine) String() string {
|
2014-10-02 23:25:48 +00:00
|
|
|
|
return fmt.Sprintf(`Affine[% 0.3f, % 0.3f, % 0.3f,
|
|
|
|
|
% 0.3f, % 0.3f, % 0.3f]`,
|
|
|
|
|
m[0][0], m[0][1], m[0][2],
|
|
|
|
|
m[1][0], m[1][1], m[1][2])
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-09 02:48:17 +00:00
|
|
|
|
// Identity sets m to be the identity transform.
|
2014-10-02 23:25:48 +00:00
|
|
|
|
func (m *Affine) Identity() {
|
|
|
|
|
*m = Affine{
|
|
|
|
|
{1, 0, 0},
|
|
|
|
|
{0, 1, 0},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-09 02:48:17 +00:00
|
|
|
|
// Eq reports whether each component of m is within epsilon of the same
|
|
|
|
|
// component in n.
|
2014-10-02 23:25:48 +00:00
|
|
|
|
func (m *Affine) Eq(n *Affine, epsilon float32) bool {
|
|
|
|
|
for i := range m {
|
|
|
|
|
for j := range m[i] {
|
|
|
|
|
diff := m[i][j] - n[i][j]
|
|
|
|
|
if diff < -epsilon || +epsilon < diff {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-09 02:48:17 +00:00
|
|
|
|
// Mul sets m to be p × q.
|
|
|
|
|
func (m *Affine) Mul(p, q *Affine) {
|
2014-10-03 04:33:15 +00:00
|
|
|
|
// Store the result in local variables, in case m == a || m == b.
|
2014-10-09 02:48:17 +00:00
|
|
|
|
m00 := p[0][0]*q[0][0] + p[0][1]*q[1][0]
|
|
|
|
|
m01 := p[0][0]*q[0][1] + p[0][1]*q[1][1]
|
|
|
|
|
m02 := p[0][0]*q[0][2] + p[0][1]*q[1][2] + p[0][2]
|
|
|
|
|
m10 := p[1][0]*q[0][0] + p[1][1]*q[1][0]
|
|
|
|
|
m11 := p[1][0]*q[0][1] + p[1][1]*q[1][1]
|
|
|
|
|
m12 := p[1][0]*q[0][2] + p[1][1]*q[1][2] + p[1][2]
|
2014-10-03 04:33:15 +00:00
|
|
|
|
m[0][0] = m00
|
|
|
|
|
m[0][1] = m01
|
|
|
|
|
m[0][2] = m02
|
|
|
|
|
m[1][0] = m10
|
|
|
|
|
m[1][1] = m11
|
|
|
|
|
m[1][2] = m12
|
2014-10-02 23:25:48 +00:00
|
|
|
|
}
|
2014-10-09 02:48:17 +00:00
|
|
|
|
|
|
|
|
|
// Scale sets m to be a scale followed by p.
|
|
|
|
|
// It is equivalent to m.Mul(p, &Affine{{x,0,0}, {0,y,0}}).
|
|
|
|
|
func (m *Affine) Scale(p *Affine, x, y float32) {
|
|
|
|
|
m[0][0] = p[0][0] * x
|
|
|
|
|
m[0][1] = p[0][1] * y
|
|
|
|
|
m[0][2] = p[0][2]
|
|
|
|
|
m[1][0] = p[1][0] * x
|
|
|
|
|
m[1][1] = p[1][1] * y
|
|
|
|
|
m[1][2] = p[1][2]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Translate sets m to be a translation followed by p.
|
|
|
|
|
// It is equivalent to m.Mul(p, &Affine{{1,0,x}, {0,1,y}}).
|
|
|
|
|
func (m *Affine) Translate(p *Affine, x, y float32) {
|
|
|
|
|
m[0][0] = p[0][0]
|
|
|
|
|
m[0][1] = p[0][1]
|
|
|
|
|
m[0][2] = p[0][0]*x + p[0][1]*y + p[0][2]
|
|
|
|
|
m[1][0] = p[1][0]
|
|
|
|
|
m[1][1] = p[1][1]
|
|
|
|
|
m[1][2] = p[1][0]*x + p[1][1]*y + p[1][2]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Rotate sets m to a rotation in radians followed by p.
|
|
|
|
|
// It is equivalent to m.Mul(p, affineRotation).
|
|
|
|
|
func (m *Affine) Rotate(p *Affine, radians float32) {
|
|
|
|
|
s, c := Sin(radians), Cos(radians)
|
|
|
|
|
m.Mul(p, &Affine{
|
|
|
|
|
{+c, +s, 0},
|
|
|
|
|
{-s, +c, 0},
|
|
|
|
|
})
|
|
|
|
|
}
|