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.

195 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. //==============================================================================
  22. /**
  23. Represents a parallelogram that is defined by 3 points.
  24. @see Rectangle, Point, Line
  25. @tags{Graphics}
  26. */
  27. template <typename ValueType>
  28. class Parallelogram
  29. {
  30. public:
  31. //==============================================================================
  32. /** Creates a parallelogram with zero size at the origin.
  33. */
  34. Parallelogram() noexcept
  35. {
  36. }
  37. /** Creates a copy of another parallelogram. */
  38. Parallelogram (const Parallelogram& other) noexcept
  39. : topLeft (other.topLeft), topRight (other.topRight), bottomLeft (other.bottomLeft)
  40. {
  41. }
  42. /** Creates a parallelogram based on 3 points. */
  43. Parallelogram (Point<ValueType> topLeftPosition,
  44. Point<ValueType> topRightPosition,
  45. Point<ValueType> bottomLeftPosition) noexcept
  46. : topLeft (topLeftPosition), topRight (topRightPosition), bottomLeft (bottomLeftPosition)
  47. {
  48. }
  49. /** Creates a parallelogram from a rectangle. */
  50. Parallelogram (Rectangle<ValueType> rectangle) noexcept
  51. : topLeft (rectangle.getTopLeft()),
  52. topRight (rectangle.getTopRight()),
  53. bottomLeft (rectangle.getBottomLeft())
  54. {
  55. }
  56. Parallelogram& operator= (const Parallelogram& other) noexcept
  57. {
  58. topLeft = other.topLeft;
  59. topRight = other.topRight;
  60. bottomLeft = other.bottomLeft;
  61. return *this;
  62. }
  63. /** Destructor. */
  64. ~Parallelogram() noexcept {}
  65. //==============================================================================
  66. /** Returns true if the parallelogram has a width or height of more than zero. */
  67. bool isEmpty() const noexcept { return topLeft != topRight || topLeft != bottomLeft; }
  68. /** Returns true if the parallelogram's coordinates are all finite numbers, i.e. not NaN or infinity. */
  69. inline bool isFinite() const noexcept { return topLeft.isFinite() && topRight.isFinite() && bottomLeft.isFinite(); }
  70. /** Returns the width of the parallelogram (i.e. the straight-line distance between the top-left and top-right. */
  71. inline ValueType getWidth() const noexcept { return Line<ValueType> (topLeft, topRight).getLength(); }
  72. /** Returns the height of the parallelogram (i.e. the straight-line distance between the top-left and bottom-left. */
  73. inline ValueType getHeight() const noexcept { return Line<ValueType> (topLeft, bottomLeft).getLength(); }
  74. //==============================================================================
  75. /** Returns the parallelogram's top-left position as a Point. */
  76. Point<ValueType> getTopLeft() const noexcept { return topLeft; }
  77. /** Returns the parallelogram's top-right position as a Point. */
  78. Point<ValueType> getTopRight() const noexcept { return topRight; }
  79. /** Returns the parallelogram's bottom-left position as a Point. */
  80. Point<ValueType> getBottomLeft() const noexcept { return bottomLeft; }
  81. /** Returns the parallelogram's bottom-right position as a Point. */
  82. Point<ValueType> getBottomRight() const noexcept { return topRight + (bottomLeft - topLeft); }
  83. //==============================================================================
  84. /** Returns true if the two parallelograms are identical. */
  85. bool operator== (const Parallelogram& other) const noexcept { return topLeft == other.topLeft && topRight == other.topRight && bottomLeft == other.bottomLeft; }
  86. /** Returns true if the two parallelograms are not identical. */
  87. bool operator!= (const Parallelogram& other) const noexcept { return ! operator== (other); }
  88. //==============================================================================
  89. /** Returns a parallelogram which is the same as this one moved by a given amount. */
  90. Parallelogram operator+ (Point<ValueType> deltaPosition) const noexcept
  91. {
  92. auto p = *this;
  93. p += deltaPosition;
  94. return p;
  95. }
  96. /** Moves this parallelogram by a given amount. */
  97. Parallelogram& operator+= (Point<ValueType> deltaPosition) noexcept
  98. {
  99. topLeft += deltaPosition;
  100. topRight += deltaPosition;
  101. bottomLeft += deltaPosition;
  102. return *this;
  103. }
  104. /** Returns a parallelogram which is the same as this one moved by a given amount. */
  105. Parallelogram operator- (Point<ValueType> deltaPosition) const noexcept
  106. {
  107. return operator+ (-deltaPosition);
  108. }
  109. /** Moves this parallelogram by a given amount. */
  110. Parallelogram& operator-= (Point<ValueType> deltaPosition) noexcept
  111. {
  112. return operator-= (-deltaPosition);
  113. }
  114. /** Returns a parallelogram that has been scaled by the given amount, centred around the origin. */
  115. template <typename PointOrScalarType>
  116. Parallelogram operator* (PointOrScalarType scaleFactor) const noexcept
  117. {
  118. auto p = *this;
  119. p *= scaleFactor;
  120. return p;
  121. }
  122. /** Scales this parallelogram by the given amount, centred around the origin. */
  123. template <typename PointOrScalarType>
  124. Parallelogram operator*= (PointOrScalarType scaleFactor) noexcept
  125. {
  126. topLeft *= scaleFactor;
  127. topRight *= scaleFactor;
  128. bottomLeft *= scaleFactor;
  129. return *this;
  130. }
  131. //==============================================================================
  132. /** Returns a point within this parallelogram, specified as proportional coordinates.
  133. The relative X and Y values should be between 0 and 1, where 0 is the left or
  134. top of this parallelogram, and 1 is the right or bottom. (Out-of-bounds values
  135. will return a point outside the parallelogram).
  136. */
  137. Point<ValueType> getRelativePoint (Point<ValueType> relativePosition) const noexcept
  138. {
  139. return topLeft
  140. + (topRight - topLeft) * relativePosition.x
  141. + (bottomLeft - topLeft) * relativePosition.y;
  142. }
  143. /** Returns a transformed verstion of the parallelogram. */
  144. Parallelogram transformedBy (const AffineTransform& transform) const noexcept
  145. {
  146. auto p = *this;
  147. transform.transformPoints (p.topLeft, p.topRight, p.bottomLeft);
  148. return p;
  149. }
  150. /** Returns the smallest rectangle that encloses this parallelogram. */
  151. Rectangle<ValueType> getBoundingBox() const noexcept
  152. {
  153. const Point<ValueType> points[] = { topLeft, topRight, bottomLeft, getBottomRight() };
  154. return Rectangle<ValueType>::findAreaContainingPoints (points, 4);
  155. }
  156. Point<ValueType> topLeft, topRight, bottomLeft;
  157. };
  158. } // namespace juce