github.com/danbrough/mobile@v0.0.3-beta03/exp/f32/affine.go (about)

     1  // Copyright 2014 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package f32
     6  
     7  import "fmt"
     8  
     9  // An Affine is a 3x3 matrix of float32 values for which the bottom row is
    10  // implicitly always equal to [0 0 1].
    11  // Elements are indexed first by row then column, i.e. m[row][column].
    12  type Affine [2]Vec3
    13  
    14  func (m Affine) String() string {
    15  	return fmt.Sprintf(`Affine[% 0.3f, % 0.3f, % 0.3f,
    16       % 0.3f, % 0.3f, % 0.3f]`,
    17  		m[0][0], m[0][1], m[0][2],
    18  		m[1][0], m[1][1], m[1][2])
    19  }
    20  
    21  // Identity sets m to be the identity transform.
    22  func (m *Affine) Identity() {
    23  	*m = Affine{
    24  		{1, 0, 0},
    25  		{0, 1, 0},
    26  	}
    27  }
    28  
    29  // Eq reports whether each component of m is within epsilon of the same
    30  // component in n.
    31  func (m *Affine) Eq(n *Affine, epsilon float32) bool {
    32  	for i := range m {
    33  		for j := range m[i] {
    34  			diff := m[i][j] - n[i][j]
    35  			if diff < -epsilon || +epsilon < diff {
    36  				return false
    37  			}
    38  		}
    39  	}
    40  	return true
    41  }
    42  
    43  // Mul sets m to be p × q.
    44  func (m *Affine) Mul(p, q *Affine) {
    45  	// Store the result in local variables, in case m == a || m == b.
    46  	m00 := p[0][0]*q[0][0] + p[0][1]*q[1][0]
    47  	m01 := p[0][0]*q[0][1] + p[0][1]*q[1][1]
    48  	m02 := p[0][0]*q[0][2] + p[0][1]*q[1][2] + p[0][2]
    49  	m10 := p[1][0]*q[0][0] + p[1][1]*q[1][0]
    50  	m11 := p[1][0]*q[0][1] + p[1][1]*q[1][1]
    51  	m12 := p[1][0]*q[0][2] + p[1][1]*q[1][2] + p[1][2]
    52  	m[0][0] = m00
    53  	m[0][1] = m01
    54  	m[0][2] = m02
    55  	m[1][0] = m10
    56  	m[1][1] = m11
    57  	m[1][2] = m12
    58  }
    59  
    60  // Inverse sets m to be the inverse of p.
    61  func (m *Affine) Inverse(p *Affine) {
    62  	m00 := p[1][1]
    63  	m01 := -p[0][1]
    64  	m02 := p[1][2]*p[0][1] - p[1][1]*p[0][2]
    65  	m10 := -p[1][0]
    66  	m11 := p[0][0]
    67  	m12 := p[1][0]*p[0][2] - p[1][2]*p[0][0]
    68  
    69  	det := m00*m11 - m10*m01
    70  
    71  	m[0][0] = m00 / det
    72  	m[0][1] = m01 / det
    73  	m[0][2] = m02 / det
    74  	m[1][0] = m10 / det
    75  	m[1][1] = m11 / det
    76  	m[1][2] = m12 / det
    77  }
    78  
    79  // Scale sets m to be a scale followed by p.
    80  // It is equivalent to m.Mul(p, &Affine{{x,0,0}, {0,y,0}}).
    81  func (m *Affine) Scale(p *Affine, x, y float32) {
    82  	m[0][0] = p[0][0] * x
    83  	m[0][1] = p[0][1] * y
    84  	m[0][2] = p[0][2]
    85  	m[1][0] = p[1][0] * x
    86  	m[1][1] = p[1][1] * y
    87  	m[1][2] = p[1][2]
    88  }
    89  
    90  // Translate sets m to be a translation followed by p.
    91  // It is equivalent to m.Mul(p, &Affine{{1,0,x}, {0,1,y}}).
    92  func (m *Affine) Translate(p *Affine, x, y float32) {
    93  	m[0][0] = p[0][0]
    94  	m[0][1] = p[0][1]
    95  	m[0][2] = p[0][0]*x + p[0][1]*y + p[0][2]
    96  	m[1][0] = p[1][0]
    97  	m[1][1] = p[1][1]
    98  	m[1][2] = p[1][0]*x + p[1][1]*y + p[1][2]
    99  }
   100  
   101  // Rotate sets m to a rotation in radians followed by p.
   102  // It is equivalent to m.Mul(p, affineRotation).
   103  func (m *Affine) Rotate(p *Affine, radians float32) {
   104  	s, c := Sin(radians), Cos(radians)
   105  	m.Mul(p, &Affine{
   106  		{+c, +s, 0},
   107  		{-s, +c, 0},
   108  	})
   109  }