Class: HexaPDF::Content::TransformationMatrix

Inherits:
Object
  • Object
show all
Includes:
Utils::MathHelpers
Defined in:
lib/hexapdf/content/transformation_matrix.rb

Overview

A TransformationMatrix is a matrix used in PDF graphics operations to specify the relationship between different coordinate systems.

All matrix operations modify the matrix in place. So if the original matrix should be preserved, duplicate it before the operation.

It is important to note that the matrix transforms from the new coordinate system to the untransformed coordinate system. This means that after the transformation all coordinates are specified in the new, transformed coordinate system and to get the untransformed coordinates the matrix needs to be applied.

Although all operations are done in 2D space the transformation matrix is a 3x3 matrix because homogeneous coordinates are used. This, however, also means that only six entries are actually used that are named like in the following graphic:

a b 0
c d 0
e f 1

Here is a simple transformation matrix to translate all coordinates by 5 units horizontally and 10 units vertically:

1  0 0
0  1 0
5 10 1

Details and some examples can be found in the PDF reference.

See: PDF1.7 s8.3

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Utils::MathHelpers

deg_to_rad, rad_to_deg

Constructor Details

#initialize(a = 1, b = 0, c = 0, d = 1, e = 0, f = 0) ⇒ TransformationMatrix

Initializes the transformation matrix with the given values.



91
92
93
94
95
96
97
98
# File 'lib/hexapdf/content/transformation_matrix.rb', line 91

def initialize(a = 1, b = 0, c = 0, d = 1, e = 0, f = 0)
  @a = a
  @b = b
  @c = c
  @d = d
  @e = e
  @f = f
end

Instance Attribute Details

#aObject (readonly)

The value at the position (1,1) in the matrix.



73
74
75
# File 'lib/hexapdf/content/transformation_matrix.rb', line 73

def a
  @a
end

#bObject (readonly)

The value at the position (1,2) in the matrix.



76
77
78
# File 'lib/hexapdf/content/transformation_matrix.rb', line 76

def b
  @b
end

#cObject (readonly)

The value at the position (2,1) in the matrix.



79
80
81
# File 'lib/hexapdf/content/transformation_matrix.rb', line 79

def c
  @c
end

#dObject (readonly)

The value at the position (2,2) in the matrix.



82
83
84
# File 'lib/hexapdf/content/transformation_matrix.rb', line 82

def d
  @d
end

#eObject (readonly)

The value at the position (3,1) in the matrix.



85
86
87
# File 'lib/hexapdf/content/transformation_matrix.rb', line 85

def e
  @e
end

#fObject (readonly)

The value at the position (3,2) in the matrix.



88
89
90
# File 'lib/hexapdf/content/transformation_matrix.rb', line 88

def f
  @f
end

Instance Method Details

#==(other) ⇒ Object

Returns true if the other object is a transformation matrix with the same values.



159
160
161
162
# File 'lib/hexapdf/content/transformation_matrix.rb', line 159

def ==(other)
  (other.kind_of?(self.class) && @a == other.a && @b == other.b && @c == other.c &&
    @d == other.d && @e == other.e && @f == other.f)
end

#evaluate(x, y) ⇒ Object

Returns the untransformed coordinates of the given point.



101
102
103
# File 'lib/hexapdf/content/transformation_matrix.rb', line 101

def evaluate(x, y)
  [@a * x + @c * y + @e, @b * x + @d * y + @f]
end

#premultiply(a, b, c, d, e, f) ⇒ Object

Transforms this matrix by premultiplying it with the given one (ie. given*this) and returns it.



144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/hexapdf/content/transformation_matrix.rb', line 144

def premultiply(a, b, c, d, e, f)
  a1 = a * @a + b * @c
  b1 = a * @b + b * @d
  c1 = c * @a + d * @c
  d1 = c * @b + d * @d
  @e = e * @a + f * @c + @e
  @f = e * @b + f * @d + @f
  @a = a1
  @b = b1
  @c = c1
  @d = d1
  self
end

#rotate(q) ⇒ Object

Rotates this matrix by an angle of q degrees and returns it.

This equal to premultiply(cos(rad(q)), sin(rad(q)), -sin(rad(q)), cos(rad(q)), x, y).



128
129
130
131
132
# File 'lib/hexapdf/content/transformation_matrix.rb', line 128

def rotate(q)
  cq = Math.cos(deg_to_rad(q))
  sq = Math.sin(deg_to_rad(q))
  premultiply(cq, sq, -sq, cq, 0, 0)
end

#scale(sx, sy) ⇒ Object

Scales this matrix by sx units horizontally and y units vertically and returns it.

This is equal to premultiply(sx, 0, 0, sy, 0, 0).



117
118
119
120
121
122
123
# File 'lib/hexapdf/content/transformation_matrix.rb', line 117

def scale(sx, sy)
  @a = sx * @a
  @b = sx * @b
  @c = sy * @c
  @d = sy * @d
  self
end

#skew(a, b) ⇒ Object

Skews this matrix by an angle of a degrees for the x axis and by an angle of b degrees for the y axis and returns it.

This is equal to premultiply(1, tan(rad(a)), tan(rad(b)), 1, x, y).



138
139
140
# File 'lib/hexapdf/content/transformation_matrix.rb', line 138

def skew(a, b)
  premultiply(1, Math.tan(deg_to_rad(a)), Math.tan(deg_to_rad(b)), 1, 0, 0)
end

#to_aObject

Creates an array [a, b, c, d, e, f] from the transformation matrix.



165
166
167
# File 'lib/hexapdf/content/transformation_matrix.rb', line 165

def to_a
  [@a, @b, @c, @d, @e, @f]
end

#translate(x, y) ⇒ Object

Translates this matrix by x units horizontally and y units vertically and returns it.

This is equal to premultiply(1, 0, 0, 1, x, y).



108
109
110
111
112
# File 'lib/hexapdf/content/transformation_matrix.rb', line 108

def translate(x, y)
  @e = x * @a + y * @c + @e
  @f = x * @b + y * @d + @f
  self
end