openshot-audio  0.1.7
juce_Line.h
Go to the documentation of this file.
1 /*
2  ==============================================================================
3 
4  This file is part of the JUCE library.
5  Copyright (c) 2015 - ROLI Ltd.
6 
7  Permission is granted to use this software under the terms of either:
8  a) the GPL v2 (or any later version)
9  b) the Affero GPL v3
10 
11  Details of these licenses can be found at: www.gnu.org/licenses
12 
13  JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
14  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
15  A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 
17  ------------------------------------------------------------------------------
18 
19  To release a closed-source product which uses JUCE, commercial licenses are
20  available: visit www.juce.com for more information.
21 
22  ==============================================================================
23 */
24 
25 #ifndef JUCE_LINE_H_INCLUDED
26 #define JUCE_LINE_H_INCLUDED
27 
28 
29 //==============================================================================
43 template <typename ValueType>
44 class Line
45 {
46 public:
47  //==============================================================================
50 
52  Line (const Line& other) noexcept
53  : start (other.start),
54  end (other.end)
55  {
56  }
57 
59  Line (ValueType startX, ValueType startY, ValueType endX, ValueType endY) noexcept
60  : start (startX, startY),
61  end (endX, endY)
62  {
63  }
64 
66  Line (const Point<ValueType> startPoint,
67  const Point<ValueType> endPoint) noexcept
68  : start (startPoint),
69  end (endPoint)
70  {
71  }
72 
74  Line& operator= (const Line& other) noexcept
75  {
76  start = other.start;
77  end = other.end;
78  return *this;
79  }
80 
83 
84  //==============================================================================
86  inline ValueType getStartX() const noexcept { return start.x; }
87 
89  inline ValueType getStartY() const noexcept { return start.y; }
90 
92  inline ValueType getEndX() const noexcept { return end.x; }
93 
95  inline ValueType getEndY() const noexcept { return end.y; }
96 
98  inline Point<ValueType> getStart() const noexcept { return start; }
99 
101  inline Point<ValueType> getEnd() const noexcept { return end; }
102 
104  void setStart (ValueType newStartX, ValueType newStartY) noexcept { start.setXY (newStartX, newStartY); }
105 
107  void setEnd (ValueType newEndX, ValueType newEndY) noexcept { end.setXY (newEndX, newEndY); }
108 
110  void setStart (const Point<ValueType> newStart) noexcept { start = newStart; }
111 
113  void setEnd (const Point<ValueType> newEnd) noexcept { end = newEnd; }
114 
116  const Line reversed() const noexcept { return Line (end, start); }
117 
119  void applyTransform (const AffineTransform& transform) noexcept
120  {
121  start.applyTransform (transform);
122  end.applyTransform (transform);
123  }
124 
125  //==============================================================================
127  ValueType getLength() const noexcept { return start.getDistanceFrom (end); }
128 
130  bool isVertical() const noexcept { return start.x == end.x; }
131 
133  bool isHorizontal() const noexcept { return start.y == end.y; }
134 
140  typename Point<ValueType>::FloatType getAngle() const noexcept { return start.getAngleToPoint (end); }
141 
143  Line<float> toFloat() const noexcept { return Line<float> (start.toFloat(), end.toFloat()); }
144 
146  Line<double> toDouble() const noexcept { return Line<double> (start.toDouble(), end.toDouble()); }
147 
148  //==============================================================================
150  bool operator== (const Line& other) const noexcept { return start == other.start && end == other.end; }
151 
153  bool operator!= (const Line& other) const noexcept { return start != other.start || end != other.end; }
154 
155  //==============================================================================
162  {
164  findIntersection (start, end, line.start, line.end, p);
165  return p;
166  }
167 
180  bool intersects (const Line& line, Point<ValueType>& intersection) const noexcept
181  {
182  return findIntersection (start, end, line.start, line.end, intersection);
183  }
184 
186  bool intersects (const Line& other) const noexcept
187  {
188  Point<ValueType> ignored;
189  return findIntersection (start, end, other.start, other.end, ignored);
190  }
191 
192  //==============================================================================
200  Point<ValueType> getPointAlongLine (ValueType distanceFromStart) const noexcept
201  {
202  return start + (end - start) * (distanceFromStart / getLength());
203  }
204 
218  Point<ValueType> getPointAlongLine (ValueType distanceFromStart,
219  ValueType perpendicularDistance) const noexcept
220  {
221  const Point<ValueType> delta (end - start);
222  const double length = juce_hypot ((double) delta.x,
223  (double) delta.y);
224  if (length <= 0)
225  return start;
226 
227  return Point<ValueType> (start.x + static_cast<ValueType> ((delta.x * distanceFromStart - delta.y * perpendicularDistance) / length),
228  start.y + static_cast<ValueType> ((delta.y * distanceFromStart + delta.x * perpendicularDistance) / length));
229  }
230 
241  Point<ValueType> getPointAlongLineProportionally (ValueType proportionOfLength) const noexcept
242  {
243  return start + (end - start) * proportionOfLength;
244  }
245 
257  ValueType getDistanceFromPoint (const Point<ValueType> targetPoint,
258  Point<ValueType>& pointOnLine) const noexcept
259  {
260  const Point<ValueType> delta (end - start);
261  const double length = delta.x * delta.x + delta.y * delta.y;
262 
263  if (length > 0)
264  {
265  const double prop = ((targetPoint.x - start.x) * delta.x
266  + (targetPoint.y - start.y) * delta.y) / length;
267 
268  if (prop >= 0 && prop <= 1.0)
269  {
270  pointOnLine = start + delta * static_cast<ValueType> (prop);
271  return targetPoint.getDistanceFrom (pointOnLine);
272  }
273  }
274 
275  const float fromStart = targetPoint.getDistanceFrom (start);
276  const float fromEnd = targetPoint.getDistanceFrom (end);
277 
278  if (fromStart < fromEnd)
279  {
280  pointOnLine = start;
281  return fromStart;
282  }
283  else
284  {
285  pointOnLine = end;
286  return fromEnd;
287  }
288  }
289 
299  {
300  const Point<ValueType> delta (end - start);
301  const double length = delta.x * delta.x + delta.y * delta.y;
302 
303  return length <= 0 ? 0
304  : jlimit (ValueType(), static_cast<ValueType> (1),
305  static_cast<ValueType> ((((point.x - start.x) * delta.x
306  + (point.y - start.y) * delta.y) / length)));
307  }
308 
313  {
315  }
316 
323  bool isPointAbove (const Point<ValueType> point) const noexcept
324  {
325  return start.x != end.x
326  && point.y < ((end.y - start.y)
327  * (point.x - start.x)) / (end.x - start.x) + start.y;
328  }
329 
330  //==============================================================================
336  Line withShortenedStart (ValueType distanceToShortenBy) const noexcept
337  {
338  return Line (getPointAlongLine (jmin (distanceToShortenBy, getLength())), end);
339  }
340 
346  Line withShortenedEnd (ValueType distanceToShortenBy) const noexcept
347  {
348  const ValueType length = getLength();
349  return Line (start, getPointAlongLine (length - jmin (distanceToShortenBy, length)));
350  }
351 
352 private:
353  //==============================================================================
354  Point<ValueType> start, end;
355 
356  static bool findIntersection (const Point<ValueType> p1, const Point<ValueType> p2,
357  const Point<ValueType> p3, const Point<ValueType> p4,
358  Point<ValueType>& intersection) noexcept
359  {
360  if (p2 == p3)
361  {
362  intersection = p2;
363  return true;
364  }
365 
366  const Point<ValueType> d1 (p2 - p1);
367  const Point<ValueType> d2 (p4 - p3);
368  const ValueType divisor = d1.x * d2.y - d2.x * d1.y;
369 
370  if (divisor == 0)
371  {
372  if (! (d1.isOrigin() || d2.isOrigin()))
373  {
374  if (d1.y == 0 && d2.y != 0)
375  {
376  const ValueType along = (p1.y - p3.y) / d2.y;
377  intersection = p1.withX (p3.x + along * d2.x);
378  return along >= 0 && along <= static_cast<ValueType> (1);
379  }
380  else if (d2.y == 0 && d1.y != 0)
381  {
382  const ValueType along = (p3.y - p1.y) / d1.y;
383  intersection = p3.withX (p1.x + along * d1.x);
384  return along >= 0 && along <= static_cast<ValueType> (1);
385  }
386  else if (d1.x == 0 && d2.x != 0)
387  {
388  const ValueType along = (p1.x - p3.x) / d2.x;
389  intersection = p1.withY (p3.y + along * d2.y);
390  return along >= 0 && along <= static_cast<ValueType> (1);
391  }
392  else if (d2.x == 0 && d1.x != 0)
393  {
394  const ValueType along = (p3.x - p1.x) / d1.x;
395  intersection = p3.withY (p1.y + along * d1.y);
396  return along >= 0 && along <= static_cast<ValueType> (1);
397  }
398  }
399 
400  intersection = (p2 + p3) / static_cast<ValueType> (2);
401  return false;
402  }
403 
404  const ValueType along1 = ((p1.y - p3.y) * d2.x - (p1.x - p3.x) * d2.y) / divisor;
405  intersection = p1 + d1 * along1;
406 
407  if (along1 < 0 || along1 > static_cast<ValueType> (1))
408  return false;
409 
410  const ValueType along2 = ((p1.y - p3.y) * d1.x - (p1.x - p3.x) * d1.y) / divisor;
411  return along2 >= 0 && along2 <= static_cast<ValueType> (1);
412  }
413 };
414 
415 
416 #endif // JUCE_LINE_H_INCLUDED
ValueType getDistanceFromPoint(const Point< ValueType > targetPoint, Point< ValueType > &pointOnLine) const noexcept
Definition: juce_Line.h:257
ValueType getStartY() const noexcept
Definition: juce_Line.h:89
bool intersects(const Line &line, Point< ValueType > &intersection) const noexcept
Definition: juce_Line.h:180
bool operator==(const Line &other) const noexcept
Definition: juce_Line.h:150
Definition: juce_Line.h:44
#define noexcept
Definition: juce_CompilerSupport.h:141
bool intersects(const Line &other) const noexcept
Definition: juce_Line.h:186
Type jmin(const Type a, const Type b)
Definition: juce_core.h:113
bool operator!=(const Line &other) const noexcept
Definition: juce_Line.h:153
ValueType getDistanceFrom(Point other) const noexcept
Definition: juce_Point.h:148
Point< ValueType > getEnd() const noexcept
Definition: juce_Line.h:101
ValueType getEndY() const noexcept
Definition: juce_Line.h:95
Point< ValueType > getStart() const noexcept
Definition: juce_Line.h:98
const Line reversed() const noexcept
Definition: juce_Line.h:116
Definition: juce_Point.h:39
Point withX(ValueType newX) const noexcept
Definition: juce_Point.h:77
Line(const Point< ValueType > startPoint, const Point< ValueType > endPoint) noexcept
Definition: juce_Line.h:66
Point< ValueType > getPointAlongLine(ValueType distanceFromStart, ValueType perpendicularDistance) const noexcept
Definition: juce_Line.h:218
Line< double > toDouble() const noexcept
Definition: juce_Line.h:146
void setStart(ValueType newStartX, ValueType newStartY) noexcept
Definition: juce_Line.h:104
bool isPointAbove(const Point< ValueType > point) const noexcept
Definition: juce_Line.h:323
Line(ValueType startX, ValueType startY, ValueType endX, ValueType endY) noexcept
Definition: juce_Line.h:59
Line withShortenedEnd(ValueType distanceToShortenBy) const noexcept
Definition: juce_Line.h:346
Point< ValueType > getIntersection(const Line &line) const noexcept
Definition: juce_Line.h:161
Line & operator=(const Line &other) noexcept
Definition: juce_Line.h:74
bool isOrigin() const noexcept
Definition: juce_Point.h:59
void setStart(const Point< ValueType > newStart) noexcept
Definition: juce_Line.h:110
Line withShortenedStart(ValueType distanceToShortenBy) const noexcept
Definition: juce_Line.h:336
void setEnd(const Point< ValueType > newEnd) noexcept
Definition: juce_Line.h:113
bool isHorizontal() const noexcept
Definition: juce_Line.h:133
void applyTransform(const AffineTransform &transform) noexcept
Definition: juce_Line.h:119
Point< ValueType > getPointAlongLine(ValueType distanceFromStart) const noexcept
Definition: juce_Line.h:200
Type jlimit(const Type lowerLimit, const Type upperLimit, const Type valueToConstrain) noexcept
Definition: juce_MathsFunctions.h:220
ValueType getStartX() const noexcept
Definition: juce_Line.h:86
Type juce_hypot(Type a, Type b) noexcept
Definition: juce_core.h:313
ValueType getLength() const noexcept
Definition: juce_Line.h:127
Line(const Line &other) noexcept
Definition: juce_Line.h:52
Point< ValueType > findNearestPointTo(const Point< ValueType > point) const noexcept
Definition: juce_Line.h:312
ValueType findNearestProportionalPositionTo(const Point< ValueType > point) const noexcept
Definition: juce_Line.h:298
void setEnd(ValueType newEndX, ValueType newEndY) noexcept
Definition: juce_Line.h:107
Point< ValueType > getPointAlongLineProportionally(ValueType proportionOfLength) const noexcept
Definition: juce_Line.h:241
Definition: juce_AffineTransform.h:40
~Line() noexcept
Definition: juce_Line.h:82
bool isVertical() const noexcept
Definition: juce_Line.h:130
Point< ValueType >::FloatType getAngle() const noexcept
Definition: juce_Line.h:140
Line() noexcept
Definition: juce_Line.h:49
TypeHelpers::SmallestFloatType< ValueType >::type FloatType
Definition: juce_Point.h:141
Point withY(ValueType newY) const noexcept
Definition: juce_Point.h:80
Line< float > toFloat() const noexcept
Definition: juce_Line.h:143
ValueType x
Definition: juce_Point.h:226
ValueType y
Definition: juce_Point.h:227
ValueType getEndX() const noexcept
Definition: juce_Line.h:92