From 2fa073ce90d69cf8cc707fda2789a4a80d653653 Mon Sep 17 00:00:00 2001 From: faiface Date: Fri, 2 Dec 2016 00:38:49 +0100 Subject: [PATCH] add Transform --- transform.go | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 transform.go diff --git a/transform.go b/transform.go new file mode 100644 index 0000000..a88c09c --- /dev/null +++ b/transform.go @@ -0,0 +1,74 @@ +package pixel + +import "github.com/go-gl/mathgl/mgl32" + +// Transform holds space transformation information. Concretely, a transformation is specified by position, +// anchor, scale and rotation. +// +// All points are first rotated around the anchor. Then they are multiplied by the scale. If the +// scale factor is 2, the object becomes 2x bigger. Finally, all points are moved, so that the original +// anchor is located precisely at the position. +// +// Create a Transform object with the Position function. This sets the position variable, which is the +// most important. Then use methods, like Scale and Rotate to change scale, rotation and achor. The order +// in which you apply these methods is irrelevant. +// +// pixel.Position(pixel.V(100, 100)).Rotate(math.Pi / 3).Scale(1.5) +type Transform struct { + pos, anc Vec + sca, rot float64 +} + +// Position creates a Transformation object with specified position. Anchor is (0, 0), rotation is 0 and scale is 1. +func Position(position Vec) Transform { + return Transform{ + pos: position, + sca: 1, + } +} + +// Move adds delta to position. +func (t Transform) Move(delta Vec) Transform { + t.pos += delta + return t +} + +// Anchor sets anchor. Anchor is the rotation center and will be moved to the position. +func (t Transform) Anchor(anchor Vec) Transform { + t.anc = anchor + return t +} + +// MoveAnchor adds delta to anchor. +func (t Transform) MoveAnchor(delta Vec) Transform { + t.anc += delta + return t +} + +// Scale scales the transform by the supplied factor. +// +// Note, that subsequent calls to this method accumulate the final scale factor. Scaling two times by 2 is equivalent +// to scaling once by 4. +func (t Transform) Scale(scale float64) Transform { + t.sca *= scale + return t +} + +// Rotate rotates the transform by the supplied angle in radians. +// +// Note, that subsequent calls to this method accumulate the final rotation. Rotating two times by Pi/2 is +// equivalent to rotating once by Pi. +func (t Transform) Rotate(angle float64) Transform { + t.rot += angle + return t +} + +// Mat3 returns a transformation matrix that satisfies previously set transform properties. +func (t Transform) Mat3() mgl32.Mat3 { + mat := mgl32.Ident3() + mat = mat.Mul3(mgl32.Translate2D(float32(t.pos.X()), float32(t.pos.Y()))) + mat = mat.Mul3(mgl32.Scale2D(float32(t.sca), float32(t.sca))) + mat = mat.Mul3(mgl32.Rotate3DZ(float32(t.rot))) + mat = mat.Mul3(mgl32.Translate2D(float32(t.anc.X()), float32(t.anc.Y()))) + return mat +}