Class: SFML::Transform

Inherits:
Object
  • Object
show all
Defined in:
lib/sfml/graphics/transform.rb

Overview

A 2D affine transformation. Wraps the 3×3 matrix that SFML uses to combine translation, rotation, scaling, and skew. Useful when you want to:

- Apply the same transform across many drawables (push it via
  `RenderStates.new(transform: …)` instead of repeating
  `position=`/`rotation=` on every shape).
- Build a transform from primitive ops without holding a Drawable.

t = SFML::Transform.identity
      .translate([400, 300])
      .rotate(30)
      .scale([2, 2])

t.transform_point([10, 0])    #=> Vector2(world coord after t)
inv = t.inverse                #=> reverse mapping

Methods are chainable and **mutate in place**, returning self. To work with a fresh copy use ‘t.dup`. The CSFML constant for the identity is exposed via `Transform.identity`.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeTransform

Returns a new instance of Transform.



23
24
25
26
27
28
# File 'lib/sfml/graphics/transform.rb', line 23

def initialize
  @struct = C::Graphics::Transform.new
  # Start as identity by copying CSFML's sfTransform_Identity.
  identity_bytes = C::Graphics.sfTransform_Identity.pointer.read_bytes(C::Graphics::Transform.size)
  @struct.pointer.write_bytes(identity_bytes)
end

Class Method Details

.from_matrix(arr) ⇒ Object

Build from a flat row-major 9-element float array. Lays out as:

[a, b, c,
 d, e, f,
 g, h, i]   # SFML stores the 3x3 conceptually as a 4x4 padded

Raises:

  • (ArgumentError)


38
39
40
41
42
43
# File 'lib/sfml/graphics/transform.rb', line 38

def self.from_matrix(arr)
  raise ArgumentError, "expected 9-element matrix, got #{arr.length}" if arr.length != 9
  t = new
  9.times { |i| t.struct[:matrix][i] = arr[i].to_f }
  t
end

.identityObject



30
31
32
# File 'lib/sfml/graphics/transform.rb', line 30

def self.identity
  new
end

Instance Method Details

#==(other) ⇒ Object Also known as: eql?



123
124
125
126
# File 'lib/sfml/graphics/transform.rb', line 123

def ==(other)
  return false unless other.is_a?(Transform)
  C::Graphics.sfTransform_equal(@struct.pointer, other.struct.pointer)
end

#combine(other) ⇒ Object

Multiply this transform by another. ‘t.combine(t2)` is `t * t2` in left-to-right order (apply t2’s transformation, then t’s).

Raises:

  • (ArgumentError)


84
85
86
87
88
# File 'lib/sfml/graphics/transform.rb', line 84

def combine(other)
  raise ArgumentError, "Transform#combine needs another SFML::Transform" unless other.is_a?(Transform)
  C::Graphics.sfTransform_combine(@struct.pointer, other.struct.pointer)
  self
end

#hashObject



128
# File 'lib/sfml/graphics/transform.rb', line 128

def hash = matrix.hash

#initialize_dup(other) ⇒ Object



45
46
47
48
49
# File 'lib/sfml/graphics/transform.rb', line 45

def initialize_dup(other)
  super
  @struct = C::Graphics::Transform.new
  @struct.pointer.write_bytes(other.struct.pointer.read_bytes(C::Graphics::Transform.size))
end

#inverseObject

Return a new Transform that’s the inverse of this one — applying both in sequence yields the identity.



92
93
94
95
96
# File 'lib/sfml/graphics/transform.rb', line 92

def inverse
  result = C::Graphics.sfTransform_getInverse(@struct.pointer)
  t = allocate_new_with(result)
  t
end

#matrixObject

Read the matrix as a flat 9-element Array of floats (row-major).



119
120
121
# File 'lib/sfml/graphics/transform.rb', line 119

def matrix
  (0...9).map { |i| @struct[:matrix][i] }
end

#rotate(degrees, center: nil) ⇒ Object

Apply a rotation by ‘degrees`. Optional `center` to pivot around a non-origin point.



60
61
62
63
64
65
66
67
68
# File 'lib/sfml/graphics/transform.rb', line 60

def rotate(degrees, center: nil)
  if center
    c = _vec2(center)
    C::Graphics.sfTransform_rotateWithCenter(@struct.pointer, degrees.to_f, c.to_native_f)
  else
    C::Graphics.sfTransform_rotate(@struct.pointer, degrees.to_f)
  end
  self
end

#scale(factors, center: nil) ⇒ Object

Apply a scale. With ‘center:`, scales around that pivot.



71
72
73
74
75
76
77
78
79
80
# File 'lib/sfml/graphics/transform.rb', line 71

def scale(factors, center: nil)
  f = _vec2(factors)
  if center
    c = _vec2(center)
    C::Graphics.sfTransform_scaleWithCenter(@struct.pointer, f.to_native_f, c.to_native_f)
  else
    C::Graphics.sfTransform_scale(@struct.pointer, f.to_native_f)
  end
  self
end

#to_sObject Also known as: inspect



130
# File 'lib/sfml/graphics/transform.rb', line 130

def to_s = "Transform(#{matrix.map { |v| v.round(3) }.inspect})"

#transform_point(point) ⇒ Object

Map a point through the transform. Returns a Vector2.



99
100
101
102
103
# File 'lib/sfml/graphics/transform.rb', line 99

def transform_point(point)
  vec = _vec2(point)
  r   = C::Graphics.sfTransform_transformPoint(@struct.pointer, vec.to_native_f)
  Vector2.new(r[:x], r[:y])
end

#transform_rect(rect) ⇒ Object

Map a SFML::Rect through the transform. Returns a new Rect.

Raises:

  • (ArgumentError)


106
107
108
109
110
111
112
113
114
115
116
# File 'lib/sfml/graphics/transform.rb', line 106

def transform_rect(rect)
  raise ArgumentError, "Transform#transform_rect needs a SFML::Rect" unless rect.is_a?(Rect)
  native = C::Graphics::FloatRect.new
  native[:position][:x] = rect.x.to_f
  native[:position][:y] = rect.y.to_f
  native[:size][:x]     = rect.width.to_f
  native[:size][:y]     = rect.height.to_f

  r = C::Graphics.sfTransform_transformRect(@struct.pointer, native)
  Rect.from_native(r)
end

#translate(offset) ⇒ Object

Apply a translation. Mutates self.



52
53
54
55
56
# File 'lib/sfml/graphics/transform.rb', line 52

def translate(offset)
  vec = _vec2(offset)
  C::Graphics.sfTransform_translate(@struct.pointer, vec.to_native_f)
  self
end