From d764afcb8f76c8a06da1ea9cdb62ae5b1462ce2e Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Fri, 26 Dec 2014 11:22:36 +0900 Subject: [PATCH] Make the elements of matrices optional --- affine.go | 3 ++- colormatrix.go | 45 ++++++++++++++++++++++++++++++------------ colormatrix_test.go | 35 ++++++++++++++++++++++++++++++++ geometrymatrix.go | 39 ++++++++++++++++++++++++++---------- geometrymatrix_test.go | 30 ++++++++++++++++++++++++++++ 5 files changed, 128 insertions(+), 24 deletions(-) diff --git a/affine.go b/affine.go index af81f4c08..f32beb57e 100644 --- a/affine.go +++ b/affine.go @@ -43,7 +43,8 @@ func add(lhs, rhs, result affine) { for i := 0; i < dim-1; i++ { for j := 0; j < dim; j++ { - result.SetElement(i, j, lhs.Element(i, j)+rhs.Element(i, j)) + v := lhs.Element(i, j) + rhs.Element(i, j) + result.SetElement(i, j, v) } } } diff --git a/colormatrix.go b/colormatrix.go index 7353ac71c..f86fa2bdc 100644 --- a/colormatrix.go +++ b/colormatrix.go @@ -29,32 +29,45 @@ const ColorMatrixDim = 5 // the color is multiplied again. type ColorMatrix struct { // es represents elements. - es [ColorMatrixDim - 1][ColorMatrixDim]float64 + es *[ColorMatrixDim - 1][ColorMatrixDim]float64 +} + +func colorMatrixEsI() *[ColorMatrixDim - 1][ColorMatrixDim]float64 { + return &[ColorMatrixDim - 1][ColorMatrixDim]float64{ + {1, 0, 0, 0, 0}, + {0, 1, 0, 0, 0}, + {0, 0, 1, 0, 0}, + {0, 0, 0, 1, 0}, + } } // NewColorMatrix returns an identity color matrix. func NewColorMatrix() ColorMatrix { return ColorMatrix{ - [ColorMatrixDim - 1][ColorMatrixDim]float64{ - {1, 0, 0, 0, 0}, - {0, 1, 0, 0, 0}, - {0, 0, 1, 0, 0}, - {0, 0, 0, 1, 0}, - }, + es: colorMatrixEsI(), } } -func (c *ColorMatrix) dim() int { +func (c ColorMatrix) dim() int { return ColorMatrixDim } // Element returns a value of a matrix at (i, j). -func (c *ColorMatrix) Element(i, j int) float64 { +func (c ColorMatrix) Element(i, j int) float64 { + if c.es == nil { + if i == j { + return 1 + } + return 0 + } return c.es[i][j] } // Concat multiplies a color matrix with the other color matrix. func (c *ColorMatrix) Concat(other ColorMatrix) { + if c.es == nil { + c.es = colorMatrixEsI() + } result := ColorMatrix{} mul(&other, c, &result) *c = result @@ -62,6 +75,9 @@ func (c *ColorMatrix) Concat(other ColorMatrix) { // Add adds a color matrix with the other color matrix. func (c *ColorMatrix) Add(other ColorMatrix) { + if c.es == nil { + c.es = colorMatrixEsI() + } result := ColorMatrix{} add(&other, c, &result) *c = result @@ -69,6 +85,9 @@ func (c *ColorMatrix) Add(other ColorMatrix) { // SetElement sets an element at (i, j). func (c *ColorMatrix) SetElement(i, j int, element float64) { + if c.es == nil { + c.es = colorMatrixEsI() + } c.es[i][j] = element } @@ -78,7 +97,7 @@ func Monochrome() ColorMatrix { const g = 23434.0 / 32768.0 const b = 2366.0 / 32768.0 return ColorMatrix{ - [ColorMatrixDim - 1][ColorMatrixDim]float64{ + &[ColorMatrixDim - 1][ColorMatrixDim]float64{ {r, g, b, 0, 0}, {r, g, b, 0, 0}, {r, g, b, 0, 0}, @@ -90,7 +109,7 @@ func Monochrome() ColorMatrix { // ScaleColor returns a color matrix that scales a color matrix by the given color (r, g, b, a). func ScaleColor(r, g, b, a float64) ColorMatrix { return ColorMatrix{ - [ColorMatrixDim - 1][ColorMatrixDim]float64{ + &[ColorMatrixDim - 1][ColorMatrixDim]float64{ {r, 0, 0, 0, 0}, {0, g, 0, 0, 0}, {0, 0, b, 0, 0}, @@ -102,7 +121,7 @@ func ScaleColor(r, g, b, a float64) ColorMatrix { // TranslateColor returns a color matrix that translates a color matrix by the given color (r, g, b, a). func TranslateColor(r, g, b, a float64) ColorMatrix { return ColorMatrix{ - [ColorMatrixDim - 1][ColorMatrixDim]float64{ + &[ColorMatrixDim - 1][ColorMatrixDim]float64{ {1, 0, 0, 0, r}, {0, 1, 0, 0, g}, {0, 0, 1, 0, b}, @@ -118,7 +137,7 @@ func RotateHue(theta float64) ColorMatrix { v2 := (1.0/3.0)*(1.0-cos) - math.Sqrt(1.0/3.0)*sin v3 := (1.0/3.0)*(1.0-cos) + math.Sqrt(1.0/3.0)*sin return ColorMatrix{ - [ColorMatrixDim - 1][ColorMatrixDim]float64{ + &[ColorMatrixDim - 1][ColorMatrixDim]float64{ {v1, v2, v3, 0, 0}, {v3, v1, v2, 0, 0}, {v2, v3, v1, 0, 0}, diff --git a/colormatrix_test.go b/colormatrix_test.go index 86837f362..701726f54 100644 --- a/colormatrix_test.go +++ b/colormatrix_test.go @@ -13,3 +13,38 @@ // limitations under the License. package ebiten_test + +import ( + . "." + "testing" +) + +func TestColorInit(t *testing.T) { + var m ColorMatrix + for i := 0; i < ColorMatrixDim-1; i++ { + for j := 0; j < ColorMatrixDim; j++ { + got := m.Element(i, j) + want := 0.0 + if i == j { + want = 1 + } + if want != got { + t.Errorf("m.Element(%d, %d) = %f, want %f", i, j, got, want) + } + } + } + + m.Add(m) + for i := 0; i < ColorMatrixDim-1; i++ { + for j := 0; j < ColorMatrixDim; j++ { + got := m.Element(i, j) + want := 0.0 + if i == j { + want = 2 + } + if want != got { + t.Errorf("m.Element(%d, %d) = %f, want %f", i, j, got, want) + } + } + } +} diff --git a/geometrymatrix.go b/geometrymatrix.go index 32893b781..d7449df16 100644 --- a/geometrymatrix.go +++ b/geometrymatrix.go @@ -24,30 +24,43 @@ const GeometryMatrixDim = 3 // A GeometryMatrix represents a matrix to transform geometry when rendering an image. type GeometryMatrix struct { // es represents elements. - es [GeometryMatrixDim - 1][GeometryMatrixDim]float64 + es *[GeometryMatrixDim - 1][GeometryMatrixDim]float64 +} + +func geometryMatrixEsI() *[GeometryMatrixDim - 1][GeometryMatrixDim]float64 { + return &[GeometryMatrixDim - 1][GeometryMatrixDim]float64{ + {1, 0, 0}, + {0, 1, 0}, + } } // NewGeometryMatrix returns an identity geometry matrix. func NewGeometryMatrix() GeometryMatrix { return GeometryMatrix{ - [GeometryMatrixDim - 1][GeometryMatrixDim]float64{ - {1, 0, 0}, - {0, 1, 0}, - }, + es: geometryMatrixEsI(), } } -func (g *GeometryMatrix) dim() int { +func (g GeometryMatrix) dim() int { return GeometryMatrixDim } // Element returns a value of a matrix at (i, j). -func (g *GeometryMatrix) Element(i, j int) float64 { +func (g GeometryMatrix) Element(i, j int) float64 { + if g.es == nil { + if i == j { + return 1 + } + return 0 + } return g.es[i][j] } // Concat multiplies a geometry matrix with the other geometry matrix. func (g *GeometryMatrix) Concat(other GeometryMatrix) { + if g.es == nil { + g.es = geometryMatrixEsI() + } result := GeometryMatrix{} mul(&other, g, &result) *g = result @@ -55,6 +68,9 @@ func (g *GeometryMatrix) Concat(other GeometryMatrix) { // Add adds a geometry matrix with the other geometry matrix. func (g *GeometryMatrix) Add(other GeometryMatrix) { + if g.es == nil { + g.es = geometryMatrixEsI() + } result := GeometryMatrix{} add(&other, g, &result) *g = result @@ -62,13 +78,16 @@ func (g *GeometryMatrix) Add(other GeometryMatrix) { // SetElement sets an element at (i, j). func (g *GeometryMatrix) SetElement(i, j int, element float64) { + if g.es == nil { + g.es = geometryMatrixEsI() + } g.es[i][j] = element } // ScaleGeometry returns a matrix that scales a geometry matrix by (x, y). func ScaleGeometry(x, y float64) GeometryMatrix { return GeometryMatrix{ - [2][3]float64{ + es: &[2][3]float64{ {x, 0, 0}, {0, y, 0}, }, @@ -78,7 +97,7 @@ func ScaleGeometry(x, y float64) GeometryMatrix { // TranslateGeometry returns a matrix taht translates a geometry matrix by (tx, ty). func TranslateGeometry(tx, ty float64) GeometryMatrix { return GeometryMatrix{ - [2][3]float64{ + es: &[2][3]float64{ {1, 0, tx}, {0, 1, ty}, }, @@ -89,7 +108,7 @@ func TranslateGeometry(tx, ty float64) GeometryMatrix { func RotateGeometry(theta float64) GeometryMatrix { sin, cos := math.Sincos(theta) return GeometryMatrix{ - [2][3]float64{ + es: &[2][3]float64{ {cos, -sin, 0}, {sin, cos, 0}, }, diff --git a/geometrymatrix_test.go b/geometrymatrix_test.go index 5c38c7f46..60be8740e 100644 --- a/geometrymatrix_test.go +++ b/geometrymatrix_test.go @@ -19,6 +19,36 @@ import ( "testing" ) +func TestGeometryInit(t *testing.T) { + var m GeometryMatrix + for i := 0; i < GeometryMatrixDim-1; i++ { + for j := 0; j < GeometryMatrixDim; j++ { + got := m.Element(i, j) + want := 0.0 + if i == j { + want = 1 + } + if want != got { + t.Errorf("m.Element(%d, %d) = %f, want %f", i, j, got, want) + } + } + } + + m.Add(m) + for i := 0; i < GeometryMatrixDim-1; i++ { + for j := 0; j < GeometryMatrixDim; j++ { + got := m.Element(i, j) + want := 0.0 + if i == j { + want = 2 + } + if want != got { + t.Errorf("m.Element(%d, %d) = %f, want %f", i, j, got, want) + } + } + } +} + func TestGeometryConcat(t *testing.T) { matrix1 := ScaleGeometry(2, 2) matrix2 := TranslateGeometry(1, 1)