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.

271 lines
8.3KB

  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() noexcept
  22. : mat00 (1.0f), mat01 (0), mat02 (0),
  23. mat10 (0), mat11 (1.0f), mat12 (0)
  24. {
  25. }
  26. AffineTransform::AffineTransform (const AffineTransform& other) noexcept
  27. : mat00 (other.mat00), mat01 (other.mat01), mat02 (other.mat02),
  28. mat10 (other.mat10), mat11 (other.mat11), mat12 (other.mat12)
  29. {
  30. }
  31. AffineTransform::AffineTransform (float m00, float m01, float m02,
  32. float m10, float m11, float m12) noexcept
  33. : mat00 (m00), mat01 (m01), mat02 (m02),
  34. mat10 (m10), mat11 (m11), mat12 (m12)
  35. {
  36. }
  37. AffineTransform& AffineTransform::operator= (const AffineTransform& other) noexcept
  38. {
  39. mat00 = other.mat00;
  40. mat01 = other.mat01;
  41. mat02 = other.mat02;
  42. mat10 = other.mat10;
  43. mat11 = other.mat11;
  44. mat12 = other.mat12;
  45. return *this;
  46. }
  47. bool AffineTransform::operator== (const AffineTransform& other) const noexcept
  48. {
  49. return mat00 == other.mat00
  50. && mat01 == other.mat01
  51. && mat02 == other.mat02
  52. && mat10 == other.mat10
  53. && mat11 == other.mat11
  54. && mat12 == other.mat12;
  55. }
  56. bool AffineTransform::operator!= (const AffineTransform& other) const noexcept
  57. {
  58. return ! operator== (other);
  59. }
  60. //==============================================================================
  61. bool AffineTransform::isIdentity() const noexcept
  62. {
  63. return mat01 == 0.0f
  64. && mat02 == 0.0f
  65. && mat10 == 0.0f
  66. && mat12 == 0.0f
  67. && mat00 == 1.0f
  68. && mat11 == 1.0f;
  69. }
  70. #if JUCE_ALLOW_STATIC_NULL_VARIABLES
  71. const AffineTransform AffineTransform::identity;
  72. #endif
  73. //==============================================================================
  74. AffineTransform AffineTransform::followedBy (const AffineTransform& other) const noexcept
  75. {
  76. return { other.mat00 * mat00 + other.mat01 * mat10,
  77. other.mat00 * mat01 + other.mat01 * mat11,
  78. other.mat00 * mat02 + other.mat01 * mat12 + other.mat02,
  79. other.mat10 * mat00 + other.mat11 * mat10,
  80. other.mat10 * mat01 + other.mat11 * mat11,
  81. other.mat10 * mat02 + other.mat11 * mat12 + other.mat12 };
  82. }
  83. AffineTransform AffineTransform::translated (float dx, float dy) const noexcept
  84. {
  85. return { mat00, mat01, mat02 + dx,
  86. mat10, mat11, mat12 + dy };
  87. }
  88. AffineTransform AffineTransform::translation (float dx, float dy) noexcept
  89. {
  90. return { 1.0f, 0.0f, dx,
  91. 0.0f, 1.0f, dy };
  92. }
  93. AffineTransform AffineTransform::withAbsoluteTranslation (float tx, float ty) const noexcept
  94. {
  95. return { mat00, mat01, tx,
  96. mat10, mat11, ty };
  97. }
  98. AffineTransform AffineTransform::rotated (float rad) const noexcept
  99. {
  100. auto cosRad = std::cos (rad);
  101. auto sinRad = std::sin (rad);
  102. return { cosRad * mat00 - sinRad * mat10,
  103. cosRad * mat01 - sinRad * mat11,
  104. cosRad * mat02 - sinRad * mat12,
  105. sinRad * mat00 + cosRad * mat10,
  106. sinRad * mat01 + cosRad * mat11,
  107. sinRad * mat02 + cosRad * mat12 };
  108. }
  109. AffineTransform AffineTransform::rotation (float rad) noexcept
  110. {
  111. auto cosRad = std::cos (rad);
  112. auto sinRad = std::sin (rad);
  113. return { cosRad, -sinRad, 0,
  114. sinRad, cosRad, 0 };
  115. }
  116. AffineTransform AffineTransform::rotation (float rad, float pivotX, float pivotY) noexcept
  117. {
  118. auto cosRad = std::cos (rad);
  119. auto sinRad = std::sin (rad);
  120. return { cosRad, -sinRad, -cosRad * pivotX + sinRad * pivotY + pivotX,
  121. sinRad, cosRad, -sinRad * pivotX + -cosRad * pivotY + pivotY };
  122. }
  123. AffineTransform AffineTransform::rotated (float angle, float pivotX, float pivotY) const noexcept
  124. {
  125. return followedBy (rotation (angle, pivotX, pivotY));
  126. }
  127. AffineTransform AffineTransform::scaled (float factorX, float factorY) const noexcept
  128. {
  129. return { factorX * mat00, factorX * mat01, factorX * mat02,
  130. factorY * mat10, factorY * mat11, factorY * mat12 };
  131. }
  132. AffineTransform AffineTransform::scaled (float factor) const noexcept
  133. {
  134. return { factor * mat00, factor * mat01, factor * mat02,
  135. factor * mat10, factor * mat11, factor * mat12 };
  136. }
  137. AffineTransform AffineTransform::scale (float factorX, float factorY) noexcept
  138. {
  139. return { factorX, 0, 0, 0, factorY, 0 };
  140. }
  141. AffineTransform AffineTransform::scale (float factor) noexcept
  142. {
  143. return { factor, 0, 0, 0, factor, 0 };
  144. }
  145. AffineTransform AffineTransform::scaled (float factorX, float factorY,
  146. float pivotX, float pivotY) const noexcept
  147. {
  148. return { factorX * mat00, factorX * mat01, factorX * mat02 + pivotX * (1.0f - factorX),
  149. factorY * mat10, factorY * mat11, factorY * mat12 + pivotY * (1.0f - factorY) };
  150. }
  151. AffineTransform AffineTransform::scale (float factorX, float factorY,
  152. float pivotX, float pivotY) noexcept
  153. {
  154. return { factorX, 0, pivotX * (1.0f - factorX),
  155. 0, factorY, pivotY * (1.0f - factorY) };
  156. }
  157. AffineTransform AffineTransform::shear (float shearX, float shearY) noexcept
  158. {
  159. return { 1.0f, shearX, 0,
  160. shearY, 1.0f, 0 };
  161. }
  162. AffineTransform AffineTransform::sheared (float shearX, float shearY) const noexcept
  163. {
  164. return { mat00 + shearX * mat10,
  165. mat01 + shearX * mat11,
  166. mat02 + shearX * mat12,
  167. mat10 + shearY * mat00,
  168. mat11 + shearY * mat01,
  169. mat12 + shearY * mat02 };
  170. }
  171. AffineTransform AffineTransform::verticalFlip (float height) noexcept
  172. {
  173. return { 1.0f, 0.0f, 0.0f,
  174. 0.0f, -1.0f, height };
  175. }
  176. AffineTransform AffineTransform::inverted() const noexcept
  177. {
  178. double determinant = (mat00 * mat11 - mat10 * mat01);
  179. if (determinant != 0)
  180. {
  181. determinant = 1.0 / determinant;
  182. auto dst00 = (float) ( mat11 * determinant);
  183. auto dst10 = (float) (-mat10 * determinant);
  184. auto dst01 = (float) (-mat01 * determinant);
  185. auto dst11 = (float) ( mat00 * determinant);
  186. return { dst00, dst01, -mat02 * dst00 - mat12 * dst01,
  187. dst10, dst11, -mat02 * dst10 - mat12 * dst11 };
  188. }
  189. // singularity..
  190. return *this;
  191. }
  192. bool AffineTransform::isSingularity() const noexcept
  193. {
  194. return (mat00 * mat11 - mat10 * mat01) == 0.0f;
  195. }
  196. AffineTransform AffineTransform::fromTargetPoints (float x00, float y00,
  197. float x10, float y10,
  198. float x01, float y01) noexcept
  199. {
  200. return { x10 - x00, x01 - x00, x00,
  201. y10 - y00, y01 - y00, y00 };
  202. }
  203. AffineTransform AffineTransform::fromTargetPoints (float sx1, float sy1, float tx1, float ty1,
  204. float sx2, float sy2, float tx2, float ty2,
  205. float sx3, float sy3, float tx3, float ty3) noexcept
  206. {
  207. return fromTargetPoints (sx1, sy1, sx2, sy2, sx3, sy3)
  208. .inverted()
  209. .followedBy (fromTargetPoints (tx1, ty1, tx2, ty2, tx3, ty3));
  210. }
  211. bool AffineTransform::isOnlyTranslation() const noexcept
  212. {
  213. return mat01 == 0.0f
  214. && mat10 == 0.0f
  215. && mat00 == 1.0f
  216. && mat11 == 1.0f;
  217. }
  218. float AffineTransform::getScaleFactor() const noexcept
  219. {
  220. return (std::abs (mat00) + std::abs (mat11)) / 2.0f;
  221. }
  222. } // namespace juce