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.

186 lines
9.4KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-11 by Raw Material Software Ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the GNU General
  7. Public License (Version 2), as published by the Free Software Foundation.
  8. A copy of the license is included in the JUCE distribution, or can be found
  9. online at www.gnu.org/licenses.
  10. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  13. ------------------------------------------------------------------------------
  14. To release a closed-source product which uses JUCE, commercial licenses are
  15. available: visit www.rawmaterialsoftware.com/juce for more information.
  16. ==============================================================================
  17. */
  18. #ifndef __JUCE_POINT_JUCEHEADER__
  19. #define __JUCE_POINT_JUCEHEADER__
  20. #include "juce_AffineTransform.h"
  21. //==============================================================================
  22. /**
  23. A pair of (x, y) co-ordinates.
  24. The ValueType template should be a primitive type such as int, float, double,
  25. rather than a class.
  26. @see Line, Path, AffineTransform
  27. */
  28. template <typename ValueType>
  29. class Point
  30. {
  31. public:
  32. //==============================================================================
  33. /** Creates a point with co-ordinates (0, 0). */
  34. Point() noexcept : x(), y() {}
  35. /** Creates a copy of another point. */
  36. Point (const Point& other) noexcept : x (other.x), y (other.y) {}
  37. /** Creates a point from an (x, y) position. */
  38. Point (const ValueType initialX, const ValueType initialY) noexcept : x (initialX), y (initialY) {}
  39. /** Destructor. */
  40. ~Point() noexcept {}
  41. //==============================================================================
  42. /** Copies this point from another one. */
  43. Point& operator= (const Point& other) noexcept { x = other.x; y = other.y; return *this; }
  44. inline bool operator== (const Point& other) const noexcept { return x == other.x && y == other.y; }
  45. inline bool operator!= (const Point& other) const noexcept { return x != other.x || y != other.y; }
  46. /** Returns true if the point is (0, 0). */
  47. bool isOrigin() const noexcept { return x == ValueType() && y == ValueType(); }
  48. /** Returns the point's x co-ordinate. */
  49. inline ValueType getX() const noexcept { return x; }
  50. /** Returns the point's y co-ordinate. */
  51. inline ValueType getY() const noexcept { return y; }
  52. /** Sets the point's x co-ordinate. */
  53. inline void setX (const ValueType newX) noexcept { x = newX; }
  54. /** Sets the point's y co-ordinate. */
  55. inline void setY (const ValueType newY) noexcept { y = newY; }
  56. /** Returns a point which has the same Y position as this one, but a new X. */
  57. Point withX (const ValueType newX) const noexcept { return Point (newX, y); }
  58. /** Returns a point which has the same X position as this one, but a new Y. */
  59. Point withY (const ValueType newY) const noexcept { return Point (x, newY); }
  60. /** Changes the point's x and y co-ordinates. */
  61. void setXY (const ValueType newX, const ValueType newY) noexcept { x = newX; y = newY; }
  62. /** Adds a pair of co-ordinates to this value. */
  63. void addXY (const ValueType xToAdd, const ValueType yToAdd) noexcept { x += xToAdd; y += yToAdd; }
  64. /** Returns a point with a given offset from this one. */
  65. Point translated (const ValueType xDelta, const ValueType yDelta) const noexcept { return Point (x + xDelta, y + yDelta); }
  66. /** Adds two points together. */
  67. Point operator+ (const Point& other) const noexcept { return Point (x + other.x, y + other.y); }
  68. /** Adds another point's co-ordinates to this one. */
  69. Point& operator+= (const Point& other) noexcept { x += other.x; y += other.y; return *this; }
  70. /** Subtracts one points from another. */
  71. Point operator- (const Point& other) const noexcept { return Point (x - other.x, y - other.y); }
  72. /** Subtracts another point's co-ordinates to this one. */
  73. Point& operator-= (const Point& other) noexcept { x -= other.x; y -= other.y; return *this; }
  74. /** Returns a point whose coordinates are multiplied by a given value. */
  75. Point operator* (const ValueType multiplier) const noexcept { return Point (x * multiplier, y * multiplier); }
  76. /** Multiplies the point's co-ordinates by a value. */
  77. Point& operator*= (const ValueType multiplier) noexcept { x *= multiplier; y *= multiplier; return *this; }
  78. /** Returns a point whose coordinates are divided by a given value. */
  79. Point operator/ (const ValueType divisor) const noexcept { return Point (x / divisor, y / divisor); }
  80. /** Divides the point's co-ordinates by a value. */
  81. Point& operator/= (const ValueType divisor) noexcept { x /= divisor; y /= divisor; return *this; }
  82. /** Returns the inverse of this point. */
  83. Point operator-() const noexcept { return Point (-x, -y); }
  84. /** Returns the straight-line distance between this point and the origin. */
  85. ValueType getDistanceFromOrigin() const noexcept { return juce_hypot (x, y); }
  86. /** Returns the straight-line distance between this point and another one. */
  87. ValueType getDistanceFrom (const Point& other) const noexcept { return juce_hypot (x - other.x, y - other.y); }
  88. /** This type will be double if the Point's type is double, otherwise it will be float. */
  89. typedef typename TypeHelpers::SmallestFloatType<ValueType>::type FloatType;
  90. /** Returns the angle from this point to another one.
  91. The return value is the number of radians clockwise from the 12 o'clock direction,
  92. where this point is the centre and the other point is on the circumference.
  93. */
  94. FloatType getAngleToPoint (const Point& other) const noexcept
  95. { return static_cast<FloatType> (std::atan2 (other.x - x, y - other.y)); }
  96. /** Taking this point to be the centre of a circle, this returns a point on its circumference.
  97. @param radius the radius of the circle.
  98. @param angle the angle of the point, in radians clockwise from the 12 o'clock position.
  99. */
  100. Point<FloatType> getPointOnCircumference (const float radius, const float angle) const noexcept
  101. { return Point<FloatType> (static_cast <FloatType> (x + radius * std::sin (angle)),
  102. static_cast <FloatType> (y - radius * std::cos (angle))); }
  103. /** Taking this point to be the centre of an ellipse, this returns a point on its circumference.
  104. @param radiusX the horizontal radius of the circle.
  105. @param radiusY the vertical radius of the circle.
  106. @param angle the angle of the point, in radians clockwise from the 12 o'clock position.
  107. */
  108. Point<FloatType> getPointOnCircumference (const float radiusX, const float radiusY, const float angle) const noexcept
  109. { return Point<FloatType> (static_cast <FloatType> (x + radiusX * std::sin (angle)),
  110. static_cast <FloatType> (y - radiusY * std::cos (angle))); }
  111. /** Uses a transform to change the point's co-ordinates.
  112. This will only compile if ValueType = float!
  113. @see AffineTransform::transformPoint
  114. */
  115. void applyTransform (const AffineTransform& transform) noexcept { transform.transformPoint (x, y); }
  116. /** Returns the position of this point, if it is transformed by a given AffineTransform. */
  117. Point transformedBy (const AffineTransform& transform) const noexcept
  118. { return Point (transform.mat00 * x + transform.mat01 * y + transform.mat02,
  119. transform.mat10 * x + transform.mat11 * y + transform.mat12); }
  120. /** Casts this point to a Point<int> object. */
  121. Point<int> toInt() const noexcept { return Point<int> (static_cast <int> (x), static_cast<int> (y)); }
  122. /** Casts this point to a Point<float> object. */
  123. Point<float> toFloat() const noexcept { return Point<float> (static_cast <float> (x), static_cast<float> (y)); }
  124. /** Casts this point to a Point<double> object. */
  125. Point<double> toDouble() const noexcept { return Point<double> (static_cast <double> (x), static_cast<double> (y)); }
  126. /** Returns the point as a string in the form "x, y". */
  127. String toString() const { return String (x) + ", " + String (y); }
  128. //==============================================================================
  129. ValueType x; /**< The point's X coordinate. */
  130. ValueType y; /**< The point's Y coordinate. */
  131. };
  132. #endif // __JUCE_POINT_JUCEHEADER__