Class: Fontisan::SvgToGlyf::Geometry::AffineTransform
- Inherits:
-
Object
- Object
- Fontisan::SvgToGlyf::Geometry::AffineTransform
- Defined in:
- lib/fontisan/svg_to_glyf/geometry/affine_transform.rb
Overview
A 2×3 affine transform representing:
x' = a·x + c·y + e
y' = b·x + d·y + f
Every coordinate operation in SvgToGlyf (SVG group transforms, viewBox mapping, Y-flip, UPM scaling) is modeled as an AffineTransform so they can be composed into a single matrix applied once per point.
Instance Attribute Summary collapse
-
#a ⇒ Object
readonly
Returns the value of attribute a.
-
#b ⇒ Object
readonly
Returns the value of attribute b.
-
#c ⇒ Object
readonly
Returns the value of attribute c.
-
#d ⇒ Object
readonly
Returns the value of attribute d.
-
#e ⇒ Object
readonly
Returns the value of attribute e.
-
#f ⇒ Object
readonly
Returns the value of attribute f.
Class Method Summary collapse
-
.flip_y(axis) ⇒ Object
Reflect across a horizontal line at y = axis.
- .identity ⇒ Object
- .rotate_degrees(angle) ⇒ Object
- .rotate_radians(angle) ⇒ Object
- .scale(sx, sy = nil) ⇒ Object
- .skew_x_radians(angle) ⇒ Object
- .skew_y_radians(angle) ⇒ Object
- .translate(tx, ty = 0) ⇒ Object
Instance Method Summary collapse
- #==(other) ⇒ Object (also: #eql?)
-
#apply(x, y) ⇒ Array(Float, Float)
Transformed [x', y'].
-
#compose(other) ⇒ Object
Compose this transform with
other, returning a new AffineTransform equivalent to applyingotherfirst, thenself. - #hash ⇒ Object
- #identity? ⇒ Boolean
-
#initialize(a, b, c, d, e, f) ⇒ AffineTransform
constructor
A new instance of AffineTransform.
Constructor Details
#initialize(a, b, c, d, e, f) ⇒ AffineTransform
Returns a new instance of AffineTransform.
24 25 26 27 28 29 30 31 |
# File 'lib/fontisan/svg_to_glyf/geometry/affine_transform.rb', line 24 def initialize(a, b, c, d, e, f) @a = a.to_f @b = b.to_f @c = c.to_f @d = d.to_f @e = e.to_f @f = f.to_f end |
Instance Attribute Details
#a ⇒ Object (readonly)
Returns the value of attribute a.
16 17 18 |
# File 'lib/fontisan/svg_to_glyf/geometry/affine_transform.rb', line 16 def a @a end |
#b ⇒ Object (readonly)
Returns the value of attribute b.
16 17 18 |
# File 'lib/fontisan/svg_to_glyf/geometry/affine_transform.rb', line 16 def b @b end |
#c ⇒ Object (readonly)
Returns the value of attribute c.
16 17 18 |
# File 'lib/fontisan/svg_to_glyf/geometry/affine_transform.rb', line 16 def c @c end |
#d ⇒ Object (readonly)
Returns the value of attribute d.
16 17 18 |
# File 'lib/fontisan/svg_to_glyf/geometry/affine_transform.rb', line 16 def d @d end |
#e ⇒ Object (readonly)
Returns the value of attribute e.
16 17 18 |
# File 'lib/fontisan/svg_to_glyf/geometry/affine_transform.rb', line 16 def e @e end |
#f ⇒ Object (readonly)
Returns the value of attribute f.
16 17 18 |
# File 'lib/fontisan/svg_to_glyf/geometry/affine_transform.rb', line 16 def f @f end |
Class Method Details
.flip_y(axis) ⇒ Object
Reflect across a horizontal line at y = axis. Points above the axis map below it and vice versa.
66 67 68 |
# File 'lib/fontisan/svg_to_glyf/geometry/affine_transform.rb', line 66 def self.flip_y(axis) new(1, 0, 0, -1, 0, 2 * axis) end |
.identity ⇒ Object
33 34 35 |
# File 'lib/fontisan/svg_to_glyf/geometry/affine_transform.rb', line 33 def self.identity new(1, 0, 0, 1, 0, 0) end |
.rotate_degrees(angle) ⇒ Object
52 53 54 |
# File 'lib/fontisan/svg_to_glyf/geometry/affine_transform.rb', line 52 def self.rotate_degrees(angle) rotate_radians(angle.to_f * Math::PI / 180.0) end |
.rotate_radians(angle) ⇒ Object
46 47 48 49 50 |
# File 'lib/fontisan/svg_to_glyf/geometry/affine_transform.rb', line 46 def self.rotate_radians(angle) cos = Math.cos(angle) sin = Math.sin(angle) new(cos, sin, -sin, cos, 0, 0) end |
.scale(sx, sy = nil) ⇒ Object
41 42 43 44 |
# File 'lib/fontisan/svg_to_glyf/geometry/affine_transform.rb', line 41 def self.scale(sx, sy = nil) sy = sx if sy.nil? new(sx, 0, 0, sy, 0, 0) end |
.skew_x_radians(angle) ⇒ Object
56 57 58 |
# File 'lib/fontisan/svg_to_glyf/geometry/affine_transform.rb', line 56 def self.skew_x_radians(angle) new(1, 0, Math.tan(angle), 1, 0, 0) end |
.skew_y_radians(angle) ⇒ Object
60 61 62 |
# File 'lib/fontisan/svg_to_glyf/geometry/affine_transform.rb', line 60 def self.skew_y_radians(angle) new(1, Math.tan(angle), 0, 1, 0, 0) end |
.translate(tx, ty = 0) ⇒ Object
37 38 39 |
# File 'lib/fontisan/svg_to_glyf/geometry/affine_transform.rb', line 37 def self.translate(tx, ty = 0) new(1, 0, 0, 1, tx, ty) end |
Instance Method Details
#==(other) ⇒ Object Also known as: eql?
98 99 100 101 102 |
# File 'lib/fontisan/svg_to_glyf/geometry/affine_transform.rb', line 98 def ==(other) other.is_a?(AffineTransform) && @a == other.a && @b == other.b && @c == other.c && @d == other.d && @e == other.e && @f == other.f end |
#apply(x, y) ⇒ Array(Float, Float)
Returns transformed [x', y'].
90 91 92 |
# File 'lib/fontisan/svg_to_glyf/geometry/affine_transform.rb', line 90 def apply(x, y) [@a * x + @c * y + @e, @b * x + @d * y + @f] end |
#compose(other) ⇒ Object
Compose this transform with other, returning a new
AffineTransform equivalent to applying other first,
then self. This matches SVG's transform="self other"
convention.
result.apply(x, y) == self.apply(*other.apply(x, y))
76 77 78 79 80 81 82 83 84 85 |
# File 'lib/fontisan/svg_to_glyf/geometry/affine_transform.rb', line 76 def compose(other) AffineTransform.new( @a * other.a + @c * other.b, @b * other.a + @d * other.b, @a * other.c + @c * other.d, @b * other.c + @d * other.d, @a * other.e + @c * other.f + @e, @b * other.e + @d * other.f + @f, ) end |
#hash ⇒ Object
106 107 108 |
# File 'lib/fontisan/svg_to_glyf/geometry/affine_transform.rb', line 106 def hash [@a, @b, @c, @d, @e, @f].hash end |
#identity? ⇒ Boolean
94 95 96 |
# File 'lib/fontisan/svg_to_glyf/geometry/affine_transform.rb', line 94 def identity? @a == 1 && @b.zero? && @c.zero? && @d == 1 && @e.zero? && @f.zero? end |