The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

245 lines
7.7KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2017 - ROLI Ltd.
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. By using JUCE, you agree to the terms of both the JUCE 5 End-User License
  8. Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
  9. 27th April 2017).
  10. End User License Agreement: www.juce.com/juce-5-licence
  11. Privacy Policy: www.juce.com/juce-5-privacy-policy
  12. Or: You may also use this code under the terms of the GPL v3 (see
  13. www.gnu.org/licenses).
  14. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  15. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  16. DISCLAIMED.
  17. ==============================================================================
  18. */
  19. namespace juce
  20. {
  21. AffineTransform::AffineTransform (float m00, float m01, float m02,
  22. float m10, float m11, float m12) noexcept
  23. : mat00 (m00), mat01 (m01), mat02 (m02),
  24. mat10 (m10), mat11 (m11), mat12 (m12)
  25. {
  26. }
  27. bool AffineTransform::operator== (const AffineTransform& other) const noexcept
  28. {
  29. return mat00 == other.mat00
  30. && mat01 == other.mat01
  31. && mat02 == other.mat02
  32. && mat10 == other.mat10
  33. && mat11 == other.mat11
  34. && mat12 == other.mat12;
  35. }
  36. bool AffineTransform::operator!= (const AffineTransform& other) const noexcept
  37. {
  38. return ! operator== (other);
  39. }
  40. //==============================================================================
  41. bool AffineTransform::isIdentity() const noexcept
  42. {
  43. return mat01 == 0.0f
  44. && mat02 == 0.0f
  45. && mat10 == 0.0f
  46. && mat12 == 0.0f
  47. && mat00 == 1.0f
  48. && mat11 == 1.0f;
  49. }
  50. JUCE_DECLARE_DEPRECATED_STATIC (const AffineTransform AffineTransform::identity;)
  51. //==============================================================================
  52. AffineTransform AffineTransform::followedBy (const AffineTransform& other) const noexcept
  53. {
  54. return { other.mat00 * mat00 + other.mat01 * mat10,
  55. other.mat00 * mat01 + other.mat01 * mat11,
  56. other.mat00 * mat02 + other.mat01 * mat12 + other.mat02,
  57. other.mat10 * mat00 + other.mat11 * mat10,
  58. other.mat10 * mat01 + other.mat11 * mat11,
  59. other.mat10 * mat02 + other.mat11 * mat12 + other.mat12 };
  60. }
  61. AffineTransform AffineTransform::translated (float dx, float dy) const noexcept
  62. {
  63. return { mat00, mat01, mat02 + dx,
  64. mat10, mat11, mat12 + dy };
  65. }
  66. AffineTransform AffineTransform::translation (float dx, float dy) noexcept
  67. {
  68. return { 1.0f, 0.0f, dx,
  69. 0.0f, 1.0f, dy };
  70. }
  71. AffineTransform AffineTransform::withAbsoluteTranslation (float tx, float ty) const noexcept
  72. {
  73. return { mat00, mat01, tx,
  74. mat10, mat11, ty };
  75. }
  76. AffineTransform AffineTransform::rotated (float rad) const noexcept
  77. {
  78. auto cosRad = std::cos (rad);
  79. auto sinRad = std::sin (rad);
  80. return { cosRad * mat00 - sinRad * mat10,
  81. cosRad * mat01 - sinRad * mat11,
  82. cosRad * mat02 - sinRad * mat12,
  83. sinRad * mat00 + cosRad * mat10,
  84. sinRad * mat01 + cosRad * mat11,
  85. sinRad * mat02 + cosRad * mat12 };
  86. }
  87. AffineTransform AffineTransform::rotation (float rad) noexcept
  88. {
  89. auto cosRad = std::cos (rad);
  90. auto sinRad = std::sin (rad);
  91. return { cosRad, -sinRad, 0,
  92. sinRad, cosRad, 0 };
  93. }
  94. AffineTransform AffineTransform::rotation (float rad, float pivotX, float pivotY) noexcept
  95. {
  96. auto cosRad = std::cos (rad);
  97. auto sinRad = std::sin (rad);
  98. return { cosRad, -sinRad, -cosRad * pivotX + sinRad * pivotY + pivotX,
  99. sinRad, cosRad, -sinRad * pivotX + -cosRad * pivotY + pivotY };
  100. }
  101. AffineTransform AffineTransform::rotated (float angle, float pivotX, float pivotY) const noexcept
  102. {
  103. return followedBy (rotation (angle, pivotX, pivotY));
  104. }
  105. AffineTransform AffineTransform::scaled (float factorX, float factorY) const noexcept
  106. {
  107. return { factorX * mat00, factorX * mat01, factorX * mat02,
  108. factorY * mat10, factorY * mat11, factorY * mat12 };
  109. }
  110. AffineTransform AffineTransform::scaled (float factor) const noexcept
  111. {
  112. return { factor * mat00, factor * mat01, factor * mat02,
  113. factor * mat10, factor * mat11, factor * mat12 };
  114. }
  115. AffineTransform AffineTransform::scale (float factorX, float factorY) noexcept
  116. {
  117. return { factorX, 0, 0, 0, factorY, 0 };
  118. }
  119. AffineTransform AffineTransform::scale (float factor) noexcept
  120. {
  121. return { factor, 0, 0, 0, factor, 0 };
  122. }
  123. AffineTransform AffineTransform::scaled (float factorX, float factorY,
  124. float pivotX, float pivotY) const noexcept
  125. {
  126. return { factorX * mat00, factorX * mat01, factorX * mat02 + pivotX * (1.0f - factorX),
  127. factorY * mat10, factorY * mat11, factorY * mat12 + pivotY * (1.0f - factorY) };
  128. }
  129. AffineTransform AffineTransform::scale (float factorX, float factorY,
  130. float pivotX, float pivotY) noexcept
  131. {
  132. return { factorX, 0, pivotX * (1.0f - factorX),
  133. 0, factorY, pivotY * (1.0f - factorY) };
  134. }
  135. AffineTransform AffineTransform::shear (float shearX, float shearY) noexcept
  136. {
  137. return { 1.0f, shearX, 0,
  138. shearY, 1.0f, 0 };
  139. }
  140. AffineTransform AffineTransform::sheared (float shearX, float shearY) const noexcept
  141. {
  142. return { mat00 + shearX * mat10,
  143. mat01 + shearX * mat11,
  144. mat02 + shearX * mat12,
  145. mat10 + shearY * mat00,
  146. mat11 + shearY * mat01,
  147. mat12 + shearY * mat02 };
  148. }
  149. AffineTransform AffineTransform::verticalFlip (float height) noexcept
  150. {
  151. return { 1.0f, 0.0f, 0.0f,
  152. 0.0f, -1.0f, height };
  153. }
  154. AffineTransform AffineTransform::inverted() const noexcept
  155. {
  156. double determinant = (mat00 * mat11 - mat10 * mat01);
  157. if (determinant != 0)
  158. {
  159. determinant = 1.0 / determinant;
  160. auto dst00 = (float) ( mat11 * determinant);
  161. auto dst10 = (float) (-mat10 * determinant);
  162. auto dst01 = (float) (-mat01 * determinant);
  163. auto dst11 = (float) ( mat00 * determinant);
  164. return { dst00, dst01, -mat02 * dst00 - mat12 * dst01,
  165. dst10, dst11, -mat02 * dst10 - mat12 * dst11 };
  166. }
  167. // singularity..
  168. return *this;
  169. }
  170. bool AffineTransform::isSingularity() const noexcept
  171. {
  172. return (mat00 * mat11 - mat10 * mat01) == 0.0f;
  173. }
  174. AffineTransform AffineTransform::fromTargetPoints (float x00, float y00,
  175. float x10, float y10,
  176. float x01, float y01) noexcept
  177. {
  178. return { x10 - x00, x01 - x00, x00,
  179. y10 - y00, y01 - y00, y00 };
  180. }
  181. AffineTransform AffineTransform::fromTargetPoints (float sx1, float sy1, float tx1, float ty1,
  182. float sx2, float sy2, float tx2, float ty2,
  183. float sx3, float sy3, float tx3, float ty3) noexcept
  184. {
  185. return fromTargetPoints (sx1, sy1, sx2, sy2, sx3, sy3)
  186. .inverted()
  187. .followedBy (fromTargetPoints (tx1, ty1, tx2, ty2, tx3, ty3));
  188. }
  189. bool AffineTransform::isOnlyTranslation() const noexcept
  190. {
  191. return mat01 == 0.0f
  192. && mat10 == 0.0f
  193. && mat00 == 1.0f
  194. && mat11 == 1.0f;
  195. }
  196. float AffineTransform::getScaleFactor() const noexcept
  197. {
  198. return (std::abs (mat00) + std::abs (mat11)) / 2.0f;
  199. }
  200. } // namespace juce