45template <
typename ValueType>
57 Line (ValueType startX, ValueType startY, ValueType endX, ValueType endY) noexcept
58 : start (startX, startY), end (endX, endY)
64 : start (startPoint), end (endPoint)
76 inline ValueType
getStartX() const noexcept {
return start.x; }
79 inline ValueType
getStartY() const noexcept {
return start.y; }
82 inline ValueType
getEndX() const noexcept {
return end.x; }
85 inline ValueType
getEndY() const noexcept {
return end.y; }
94 void setStart (ValueType newStartX, ValueType newStartY)
noexcept { start.setXY (newStartX, newStartY); }
97 void setEnd (ValueType newEndX, ValueType newEndY)
noexcept { end.setXY (newEndX, newEndY); }
111 start.applyTransform (transform);
112 end.applyTransform (transform);
117 ValueType
getLength() const noexcept {
return start.getDistanceFrom (end); }
123 bool isVertical() const noexcept {
return start.x == end.x; }
142 return { startPoint, startPoint.getPointOnCircumference (length, angle) };
154 bool operator== (
Line other)
const noexcept {
return start == other.start && end == other.end; }
157 bool operator!= (
Line other)
const noexcept {
return start != other.start || end != other.end; }
168 findIntersection (start, end, line.start, line.end, p);
186 return findIntersection (start, end, line.start, line.end, intersection);
193 return findIntersection (start, end, other.start, other.end, ignored);
207 return approximatelyEqual (length, (ValueType) 0) ? start : start + (end - start) * (distanceFromStart / length);
224 ValueType perpendicularDistance)
const noexcept
226 auto delta = end - start;
232 return { start.x +
static_cast<ValueType
> ((delta.x * distanceFromStart - delta.y * perpendicularDistance) / length),
233 start.y +
static_cast<ValueType
> ((delta.y * distanceFromStart + delta.x * perpendicularDistance) / length) };
248 return start + (end - start) * proportionOfLength;
265 auto delta = end - start;
266 auto length = delta.x * delta.x + delta.y * delta.y;
270 auto prop = ((targetPoint.x - start.x) * delta.x
271 + (targetPoint.y - start.y) * delta.y) / (
double) length;
273 if (prop >= 0 && prop <= 1.0)
275 pointOnLine = start + delta * prop;
276 return targetPoint.getDistanceFrom (pointOnLine);
280 auto fromStart = targetPoint.getDistanceFrom (start);
281 auto fromEnd = targetPoint.getDistanceFrom (end);
283 if (fromStart < fromEnd)
303 auto delta = end - start;
304 auto length = delta.x * delta.x + delta.y * delta.y;
306 return length <= 0 ? 0
307 :
jlimit (ValueType(),
static_cast<ValueType
> (1),
308 static_cast<ValueType
> ((((point.x - start.x) * delta.x
309 + (point.y - start.y) * delta.y) / length)));
328 return start.x != end.x
329 && point.y < ((end.y - start.y) * (point.x - start.x)) / (end.x - start.x) + start.y;
378 static bool isZeroToOne (ValueType v)
noexcept {
return v >= 0 && v <= static_cast<ValueType> (1); }
380 static bool findIntersection (
const Point<ValueType> p1,
const Point<ValueType> p2,
381 const Point<ValueType> p3,
const Point<ValueType> p4,
382 Point<ValueType>& intersection)
noexcept
392 auto divisor = d1.x * d2.y - d2.x * d1.y;
394 const auto zero = ValueType{};
398 if (! (d1.isOrigin() || d2.isOrigin()))
402 auto along = (p1.y - p3.y) / d2.y;
403 intersection = p1.withX (p3.x + along * d2.x);
404 return isZeroToOne (along);
409 auto along = (p3.y - p1.y) / d1.y;
410 intersection = p3.withX (p1.x + along * d1.x);
411 return isZeroToOne (along);
416 auto along = (p1.x - p3.x) / d2.x;
417 intersection = p1.withY (p3.y + along * d2.y);
418 return isZeroToOne (along);
423 auto along = (p3.x - p1.x) / d1.x;
424 intersection = p3.withY (p1.y + along * d1.y);
425 return isZeroToOne (along);
429 intersection = (p2 + p3) /
static_cast<ValueType
> (2);
433 auto along1 = ((p1.y - p3.y) * d2.x - (p1.x - p3.x) * d2.y) / divisor;
434 intersection = p1 + d1 * along1;
436 if (! isZeroToOne (along1))
439 auto along2 = ((p1.y - p3.y) * d1.x - (p1.x - p3.x) * d1.y) / divisor;
440 return isZeroToOne (along2);
Line(Point< ValueType > startPoint, Point< ValueType > endPoint) noexcept
Creates a line from its start and end points.
Line reversed() const noexcept
Returns a line that is the same as this one, but with the start and end reversed,.
ValueType getStartY() const noexcept
Returns the y coordinate of the line's start point.
static Line fromStartAndAngle(Point< ValueType > startPoint, ValueType length, ValueType angle) noexcept
Creates a line from a start point, length and angle.
~Line()=default
Destructor.
bool isVertical() const noexcept
Returns true if the line's start and end x coordinates are the same.
Line withLengthenedEnd(ValueType distanceToLengthenBy) const noexcept
Returns a lengthened copy of this line.
void setStart(ValueType newStartX, ValueType newStartY) noexcept
Changes this line's start point.
Point< ValueType >::FloatType getAngle() const noexcept
Returns the line's angle.
ValueType getEndY() const noexcept
Returns the y coordinate of the line's end point.
void setStart(const Point< ValueType > newStart) noexcept
Changes this line's start point.
Point< ValueType > getIntersection(Line line) const noexcept
Finds the intersection between two lines.
Point< ValueType > getPointAlongLineProportionally(typename Point< ValueType >::FloatType proportionOfLength) const noexcept
Returns the location of the point which is a given distance along this line proportional to the line'...
Point< ValueType > getPointAlongLine(ValueType distanceFromStart) const noexcept
Returns the location of the point which is a given distance along this line.
Line withLengthenedStart(ValueType distanceToLengthenBy) const noexcept
Returns a lengthened copy of this line.
Line(ValueType startX, ValueType startY, ValueType endX, ValueType endY) noexcept
Creates a line based on the coordinates of its start and end points.
ValueType getLengthSquared() const noexcept
Returns the length of the line.
bool isPointAbove(Point< ValueType > point) const noexcept
Returns true if the given point lies above this line.
Line withShortenedStart(ValueType distanceToShortenBy) const noexcept
Returns a shortened copy of this line.
bool operator!=(Line other) const noexcept
Compares two lines.
void setEnd(const Point< ValueType > newEnd) noexcept
Changes this line's end point.
bool intersects(Line other) const noexcept
Returns true if this line intersects another.
Line & operator=(const Line &)=default
Copies a line from another one.
ValueType getLength() const noexcept
Returns the length of the line.
ValueType findNearestProportionalPositionTo(Point< ValueType > point) const noexcept
Finds the point on this line which is nearest to a given point, and returns its position as a proport...
Line()=default
Creates a line, using (0, 0) as its start and end points.
Line< float > toFloat() const noexcept
Casts this line to float coordinates.
ValueType getStartX() const noexcept
Returns the x coordinate of the line's start point.
Point< ValueType > findNearestPointTo(Point< ValueType > point) const noexcept
Finds the point on this line which is nearest to a given point.
ValueType getDistanceFromPoint(Point< ValueType > targetPoint, Point< ValueType > &pointOnLine) const noexcept
Returns the smallest distance between this line segment and a given point.
bool operator==(Line other) const noexcept
Compares two lines.
void setEnd(ValueType newEndX, ValueType newEndY) noexcept
Changes this line's end point.
Line(const Line &)=default
Creates a copy of another line.
bool isHorizontal() const noexcept
Returns true if the line's start and end y coordinates are the same.
Point< ValueType > getEnd() const noexcept
Returns the line's end point.
ValueType getEndX() const noexcept
Returns the x coordinate of the line's end point.
Line< double > toDouble() const noexcept
Casts this line to double coordinates.
void applyTransform(const AffineTransform &transform) noexcept
Applies an affine transform to the line's start and end points.
Line withShortenedEnd(ValueType distanceToShortenBy) const noexcept
Returns a shortened copy of this line.
Point< ValueType > getPointAlongLine(ValueType distanceFromStart, ValueType perpendicularDistance) const noexcept
Returns a point which is a certain distance along and to the side of this line.
bool intersects(Line line, Point< ValueType > &intersection) const noexcept
Finds the intersection between two lines.
Point< ValueType > getStart() const noexcept
Returns the line's start point.
A pair of (x, y) coordinates.
constexpr bool approximatelyEqual(Type a, Type b, Tolerance< Type > tolerance=Tolerance< Type >{} .withAbsolute(std::numeric_limits< Type >::min()) .withRelative(std::numeric_limits< Type >::epsilon()))
Returns true if the two floating-point numbers are approximately equal.
constexpr Type jmin(Type a, Type b)
Returns the smaller of two values.
Type jlimit(Type lowerLimit, Type upperLimit, Type valueToConstrain) noexcept
Constrains a value to keep it within a given range.
Type juce_hypot(Type a, Type b) noexcept
Using juce_hypot is easier than dealing with the different types of hypot function that are provided ...