JUCE-7.0.12-0-g4f43011b96 JUCE-7.0.12-0-g4f43011b96
JUCE — C++ application framework with suport for VST, VST3, LV2 audio plug-ins

« « « Anklang Documentation
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
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
37{
38 const auto tie = [] (const AffineTransform& a)
39 {
40 return std::tie (a.mat00, a.mat01, a.mat02, a.mat10, a.mat11, a.mat12);
41 };
42
43 return tie (*this) == tie (other);
44}
45
47{
48 return ! operator== (other);
49}
50
51//==============================================================================
53{
55}
56
57const AffineTransform AffineTransform::identity (1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
58
59//==============================================================================
61{
62 return { other.mat00 * mat00 + other.mat01 * mat10,
63 other.mat00 * mat01 + other.mat01 * mat11,
64 other.mat00 * mat02 + other.mat01 * mat12 + other.mat02,
65 other.mat10 * mat00 + other.mat11 * mat10,
66 other.mat10 * mat01 + other.mat11 * mat11,
67 other.mat10 * mat02 + other.mat11 * mat12 + other.mat12 };
68}
69
70AffineTransform AffineTransform::translated (float dx, float dy) const noexcept
71{
72 return { mat00, mat01, mat02 + dx,
73 mat10, mat11, mat12 + dy };
74}
75
77{
78 return { 1.0f, 0.0f, dx,
79 0.0f, 1.0f, dy };
80}
81
83{
84 return { mat00, mat01, tx,
85 mat10, mat11, ty };
86}
87
89{
90 auto cosRad = std::cos (rad);
91 auto sinRad = std::sin (rad);
92
93 return { cosRad * mat00 - sinRad * mat10,
94 cosRad * mat01 - sinRad * mat11,
95 cosRad * mat02 - sinRad * mat12,
96 sinRad * mat00 + cosRad * mat10,
97 sinRad * mat01 + cosRad * mat11,
98 sinRad * mat02 + cosRad * mat12 };
99}
100
102{
103 auto cosRad = std::cos (rad);
104 auto sinRad = std::sin (rad);
105
106 return { cosRad, -sinRad, 0,
107 sinRad, cosRad, 0 };
108}
109
111{
112 auto cosRad = std::cos (rad);
113 auto sinRad = std::sin (rad);
114
115 return { cosRad, -sinRad, -cosRad * pivotX + sinRad * pivotY + pivotX,
117}
118
119AffineTransform AffineTransform::rotated (float angle, float pivotX, float pivotY) const noexcept
120{
121 return followedBy (rotation (angle, pivotX, pivotY));
122}
123
125{
126 return { factorX * mat00, factorX * mat01, factorX * mat02,
127 factorY * mat10, factorY * mat11, factorY * mat12 };
128}
129
130AffineTransform AffineTransform::scaled (float factor) const noexcept
131{
132 return { factor * mat00, factor * mat01, factor * mat02,
133 factor * mat10, factor * mat11, factor * mat12 };
134}
135
137{
138 return { factorX, 0, 0, 0, factorY, 0 };
139}
140
142{
143 return { factor, 0, 0, 0, factor, 0 };
144}
145
147 float pivotX, float pivotY) const noexcept
148{
149 return { factorX * mat00, factorX * mat01, factorX * mat02 + pivotX * (1.0f - factorX),
150 factorY * mat10, factorY * mat11, factorY * mat12 + pivotY * (1.0f - factorY) };
151}
152
154 float pivotX, float pivotY) noexcept
155{
156 return { factorX, 0, pivotX * (1.0f - factorX),
157 0, factorY, pivotY * (1.0f - factorY) };
158}
159
161{
162 return { 1.0f, shearX, 0,
163 shearY, 1.0f, 0 };
164}
165
167{
168 return { mat00 + shearX * mat10,
169 mat01 + shearX * mat11,
170 mat02 + shearX * mat12,
171 mat10 + shearY * mat00,
172 mat11 + shearY * mat01,
173 mat12 + shearY * mat02 };
174}
175
177{
178 return { 1.0f, 0.0f, 0.0f,
179 0.0f, -1.0f, height };
180}
181
183{
184 double determinant = getDeterminant();
185
186 if (! approximatelyEqual (determinant, 0.0))
187 {
188 determinant = 1.0 / determinant;
189
190 auto dst00 = (float) ( mat11 * determinant);
191 auto dst10 = (float) (-mat10 * determinant);
192 auto dst01 = (float) (-mat01 * determinant);
193 auto dst11 = (float) ( mat00 * determinant);
194
195 return { dst00, dst01, -mat02 * dst00 - mat12 * dst01,
196 dst10, dst11, -mat02 * dst10 - mat12 * dst11 };
197 }
198
199 // singularity..
200 return *this;
201}
202
204{
205 return exactlyEqual (mat00 * mat11 - mat10 * mat01, 0.0f);
206}
207
209 float x10, float y10,
210 float x01, float y01) noexcept
211{
212 return { x10 - x00, x01 - x00, x00,
213 y10 - y00, y01 - y00, y00 };
214}
215
217 float sx2, float sy2, float tx2, float ty2,
218 float sx3, float sy3, float tx3, float ty3) noexcept
219{
220 return fromTargetPoints (sx1, sy1, sx2, sy2, sx3, sy3)
221 .inverted()
222 .followedBy (fromTargetPoints (tx1, ty1, tx2, ty2, tx3, ty3));
223}
224
226{
227 return exactlyEqual (mat01, 0.0f)
228 && exactlyEqual (mat10, 0.0f)
229 && exactlyEqual (mat00, 1.0f)
230 && exactlyEqual (mat11, 1.0f);
231}
232
234{
235 return (mat00 * mat11) - (mat01 * mat10);
236}
237
238float AffineTransform::getScaleFactor() const noexcept
239{
240 return (std::abs (mat00) + std::abs (mat11)) / 2.0f;
241}
242
243
244//==============================================================================
245//==============================================================================
246#if JUCE_UNIT_TESTS
247
248class AffineTransformTests final : public UnitTest
249{
250public:
252 : UnitTest ("AffineTransform", UnitTestCategories::maths)
253 {}
254
255 void runTest() override
256 {
257 beginTest ("Determinant");
258 {
259 constexpr float scale1 = 1.5f, scale2 = 1.3f;
260
265
266 expect (approximatelyEqual (std::sqrt (std::abs (transform.getDeterminant())), scale1 * scale2));
267 }
268 }
269};
270
272
273#endif
274
275} // namespace juce
Represents a 2D affine-transformation matrix.
AffineTransform scaled(float factorX, float factorY) const noexcept
Returns a transform which is the same as this one followed by a re-scaling.
AffineTransform rotated(float angleInRadians) const noexcept
Returns a transform which is the same as this one followed by a rotation.
bool isSingularity() const noexcept
Returns true if this transform maps to a singularity - i.e.
static AffineTransform scale(float factorX, float factorY) noexcept
Returns a new transform which is a re-scale about the origin.
AffineTransform withAbsoluteTranslation(float translationX, float translationY) const noexcept
Returns a copy of this transform with the specified translation matrix values.
float getDeterminant() const noexcept
Returns the determinant of the transform.
static AffineTransform fromTargetPoints(float x00, float y00, float x10, float y10, float x01, float y01) noexcept
Returns the transform that will map three known points onto three coordinates that are supplied.
AffineTransform followedBy(const AffineTransform &other) const noexcept
Returns the result of concatenating another transformation after this one.
bool isOnlyTranslation() const noexcept
Returns true if the transform only translates, and doesn't scale or rotate the points.
AffineTransform()=default
Creates an identity transform.
bool isIdentity() const noexcept
Returns true if this transform has no effect on points.
bool operator!=(const AffineTransform &other) const noexcept
Compares two transforms.
static AffineTransform translation(float deltaX, float deltaY) noexcept
Returns a new transform which is a translation.
bool operator==(const AffineTransform &other) const noexcept
Compares two transforms.
AffineTransform sheared(float shearX, float shearY) const noexcept
Returns a transform which is the same as this one followed by a shear.
static AffineTransform verticalFlip(float height) noexcept
Returns a transform that will flip coordinates vertically within a window of the given height.
AffineTransform inverted() const noexcept
Returns a matrix which is the inverse operation of this one.
AffineTransform translated(float deltaX, float deltaY) const noexcept
Returns a new transform which is the same as this one followed by a translation.
static AffineTransform shear(float shearX, float shearY) noexcept
Returns a shear transform, centred around the origin (0, 0).
static AffineTransform rotation(float angleInRadians) noexcept
Returns a new transform which is a rotation about (0, 0).
T cos(T... args)
typedef float
JUCE Namespace.
constexpr bool approximatelyEqual(Type a, Type b, Tolerance< Type > tolerance=Tolerance< Type >{} .withAbsolute(std::numeric_limits< Type >::min()) .withRelative(std::numeric_limits< Type >::epsilon()))
Returns true if the two floating-point numbers are approximately equal.
constexpr bool exactlyEqual(Type a, Type b)
Equivalent to operator==, but suppresses float-equality warnings.
Type unalignedPointerCast(void *ptr) noexcept
Casts a pointer to another type via void*, which suppresses the cast-align warning which sometimes ar...
Definition juce_Memory.h:88
constexpr FloatType degreesToRadians(FloatType degrees) noexcept
Converts an angle in degrees to radians.
T sin(T... args)
T sqrt(T... args)
T tie(T... args)
T transform(T... args)