diff --git a/modules/juce_graphics/geometry/juce_Parallelogram.h b/modules/juce_graphics/geometry/juce_Parallelogram.h new file mode 100644 index 0000000000..7e7fcd86c8 --- /dev/null +++ b/modules/juce_graphics/geometry/juce_Parallelogram.h @@ -0,0 +1,192 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2017 - ROLI Ltd. + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 5 End-User License + Agreement and JUCE 5 Privacy Policy (both updated and effective as of the + 27th April 2017). + + End User License Agreement: www.juce.com/juce-5-licence + Privacy Policy: www.juce.com/juce-5-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ + +//============================================================================== +/** + Represents a parallelogram that is defined by 3 points. + @see Rectangle, Point, Line +*/ +template +class Parallelogram +{ +public: + //============================================================================== + /** Creates a parallelogram with zero size at the origin. + */ + Parallelogram() noexcept + { + } + + /** Creates a copy of another parallelogram. */ + Parallelogram (const Parallelogram& other) noexcept + : topLeft (other.topLeft), topRight (other.topRight), bottomLeft (other.bottomLeft) + { + } + + /** Creates a parallelogram based on 3 points. */ + Parallelogram (Point topLeftPosition, + Point topRightPosition, + Point bottomLeftPosition) noexcept + : topLeft (topLeftPosition), topRight (topRightPosition), bottomLeft (bottomLeftPosition) + { + } + + /** Creates a parallelogram from a rectangle. */ + Parallelogram (Rectangle rectangle) noexcept + : topLeft (rectangle.getTopLeft()), + topRight (rectangle.getTopRight()), + bottomLeft (rectangle.getBottomLeft()) + { + } + + Parallelogram& operator= (const Parallelogram& other) noexcept + { + topLeft = other.topLeft; + topRight = other.topRight; + bottomLeft = other.bottomLeft; + return *this; + } + + /** Destructor. */ + ~Parallelogram() noexcept {} + + //============================================================================== + /** Returns true if the parallelogram has a width or height of more than zero. */ + bool isEmpty() const noexcept { return topLeft != topRight || topLeft != bottomLeft; } + + /** Returns true if the parallelogram's coordinates are all finite numbers, i.e. not NaN or infinity. */ + inline bool isFinite() const noexcept { return topLeft.isFinite() && topRight.isFinite() && bottomLeft.isFinite(); } + + /** Returns the width of the parallelogram (i.e. the straight-line distance between the top-left and top-right. */ + inline ValueType getWidth() const noexcept { return Line (topLeft, topRight).getLength(); } + + /** Returns the height of the parallelogram (i.e. the straight-line distance between the top-left and bottom-left. */ + inline ValueType getHeight() const noexcept { return Line (topLeft, bottomLeft).getLength(); } + + //============================================================================== + /** Returns the parallelogram's top-left position as a Point. */ + Point getTopLeft() const noexcept { return topLeft; } + + /** Returns the parallelogram's top-right position as a Point. */ + Point getTopRight() const noexcept { return topRight; } + + /** Returns the parallelogram's bottom-left position as a Point. */ + Point getBottomLeft() const noexcept { return bottomLeft; } + + /** Returns the parallelogram's bottom-right position as a Point. */ + Point getBottomRight() const noexcept { return topRight + (bottomLeft - topLeft); } + + //============================================================================== + /** Returns true if the two parallelograms are identical. */ + bool operator== (const Parallelogram& other) const noexcept { return topLeft == other.topLeft && topRight == other.topRight && bottomLeft == other.bottomLeft; } + + /** Returns true if the two parallelograms are not identical. */ + bool operator!= (const Parallelogram& other) const noexcept { return ! operator== (other); } + + //============================================================================== + /** Returns a parallelogram which is the same as this one moved by a given amount. */ + Parallelogram operator+ (Point deltaPosition) const noexcept + { + auto p = *this; + p += deltaPosition; + return p; + } + + /** Moves this parallelogram by a given amount. */ + Parallelogram& operator+= (Point deltaPosition) noexcept + { + topLeft += deltaPosition; + topRight += deltaPosition; + bottomLeft += deltaPosition; + return *this; + } + + /** Returns a parallelogram which is the same as this one moved by a given amount. */ + Parallelogram operator- (Point deltaPosition) const noexcept + { + return operator+ (-deltaPosition); + } + + /** Moves this parallelogram by a given amount. */ + Parallelogram& operator-= (Point deltaPosition) noexcept + { + return operator-= (-deltaPosition); + } + + /** Returns a parallelogram that has been scaled by the given amount, centred around the origin. */ + template + Parallelogram operator* (PointOrScalarType scaleFactor) const noexcept + { + auto p = *this; + p *= scaleFactor; + return p; + } + + /** Scales this parallelogram by the given amount, centred around the origin. */ + template + Parallelogram operator*= (PointOrScalarType scaleFactor) noexcept + { + topLeft *= scaleFactor; + topRight *= scaleFactor; + bottomLeft *= scaleFactor; + return *this; + } + + //============================================================================== + /** Returns a point within this parallelogram, specified as proportional coordinates. + The relative X and Y values should be between 0 and 1, where 0 is the left or + top of this parallelogram, and 1 is the right or bottom. (Out-of-bounds values + will return a point outside the parallelogram). + */ + Point getRelativePoint (Point relativePosition) const noexcept + { + return topLeft + + (topRight - topLeft) * relativePosition.x + + (bottomLeft - topLeft) * relativePosition.y; + } + + /** Returns a transformed verstion of the parallelogram. */ + Parallelogram transformedBy (const AffineTransform& transform) const noexcept + { + auto p = *this; + transform.transformPoints (p.topLeft, p.topRight, p.bottomLeft); + return p; + } + + /** Returns the smallest rectangle that encloses this parallelogram. */ + Rectangle getBoundingBox() const noexcept + { + const Point points[] = { topLeft, topRight, bottomLeft, getBottomRight() }; + return Rectangle::findAreaContainingPoints (points, 4); + } + + Point topLeft, topRight, bottomLeft; +}; + +} // namespace juce diff --git a/modules/juce_graphics/juce_graphics.h b/modules/juce_graphics/juce_graphics.h index 6953c238e7..358500276a 100644 --- a/modules/juce_graphics/juce_graphics.h +++ b/modules/juce_graphics/juce_graphics.h @@ -105,6 +105,7 @@ namespace juce #include "geometry/juce_Point.h" #include "geometry/juce_Line.h" #include "geometry/juce_Rectangle.h" +#include "geometry/juce_Parallelogram.h" #include "placement/juce_Justification.h" #include "geometry/juce_Path.h" #include "geometry/juce_RectangleList.h"