diff --git a/transform.go b/transform.go index 2d73b56..0f1c657 100644 --- a/transform.go +++ b/transform.go @@ -98,6 +98,22 @@ func (t Transform) Rotate(angle float64) Transform { return t } +// Project transforms a vector by a transform. +func (t Transform) Project(v Vec) Vec { + mat := t.Mat3() + vec := mgl32.Vec3{float32(v.X()), float32(v.Y()), 1} + pro := mat.Mul3x1(vec) + return V(float64(pro.X()), float64(pro.Y())) +} + +// Unproject does the inverse operation to Project. +func (t Transform) Unproject(v Vec) Vec { + mat := t.InvMat3() + vec := mgl32.Vec3{float32(v.X()), float32(v.Y()), 1} + unp := mat.Mul3x1(vec) + return V(float64(unp.X()), float64(unp.Y())) +} + // Mat3 returns a transformation matrix that satisfies previously set transform properties. func (t Transform) Mat3() mgl32.Mat3 { mat := mgl32.Ident3() @@ -108,6 +124,16 @@ func (t Transform) Mat3() mgl32.Mat3 { return mat } +// InvMat3 returns an inverse transformation matrix to the matrix returned by Mat3 method. +func (t Transform) InvMat3() mgl32.Mat3 { + mat := mgl32.Ident3() + mat = mat.Mul3(mgl32.Translate2D(float32(t.anc.X()), float32(t.anc.Y()))) + mat = mat.Mul3(mgl32.Scale2D(float32(1/t.sca.X()), float32(1/t.sca.Y()))) + mat = mat.Mul3(mgl32.Rotate3DZ(float32(-t.rot))) + mat = mat.Mul3(mgl32.Translate2D(float32(-t.pos.X()), float32(-t.pos.Y()))) + return mat +} + // Camera is a convenience function, that returns a Transform that acts like a camera. // Center is the position in the world coordinates, that will be projected onto the center of the screen. // One unit in world coordinates will be projected onto zoom pixels.