LMMS
Loading...
Searching...
No Matches
juce_AffineTransform.cpp
Go to the documentation of this file.
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 By using JUCE, you agree to the terms of both the JUCE 7 End-User License
11 Agreement and JUCE Privacy Policy.
12
13 End User License Agreement: www.juce.com/juce-7-licence
14 Privacy Policy: www.juce.com/juce-privacy-policy
15
16 Or: You may also use this code under the terms of the GPL v3 (see
17 www.gnu.org/licenses).
18
19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
21 DISCLAIMED.
22
23 ==============================================================================
24*/
25
26namespace juce
27{
28
29AffineTransform::AffineTransform (float m00, float m01, float m02,
30 float m10, float m11, float m12) noexcept
31 : mat00 (m00), mat01 (m01), mat02 (m02),
32 mat10 (m10), mat11 (m11), mat12 (m12)
33{
34}
35
36bool AffineTransform::operator== (const AffineTransform& other) const noexcept
37{
38 return mat00 == other.mat00
39 && mat01 == other.mat01
40 && mat02 == other.mat02
41 && mat10 == other.mat10
42 && mat11 == other.mat11
43 && mat12 == other.mat12;
44}
45
46bool AffineTransform::operator!= (const AffineTransform& other) const noexcept
47{
48 return ! operator== (other);
49}
50
51//==============================================================================
53{
54 return mat01 == 0.0f
55 && mat02 == 0.0f
56 && mat10 == 0.0f
57 && mat12 == 0.0f
58 && mat00 == 1.0f
59 && mat11 == 1.0f;
60}
61
62const AffineTransform AffineTransform::identity (1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
63
64//==============================================================================
66{
67 return { other.mat00 * mat00 + other.mat01 * mat10,
68 other.mat00 * mat01 + other.mat01 * mat11,
69 other.mat00 * mat02 + other.mat01 * mat12 + other.mat02,
70 other.mat10 * mat00 + other.mat11 * mat10,
71 other.mat10 * mat01 + other.mat11 * mat11,
72 other.mat10 * mat02 + other.mat11 * mat12 + other.mat12 };
73}
74
75AffineTransform AffineTransform::translated (float dx, float dy) const noexcept
76{
77 return { mat00, mat01, mat02 + dx,
78 mat10, mat11, mat12 + dy };
79}
80
82{
83 return { 1.0f, 0.0f, dx,
84 0.0f, 1.0f, dy };
85}
86
88{
89 return { mat00, mat01, tx,
90 mat10, mat11, ty };
91}
92
93AffineTransform AffineTransform::rotated (float rad) const noexcept
94{
95 auto cosRad = std::cos (rad);
96 auto sinRad = std::sin (rad);
97
98 return { cosRad * mat00 - sinRad * mat10,
99 cosRad * mat01 - sinRad * mat11,
100 cosRad * mat02 - sinRad * mat12,
101 sinRad * mat00 + cosRad * mat10,
102 sinRad * mat01 + cosRad * mat11,
103 sinRad * mat02 + cosRad * mat12 };
104}
105
107{
108 auto cosRad = std::cos (rad);
109 auto sinRad = std::sin (rad);
110
111 return { cosRad, -sinRad, 0,
112 sinRad, cosRad, 0 };
113}
114
115AffineTransform AffineTransform::rotation (float rad, float pivotX, float pivotY) noexcept
116{
117 auto cosRad = std::cos (rad);
118 auto sinRad = std::sin (rad);
119
120 return { cosRad, -sinRad, -cosRad * pivotX + sinRad * pivotY + pivotX,
121 sinRad, cosRad, -sinRad * pivotX + -cosRad * pivotY + pivotY };
122}
123
124AffineTransform AffineTransform::rotated (float angle, float pivotX, float pivotY) const noexcept
125{
126 return followedBy (rotation (angle, pivotX, pivotY));
127}
128
129AffineTransform AffineTransform::scaled (float factorX, float factorY) const noexcept
130{
131 return { factorX * mat00, factorX * mat01, factorX * mat02,
132 factorY * mat10, factorY * mat11, factorY * mat12 };
133}
134
135AffineTransform AffineTransform::scaled (float factor) const noexcept
136{
137 return { factor * mat00, factor * mat01, factor * mat02,
138 factor * mat10, factor * mat11, factor * mat12 };
139}
140
141AffineTransform AffineTransform::scale (float factorX, float factorY) noexcept
142{
143 return { factorX, 0, 0, 0, factorY, 0 };
144}
145
147{
148 return { factor, 0, 0, 0, factor, 0 };
149}
150
151AffineTransform AffineTransform::scaled (float factorX, float factorY,
152 float pivotX, float pivotY) const noexcept
153{
154 return { factorX * mat00, factorX * mat01, factorX * mat02 + pivotX * (1.0f - factorX),
155 factorY * mat10, factorY * mat11, factorY * mat12 + pivotY * (1.0f - factorY) };
156}
157
158AffineTransform AffineTransform::scale (float factorX, float factorY,
159 float pivotX, float pivotY) noexcept
160{
161 return { factorX, 0, pivotX * (1.0f - factorX),
162 0, factorY, pivotY * (1.0f - factorY) };
163}
164
165AffineTransform AffineTransform::shear (float shearX, float shearY) noexcept
166{
167 return { 1.0f, shearX, 0,
168 shearY, 1.0f, 0 };
169}
170
171AffineTransform AffineTransform::sheared (float shearX, float shearY) const noexcept
172{
173 return { mat00 + shearX * mat10,
174 mat01 + shearX * mat11,
175 mat02 + shearX * mat12,
176 mat10 + shearY * mat00,
177 mat11 + shearY * mat01,
178 mat12 + shearY * mat02 };
179}
180
182{
183 return { 1.0f, 0.0f, 0.0f,
184 0.0f, -1.0f, height };
185}
186
188{
189 double determinant = getDeterminant();
190
191 if (! approximatelyEqual (determinant, 0.0))
192 {
193 determinant = 1.0 / determinant;
194
195 auto dst00 = (float) ( mat11 * determinant);
196 auto dst10 = (float) (-mat10 * determinant);
197 auto dst01 = (float) (-mat01 * determinant);
198 auto dst11 = (float) ( mat00 * determinant);
199
200 return { dst00, dst01, -mat02 * dst00 - mat12 * dst01,
201 dst10, dst11, -mat02 * dst10 - mat12 * dst11 };
202 }
203
204 // singularity..
205 return *this;
206}
207
209{
210 return (mat00 * mat11 - mat10 * mat01) == 0.0f;
211}
212
214 float x10, float y10,
215 float x01, float y01) noexcept
216{
217 return { x10 - x00, x01 - x00, x00,
218 y10 - y00, y01 - y00, y00 };
219}
220
221AffineTransform AffineTransform::fromTargetPoints (float sx1, float sy1, float tx1, float ty1,
222 float sx2, float sy2, float tx2, float ty2,
223 float sx3, float sy3, float tx3, float ty3) noexcept
224{
225 return fromTargetPoints (sx1, sy1, sx2, sy2, sx3, sy3)
226 .inverted()
227 .followedBy (fromTargetPoints (tx1, ty1, tx2, ty2, tx3, ty3));
228}
229
231{
232 return mat01 == 0.0f
233 && mat10 == 0.0f
234 && mat00 == 1.0f
235 && mat11 == 1.0f;
236}
237
239{
240 return (mat00 * mat11) - (mat01 * mat10);
241}
242
244{
245 return (std::abs (mat00) + std::abs (mat11)) / 2.0f;
246}
247
248
249//==============================================================================
250//==============================================================================
251#if JUCE_UNIT_TESTS
252
253class AffineTransformTests : public UnitTest
254{
255public:
256 AffineTransformTests()
257 : UnitTest ("AffineTransform", UnitTestCategories::maths)
258 {}
259
260 void runTest() override
261 {
262 beginTest ("Determinant");
263 {
264 constexpr float scale1 = 1.5f, scale2 = 1.3f;
265
266 auto transform = AffineTransform::scale (scale1)
267 .followedBy (AffineTransform::rotation (degreesToRadians (72.0f)))
268 .followedBy (AffineTransform::translation (100.0f, 20.0f))
269 .followedBy (AffineTransform::scale (scale2));
270
271 expect (approximatelyEqual (std::sqrt (std::abs (transform.getDeterminant())), scale1 * scale2));
272 }
273 }
274};
275
276static AffineTransformTests timeTests;
277
278#endif
279
280} // namespace juce
#define noexcept
Definition DistrhoDefines.h:72
Definition juce_AffineTransform.h:43
AffineTransform scaled(float factorX, float factorY) const noexcept
Definition juce_AffineTransform.cpp:129
AffineTransform rotated(float angleInRadians) const noexcept
Definition juce_AffineTransform.cpp:93
float mat10
Definition juce_AffineTransform.h:300
bool isSingularity() const noexcept
Definition juce_AffineTransform.cpp:208
static AffineTransform scale(float factorX, float factorY) noexcept
Definition juce_AffineTransform.cpp:141
AffineTransform withAbsoluteTranslation(float translationX, float translationY) const noexcept
Definition juce_AffineTransform.cpp:87
float getDeterminant() const noexcept
Definition juce_AffineTransform.cpp:238
float mat11
Definition juce_AffineTransform.h:300
static AffineTransform fromTargetPoints(float x00, float y00, float x10, float y10, float x01, float y01) noexcept
Definition juce_AffineTransform.cpp:213
static const AffineTransform identity
Definition juce_AffineTransform.h:289
AffineTransform followedBy(const AffineTransform &other) const noexcept
Definition juce_AffineTransform.cpp:65
float mat12
Definition juce_AffineTransform.h:300
float mat02
Definition juce_AffineTransform.h:299
float mat01
Definition juce_AffineTransform.h:299
bool isOnlyTranslation() const noexcept
Definition juce_AffineTransform.cpp:230
bool isIdentity() const noexcept
Definition juce_AffineTransform.cpp:52
static AffineTransform translation(float deltaX, float deltaY) noexcept
Definition juce_AffineTransform.cpp:81
float getScaleFactor() const noexcept
Definition juce_AffineTransform.cpp:243
AffineTransform sheared(float shearX, float shearY) const noexcept
Definition juce_AffineTransform.cpp:171
static AffineTransform verticalFlip(float height) noexcept
Definition juce_AffineTransform.cpp:181
float mat00
Definition juce_AffineTransform.h:299
AffineTransform inverted() const noexcept
Definition juce_AffineTransform.cpp:187
AffineTransform translated(float deltaX, float deltaY) const noexcept
Definition juce_AffineTransform.cpp:75
static AffineTransform shear(float shearX, float shearY) noexcept
Definition juce_AffineTransform.cpp:165
static AffineTransform rotation(float angleInRadians) noexcept
Definition juce_AffineTransform.cpp:106
Definition juce_UnitTest.h:70
static int int height
Definition pugl.h:1594
Definition juce_UnitTestCategories.h:27
Definition carla_juce.cpp:31
bool approximatelyEqual(Type a, Type b) noexcept
Definition juce_MathsFunctions.h:324
dy
Definition zipinfo.c:2288
#define const
Definition zconf.h:137