mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
113 lines
2.5 KiB
Go
113 lines
2.5 KiB
Go
package graphics
|
|
|
|
type affineMatrixElement float64
|
|
|
|
type AffineMatrix struct {
|
|
elements []affineMatrixElement
|
|
dimension int
|
|
}
|
|
|
|
func NewAffineMatrix(dimension int) *AffineMatrix {
|
|
if dimension < 0 {
|
|
panic("invalid dimension")
|
|
}
|
|
matrix := &AffineMatrix{}
|
|
elementsNumber := dimension * (dimension - 1)
|
|
matrix.elements = make([]affineMatrixElement, elementsNumber)
|
|
matrix.dimension = dimension
|
|
return matrix
|
|
}
|
|
|
|
func IdentityAffineMatrix(dimension int) *AffineMatrix {
|
|
if dimension < 0 {
|
|
panic("invalid dimension")
|
|
}
|
|
matrix := NewAffineMatrix(dimension)
|
|
for i := 0; i < dimension-1; i++ {
|
|
for j := 0; j < dimension; j++ {
|
|
if i == j {
|
|
matrix.elements[i*dimension+j] = 1
|
|
} else {
|
|
matrix.elements[i*dimension+j] = 0
|
|
}
|
|
}
|
|
}
|
|
return matrix
|
|
}
|
|
|
|
func (matrix *AffineMatrix) Clone() *AffineMatrix {
|
|
result := NewAffineMatrix(matrix.dimension)
|
|
copy(result.elements, matrix.elements)
|
|
return result
|
|
}
|
|
|
|
func (matrix *AffineMatrix) Element(i, j int) float64 {
|
|
dimension := matrix.dimension
|
|
if i < 0 || dimension <= i {
|
|
panic("out of range index i")
|
|
}
|
|
if j < 0 || dimension <= j {
|
|
panic("out of range index j")
|
|
}
|
|
if i == dimension-1 {
|
|
if j == dimension-1 {
|
|
return 1
|
|
}
|
|
return 0
|
|
}
|
|
return float64(matrix.elements[i*dimension+j])
|
|
}
|
|
|
|
func (matrix *AffineMatrix) SetElement(i, j int, element float64) {
|
|
dimension := matrix.dimension
|
|
if i < 0 || dimension-1 <= i {
|
|
panic("out of range index i")
|
|
}
|
|
if j < 0 || dimension <= j {
|
|
panic("out of range index j")
|
|
}
|
|
matrix.elements[i*dimension+j] = affineMatrixElement(element)
|
|
}
|
|
|
|
func (matrix *AffineMatrix) IsIdentity() bool {
|
|
dimension := matrix.dimension
|
|
for i := 0; i < dimension-1; i++ {
|
|
for j := 0; j < dimension; j++ {
|
|
element := matrix.elements[i*dimension+j]
|
|
if i == j && element != 1 {
|
|
return false
|
|
} else if i != j && element != 0 {
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
/*
|
|
* TODO: The arguments' names are strange even though they are not wrong.
|
|
*/
|
|
func (rhs *AffineMatrix) Concat(lhs *AffineMatrix) *AffineMatrix {
|
|
dimension := lhs.dimension
|
|
if dimension != rhs.dimension {
|
|
panic("diffrent-sized matrices can't be concatenated")
|
|
}
|
|
result := NewAffineMatrix(dimension)
|
|
|
|
for i := 0; i < dimension-1; i++ {
|
|
for j := 0; j < dimension; j++ {
|
|
element := affineMatrixElement(0.0)
|
|
for k := 0; k < dimension-1; k++ {
|
|
element += lhs.elements[i*dimension+k] *
|
|
rhs.elements[k*dimension+j]
|
|
}
|
|
if j == dimension-1 {
|
|
element += lhs.elements[i*dimension+dimension-1]
|
|
}
|
|
result.elements[i*dimension+j] = element
|
|
}
|
|
}
|
|
|
|
return result
|
|
}
|