diff --git a/geom.go b/geom.go index f199c59ce..9a5fd3ec5 100644 --- a/geom.go +++ b/geom.go @@ -61,6 +61,10 @@ func (g *GeoM) apply32(x, y float32) (x2, y2 float32) { return (g.a_1+1)*x + g.b*y + g.tx, g.c*x + (g.d_1+1)*y + g.ty } +func (g *GeoM) elements() (a, b, c, d, tx, ty float32) { + return g.a_1 + 1, g.b, g.c, g.d_1 + 1, g.tx, g.ty +} + // Element returns a value of a matrix at (i, j). func (g *GeoM) Element(i, j int) float64 { switch { @@ -136,6 +140,10 @@ func (g *GeoM) Translate(tx, ty float64) { // Rotate rotates the matrix by theta. // The unit is radian. func (g *GeoM) Rotate(theta float64) { + if theta == 0 { + return + } + sin64, cos64 := math.Sincos(theta) sin, cos := float32(sin64), float32(cos64) diff --git a/image.go b/image.go index 5b3df3e2d..8da0e5245 100644 --- a/image.go +++ b/image.go @@ -130,8 +130,8 @@ type geoM32 struct { inner *GeoM } -func (g geoM32) Apply(x, y float32) (x2, y2 float32) { - return g.inner.apply32(x, y) +func (g geoM32) Elements() (a, b, c, d, tx, ty float32) { + return g.inner.elements() } // DrawImage draws the given image on the image i. diff --git a/internal/graphicsutil/vertices.go b/internal/graphicsutil/vertices.go index ac14ee157..1505905ce 100644 --- a/internal/graphicsutil/vertices.go +++ b/internal/graphicsutil/vertices.go @@ -44,7 +44,7 @@ func (v *verticesBackend) sliceForOneQuad() []float32 { } type GeoM interface { - Apply(x, y float32) (x2, y2 float32) + Elements() (a, b, c, d, tx, ty float32) } func QuadVertices(width, height int, sx0, sy0, sx1, sy1 int, geom GeoM) []float32 { @@ -55,9 +55,6 @@ func QuadVertices(width, height int, sx0, sy0, sx1, sy1 int, geom GeoM) []float3 return nil } - x0, y0 := float32(0.0), float32(0.0) - x1, y1 := float32(sx1-sx0), float32(sy1-sy0) - // it really feels like we should be able to cache this computation // but it may not matter. w := 1 @@ -71,16 +68,16 @@ func QuadVertices(width, height int, sx0, sy0, sx1, sy1 int, geom GeoM) []float3 wf := float32(w) hf := float32(h) u0, v0, u1, v1 := float32(sx0)/wf, float32(sy0)/hf, float32(sx1)/wf, float32(sy1)/hf - return quadVerticesImpl(u0, v0, u1, v1, x0, y0, x1, y1, geom) + return quadVerticesImpl(float32(sx1-sx0), float32(sy1-sy0), u0, v0, u1, v1, geom) } -func quadVerticesImpl(u0, v0, u1, v1, x0, y0, x1, y1 float32, geom GeoM) []float32 { +func quadVerticesImpl(x, y, u0, v0, u1, v1 float32, geom GeoM) []float32 { vs := theVerticesBackend.sliceForOneQuad() - x, y := geom.Apply(x0, y0) + a, b, c, d, tx, ty := geom.Elements() // Vertex coordinates - vs[0] = x - vs[1] = y + vs[0] = tx + vs[1] = ty // Texture coordinates: first 2 values indicates the actual coodinate, and // the second indicates diagonally opposite coodinates. @@ -91,25 +88,22 @@ func quadVerticesImpl(u0, v0, u1, v1, x0, y0, x1, y1 float32, geom GeoM) []float vs[5] = v1 // and the same for the other three coordinates - x, y = geom.Apply(x1, y0) - vs[6] = x - vs[7] = y + vs[6] = a*x + tx + vs[7] = c*x + ty vs[8] = u1 vs[9] = v0 vs[10] = u0 vs[11] = v1 - x, y = geom.Apply(x0, y1) - vs[12] = x - vs[13] = y + vs[12] = b*y + tx + vs[13] = d*y + ty vs[14] = u0 vs[15] = v1 vs[16] = u1 vs[17] = v0 - x, y = geom.Apply(x1, y1) - vs[18] = x - vs[19] = y + vs[18] = a*x + b*y + tx + vs[19] = c*x + d*y + ty vs[20] = u1 vs[21] = v1 vs[22] = u0 diff --git a/internal/restorable/image.go b/internal/restorable/image.go index 762b40cdc..7f045e7bb 100644 --- a/internal/restorable/image.go +++ b/internal/restorable/image.go @@ -129,8 +129,8 @@ type geoM struct { ty float32 } -func (g *geoM) Apply(x, y float32) (float32, float32) { - return x*g.scaleX + g.tx, y*g.scaleY + g.ty +func (g *geoM) Elements() (a, b, c, d, tx, ty float32) { + return g.scaleX, 0, 0, g.scaleY, g.tx, g.ty } // ReplacePixels replaces the image pixels with the given pixels slice. diff --git a/internal/restorable/images_test.go b/internal/restorable/images_test.go index cdd037a32..da0a774c7 100644 --- a/internal/restorable/images_test.go +++ b/internal/restorable/images_test.go @@ -107,8 +107,8 @@ var ( type idGeoM struct{} -func (idGeoM) Apply(x, y float32) (x2, y2 float32) { - return x, y +func (idGeoM) Elements() (a, b, c, d, tx, ty float32) { + return 1, 0, 0, 1, 0, 0 } func TestRestoreChain(t *testing.T) { @@ -267,8 +267,8 @@ type geoM struct { ty float32 } -func (g *geoM) Apply(x, y float32) (x2, y2 float32) { - return x + g.tx, y + g.ty +func (g *geoM) Elements() (a, b, c, d, tx, ty float32) { + return 1, 0, 0, 1, g.tx, g.ty } func TestRestoreComplexGraph(t *testing.T) { diff --git a/internal/shareable/shareable.go b/internal/shareable/shareable.go index fd83b1947..dd7200c73 100644 --- a/internal/shareable/shareable.go +++ b/internal/shareable/shareable.go @@ -100,8 +100,8 @@ type Image struct { type idGeoM struct{} -func (idGeoM) Apply(x, y float32) (x2, y2 float32) { - return x, y +func (idGeoM) Elements() (a, b, c, d, tx, ty float32) { + return 1, 0, 0, 1, 0, 0 } func (i *Image) ensureNotShared() { diff --git a/internal/shareable/shareable_test.go b/internal/shareable/shareable_test.go index b2a929959..fff536142 100644 --- a/internal/shareable/shareable_test.go +++ b/internal/shareable/shareable_test.go @@ -50,8 +50,8 @@ type geoM struct { ty float32 } -func (g *geoM) Apply(x, y float32) (x2, y2 float32) { - return x + g.tx, y + g.ty +func (g *geoM) Elements() (a, b, c, d, tx, ty float32) { + return 1, 0, 0, 1, g.tx, g.ty } func TestEnsureNotShared(t *testing.T) {