Audio plugin host https://kx.studio/carla
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.

186 lines
7.5KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2022 - Raw Material Software Limited
  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 7 End-User License
  8. Agreement and JUCE Privacy Policy.
  9. End User License Agreement: www.juce.com/juce-7-licence
  10. Privacy Policy: www.juce.com/juce-privacy-policy
  11. Or: You may also use this code under the terms of the GPL v3 (see
  12. www.gnu.org/licenses).
  13. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  14. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  15. DISCLAIMED.
  16. ==============================================================================
  17. */
  18. namespace juce
  19. {
  20. //==============================================================================
  21. /**
  22. Represents a parallelogram that is defined by 3 points.
  23. @see Rectangle, Point, Line
  24. @tags{Graphics}
  25. */
  26. template <typename ValueType>
  27. class Parallelogram
  28. {
  29. public:
  30. //==============================================================================
  31. /** Creates a parallelogram with zero size at the origin.
  32. */
  33. Parallelogram() = default;
  34. /** Creates a copy of another parallelogram. */
  35. Parallelogram (const Parallelogram&) = default;
  36. /** Creates a parallelogram based on 3 points. */
  37. Parallelogram (Point<ValueType> topLeftPosition,
  38. Point<ValueType> topRightPosition,
  39. Point<ValueType> bottomLeftPosition) noexcept
  40. : topLeft (topLeftPosition), topRight (topRightPosition), bottomLeft (bottomLeftPosition)
  41. {
  42. }
  43. /** Creates a parallelogram from a rectangle. */
  44. Parallelogram (Rectangle<ValueType> rectangle) noexcept
  45. : topLeft (rectangle.getTopLeft()),
  46. topRight (rectangle.getTopRight()),
  47. bottomLeft (rectangle.getBottomLeft())
  48. {
  49. }
  50. Parallelogram& operator= (const Parallelogram&) = default;
  51. /** Destructor. */
  52. ~Parallelogram() = default;
  53. //==============================================================================
  54. /** Returns true if the parallelogram has a width or height of more than zero. */
  55. bool isEmpty() const noexcept { return topLeft != topRight || topLeft != bottomLeft; }
  56. /** Returns true if the parallelogram's coordinates are all finite numbers, i.e. not NaN or infinity. */
  57. inline bool isFinite() const noexcept { return topLeft.isFinite() && topRight.isFinite() && bottomLeft.isFinite(); }
  58. /** Returns the width of the parallelogram (i.e. the straight-line distance between the top-left and top-right. */
  59. inline ValueType getWidth() const noexcept { return Line<ValueType> (topLeft, topRight).getLength(); }
  60. /** Returns the height of the parallelogram (i.e. the straight-line distance between the top-left and bottom-left. */
  61. inline ValueType getHeight() const noexcept { return Line<ValueType> (topLeft, bottomLeft).getLength(); }
  62. //==============================================================================
  63. /** Returns the parallelogram's top-left position as a Point. */
  64. Point<ValueType> getTopLeft() const noexcept { return topLeft; }
  65. /** Returns the parallelogram's top-right position as a Point. */
  66. Point<ValueType> getTopRight() const noexcept { return topRight; }
  67. /** Returns the parallelogram's bottom-left position as a Point. */
  68. Point<ValueType> getBottomLeft() const noexcept { return bottomLeft; }
  69. /** Returns the parallelogram's bottom-right position as a Point. */
  70. Point<ValueType> getBottomRight() const noexcept { return topRight + (bottomLeft - topLeft); }
  71. //==============================================================================
  72. /** Returns true if the two parallelograms are identical. */
  73. bool operator== (const Parallelogram& other) const noexcept { return topLeft == other.topLeft && topRight == other.topRight && bottomLeft == other.bottomLeft; }
  74. /** Returns true if the two parallelograms are not identical. */
  75. bool operator!= (const Parallelogram& other) const noexcept { return ! operator== (other); }
  76. //==============================================================================
  77. /** Returns a parallelogram which is the same as this one moved by a given amount. */
  78. Parallelogram operator+ (Point<ValueType> deltaPosition) const noexcept
  79. {
  80. auto p = *this;
  81. p += deltaPosition;
  82. return p;
  83. }
  84. /** Moves this parallelogram by a given amount. */
  85. Parallelogram& operator+= (Point<ValueType> deltaPosition) noexcept
  86. {
  87. topLeft += deltaPosition;
  88. topRight += deltaPosition;
  89. bottomLeft += deltaPosition;
  90. return *this;
  91. }
  92. /** Returns a parallelogram which is the same as this one moved by a given amount. */
  93. Parallelogram operator- (Point<ValueType> deltaPosition) const noexcept
  94. {
  95. return operator+ (-deltaPosition);
  96. }
  97. /** Moves this parallelogram by a given amount. */
  98. Parallelogram& operator-= (Point<ValueType> deltaPosition) noexcept
  99. {
  100. return operator-= (-deltaPosition);
  101. }
  102. /** Returns a parallelogram that has been scaled by the given amount, centred around the origin. */
  103. template <typename PointOrScalarType>
  104. Parallelogram operator* (PointOrScalarType scaleFactor) const noexcept
  105. {
  106. auto p = *this;
  107. p *= scaleFactor;
  108. return p;
  109. }
  110. /** Scales this parallelogram by the given amount, centred around the origin. */
  111. template <typename PointOrScalarType>
  112. Parallelogram operator*= (PointOrScalarType scaleFactor) noexcept
  113. {
  114. topLeft *= scaleFactor;
  115. topRight *= scaleFactor;
  116. bottomLeft *= scaleFactor;
  117. return *this;
  118. }
  119. //==============================================================================
  120. /** Returns a point within this parallelogram, specified as proportional coordinates.
  121. The relative X and Y values should be between 0 and 1, where 0 is the left or
  122. top of this parallelogram, and 1 is the right or bottom. (Out-of-bounds values
  123. will return a point outside the parallelogram).
  124. */
  125. Point<ValueType> getRelativePoint (Point<ValueType> relativePosition) const noexcept
  126. {
  127. return topLeft
  128. + (topRight - topLeft) * relativePosition.x
  129. + (bottomLeft - topLeft) * relativePosition.y;
  130. }
  131. /** Returns a transformed version of the parallelogram. */
  132. Parallelogram transformedBy (const AffineTransform& transform) const noexcept
  133. {
  134. auto p = *this;
  135. transform.transformPoints (p.topLeft.x, p.topLeft.y,
  136. p.topRight.x, p.topRight.y,
  137. p.bottomLeft.x, p.bottomLeft.y);
  138. return p;
  139. }
  140. /** Returns the smallest rectangle that encloses this parallelogram. */
  141. Rectangle<ValueType> getBoundingBox() const noexcept
  142. {
  143. const Point<ValueType> points[] = { topLeft, topRight, bottomLeft, getBottomRight() };
  144. return Rectangle<ValueType>::findAreaContainingPoints (points, 4);
  145. }
  146. Point<ValueType> topLeft, topRight, bottomLeft;
  147. };
  148. } // namespace juce