103 lines
2.4 KiB
Go
103 lines
2.4 KiB
Go
package engine
|
|
|
|
import "math"
|
|
|
|
// Matrix represents a 2D transformation matrix in the form:
|
|
// | A C E |
|
|
// | B D F |
|
|
// | 0 0 1 |
|
|
type Matrix struct {
|
|
A, B, C, D, E, F float64
|
|
}
|
|
|
|
// NewIdentityMatrix creates an identity matrix
|
|
func NewIdentityMatrix() Matrix {
|
|
return Matrix{
|
|
A: 1, B: 0, C: 0,
|
|
D: 1, E: 0, F: 0,
|
|
}
|
|
}
|
|
|
|
// Translate creates a translation matrix
|
|
func Translate(x, y float64) Matrix {
|
|
return Matrix{
|
|
A: 1, B: 0, C: 0,
|
|
D: 1, E: x, F: y,
|
|
}
|
|
}
|
|
|
|
// Rotate creates a rotation matrix for the given angle in radians
|
|
func Rotate(angle float64) Matrix {
|
|
cos := math.Cos(angle)
|
|
sin := math.Sin(angle)
|
|
return Matrix{
|
|
A: cos, B: sin, C: -sin,
|
|
D: cos, E: 0, F: 0,
|
|
}
|
|
}
|
|
|
|
// Scale creates a scaling matrix
|
|
func Scale(sx, sy float64) Matrix {
|
|
return Matrix{
|
|
A: sx, B: 0, C: 0,
|
|
D: sy, E: 0, F: 0,
|
|
}
|
|
}
|
|
|
|
// Multiply multiplies two matrices
|
|
func (m Matrix) Multiply(other Matrix) Matrix {
|
|
return Matrix{
|
|
A: m.A*other.A + m.C*other.B,
|
|
B: m.B*other.A + m.D*other.B,
|
|
C: m.A*other.C + m.C*other.D,
|
|
D: m.B*other.C + m.D*other.D,
|
|
E: m.A*other.E + m.C*other.F + m.E,
|
|
F: m.B*other.E + m.D*other.F + m.F,
|
|
}
|
|
}
|
|
|
|
// Transform represents a geometric transformation
|
|
type Transform struct {
|
|
x, y, size float64
|
|
rotation int // 0 = 0 rad, 1 = 0.5π rad, 2 = π rad, 3 = 1.5π rad
|
|
}
|
|
|
|
// NewTransform creates a new Transform
|
|
func NewTransform(x, y, size float64, rotation int) Transform {
|
|
return Transform{
|
|
x: x,
|
|
y: y,
|
|
size: size,
|
|
rotation: rotation,
|
|
}
|
|
}
|
|
|
|
// TransformIconPoint transforms a point based on the translation and rotation specification
|
|
// w and h represent the width and height of the transformed rectangle for proper corner positioning
|
|
func (t Transform) TransformIconPoint(x, y, w, h float64) Point {
|
|
right := t.x + t.size
|
|
bottom := t.y + t.size
|
|
rotation := t.rotation % 4
|
|
|
|
switch rotation {
|
|
case 1: // 90 degrees
|
|
return Point{X: right - y - h, Y: t.y + x}
|
|
case 2: // 180 degrees
|
|
return Point{X: right - x - w, Y: bottom - y - h}
|
|
case 3: // 270 degrees
|
|
return Point{X: t.x + y, Y: bottom - x - w}
|
|
default: // 0 degrees
|
|
return Point{X: t.x + x, Y: t.y + y}
|
|
}
|
|
}
|
|
|
|
// ApplyTransform applies a transformation matrix to a point
|
|
func ApplyTransform(point Point, matrix Matrix) Point {
|
|
return Point{
|
|
X: matrix.A*point.X + matrix.C*point.Y + matrix.E,
|
|
Y: matrix.B*point.X + matrix.D*point.Y + matrix.F,
|
|
}
|
|
}
|
|
|
|
// NoTransform represents an identity transformation
|
|
var NoTransform = NewTransform(0, 0, 0, 0) |