affine: Add GeoM.Apply (#432)

This commit is contained in:
Hajime Hoshi 2017-09-16 17:19:45 +09:00
parent fc125eb531
commit 2a9873a4bb
3 changed files with 74 additions and 0 deletions

View File

@ -33,6 +33,12 @@ func (g *GeoM) Reset() {
g.impl.Reset() g.impl.Reset()
} }
// Apply pre-multiplies a vector (x, y) by the matrix.
// In other words, Apply calculates GeoM * (x, y).
func (g *GeoM) Apply(x, y float64) (x2, y2 float64) {
return g.impl.Apply(x, y)
}
// Element returns a value of a matrix at (i, j). // Element returns a value of a matrix at (i, j).
func (g *GeoM) Element(i, j int) float64 { func (g *GeoM) Element(i, j int) float64 {
a, b, c, d, tx, ty := g.impl.Elements() a, b, c, d, tx, ty := g.impl.Elements()

View File

@ -116,6 +116,67 @@ func TestGeoMConcatSelf(t *testing.T) {
} }
} }
func TestGeoMApply(t *testing.T) {
trans := GeoM{}
trans.Translate(1, 2)
scale := GeoM{}
scale.Scale(1.5, 2.5)
cpx := GeoM{}
cpx.Rotate(math.Pi)
cpx.Scale(1.5, 2.5)
cpx.Translate(-2, -3)
cases := []struct {
GeoM GeoM
InX float64
InY float64
OutX float64
OutY float64
Delta float64
}{
{
GeoM: GeoM{},
InX: 3.14159,
InY: 2.81828,
OutX: 3.14159,
OutY: 2.81828,
Delta: 0.00001,
},
{
GeoM: trans,
InX: 3.14159,
InY: 2.81828,
OutX: 4.14159,
OutY: 4.81828,
Delta: 0.00001,
},
{
GeoM: scale,
InX: 3.14159,
InY: 2.81828,
OutX: 4.71239,
OutY: 7.04570,
Delta: 0.00001,
},
{
GeoM: cpx,
InX: 3.14159,
InY: 2.81828,
OutX: -6.71239,
OutY: -10.04570,
Delta: 0.00001,
},
}
for _, c := range cases {
rx, ry := c.GeoM.Apply(c.InX, c.InY)
if math.Abs(rx-c.OutX) > c.Delta || math.Abs(ry-c.OutY) > c.Delta {
t.Errorf("%v.Apply(%v, %v) = (%v, %v), want (%v, %v)", c.GeoM, c.InX, c.InY, rx, ry, c.OutX, c.OutY)
}
}
}
func BenchmarkGeoM(b *testing.B) { func BenchmarkGeoM(b *testing.B) {
var m GeoM var m GeoM
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {

View File

@ -38,6 +38,13 @@ func (g *GeoM) Reset() {
g.inited = false g.inited = false
} }
func (g *GeoM) Apply(x, y float64) (x2, y2 float64) {
if !g.inited {
return x, y
}
return g.a*x + g.b*y + g.tx, g.c*x + g.d*y + g.ty
}
func (g *GeoM) Elements() (a, b, c, d, tx, ty float64) { func (g *GeoM) Elements() (a, b, c, d, tx, ty float64) {
if !g.inited { if !g.inited {
return 1, 0, 0, 1, 0, 0 return 1, 0, 0, 1, 0, 0