struct Eagle::Transform2D

Overview

A 2D affine transform: translation, rotation and scale packed into a 3x2 matrix.

Most code never builds one by hand, because Node2D#position, Node2D#rotation and Node2D#scale are composed for you. Reach for Transform2D when you need the matrix itself: converting points between spaces, drawing with Graphics#apply, or baking a pose.

The matrix layout is:

[ a c tx ]
[ b d ty ]

Multiplying transforms composes them right to left, and multiplying by a Vec2 transforms a point.

t = Transform2D.trs(v2(200, 150), Mathf.deg2rad(45), v2(2, 2))
tip = t * v2(10, 0)             # local point to world
back = t.inverse * tip          # world point back to local => (10, 0)
dir = t.transform_dir(Vec2::RIGHT) # direction only, ignores translation

g.with_transform(t) { g.rect(-5, -5, 10, 10) } # draw in the transformed space

Defined in:

eagle/math/transform2d.cr

Constant Summary

IDENTITY = Transform2D.new

The transform that changes nothing.

Constructors

Instance Method Summary

Constructor Detail

def self.identity : Transform2D #

Returns IDENTITY.


def self.new(a : Float32 = 1_f32, b : Float32 = 0_f32, c : Float32 = 0_f32, d : Float32 = 1_f32, tx : Float32 = 0_f32, ty : Float32 = 0_f32) #

Creates a transform from raw matrix elements. The defaults give the identity.


def self.rotation(rad : Number) : Transform2D #

A pure rotation by rad radians around the origin.


def self.scale(v : Vec2) : Transform2D #

A pure scale by v.


def self.translation(v : Vec2) : Transform2D #

A pure translation by v.


def self.trs(pos : Vec2, rot : Number, scale : Vec2, pivot : Vec2 = Vec2::ZERO) : Transform2D #

Builds translation * rotation * scale in one step. pivot is the local point that ends up at pos, so the shape rotates and scales around it.


Instance Method Detail

def *(o : Transform2D) : Transform2D #

Composes two transforms: (a * b) * p == a * (b * p).


def *(p : Vec2) : Vec2 #

Transforms a point, applying translation.


def ==(o : Transform2D) : Bool #

Exact equality. Use #approx? for computed values.


def a : Float32 #

Matrix element: x-axis x component.


def a=(a : Float32) #

Matrix element: x-axis x component.


def approx?(o : Transform2D, eps = 1e-5) : Bool #

Component-wise comparison within eps.


def b : Float32 #

Matrix element: x-axis y component.


def b=(b : Float32) #

Matrix element: x-axis y component.


def c : Float32 #

Matrix element: y-axis x component.


def c=(c : Float32) #

Matrix element: y-axis x component.


def d : Float32 #

Matrix element: y-axis y component.


def d=(d : Float32) #

Matrix element: y-axis y component.


def inverse : Transform2D #

The inverse transform, which maps back from world to local space. Returns identity if the matrix can't be inverted, for example with a zero scale.


def rotation : Float32 #

The rotation part in radians.


def scale : Vec2 #

The scale along each axis.


def to_mat4 : Mat4 #

The same transform as a 4x4 matrix, for passing to shaders.


def transform_dir(v : Vec2) : Vec2 #

Transforms a direction, ignoring translation.


def translation : Vec2 #

The translation part.


def tx : Float32 #

Translation x.


def tx=(tx : Float32) #

Translation x.


def ty : Float32 #

Translation y.


def ty=(ty : Float32) #

Translation y.