DISTRHO Plugin Framework
Geometry.hpp
1 /*
2  * DISTRHO Plugin Framework (DPF)
3  * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com>
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any purpose with
6  * or without fee is hereby granted, provided that the above copyright notice and this
7  * permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
10  * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
11  * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
12  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
13  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 #ifndef DGL_GEOMETRY_HPP_INCLUDED
18 #define DGL_GEOMETRY_HPP_INCLUDED
19 
20 #include "Base.hpp"
21 
22 START_NAMESPACE_DGL
23 
24 // --------------------------------------------------------------------------------------------------------------------
25 // Forward class names
26 
27 template<typename> class Line;
28 template<typename> class Circle;
29 template<typename> class Triangle;
30 template<typename> class Rectangle;
31 
32 // --------------------------------------------------------------------------------------------------------------------
33 
34 /**
35  DGL Point class.
36 
37  This class describes a single point in space, defined by an X and Y value.
38  */
39 template<typename T>
40 class Point
41 {
42 public:
43  /**
44  Constructor for (0, 0) point.
45  */
46  Point() noexcept;
47 
48  /**
49  Constructor using custom X and Y values.
50  */
51  Point(const T& x, const T& y) noexcept;
52 
53  /**
54  Constructor using another Point class values.
55  */
56  Point(const Point<T>& pos) noexcept;
57 
58  /**
59  Get X value.
60  */
61  const T& getX() const noexcept;
62 
63  /**
64  Get Y value.
65  */
66  const T& getY() const noexcept;
67 
68  /**
69  Set X value to @a x.
70  */
71  void setX(const T& x) noexcept;
72 
73  /**
74  Set Y value to @a y.
75  */
76  void setY(const T& y) noexcept;
77 
78  /**
79  Set X and Y values to @a x and @a y respectively.
80  */
81  void setPos(const T& x, const T& y) noexcept;
82 
83  /**
84  Set X and Y values according to @a pos.
85  */
86  void setPos(const Point<T>& pos) noexcept;
87 
88  /**
89  Move this point by @a x and @a y values.
90  */
91  void moveBy(const T& x, const T& y) noexcept;
92 
93  /**
94  Move this point by @a pos.
95  */
96  void moveBy(const Point<T>& pos) noexcept;
97 
98  /**
99  Return true if point is (0, 0).
100  */
101  bool isZero() const noexcept;
102 
103  /**
104  Return true if point is not (0, 0).
105  */
106  bool isNotZero() const noexcept;
107 
108  Point<T> operator+(const Point<T>& pos) noexcept;
109  Point<T> operator-(const Point<T>& pos) noexcept;
110  Point<T>& operator=(const Point<T>& pos) noexcept;
111  Point<T>& operator+=(const Point<T>& pos) noexcept;
112  Point<T>& operator-=(const Point<T>& pos) noexcept;
113  bool operator==(const Point<T>& pos) const noexcept;
114  bool operator!=(const Point<T>& pos) const noexcept;
115 
116 private:
117  T x, y;
118  template<typename> friend class Line;
119  template<typename> friend class Circle;
120  template<typename> friend class Triangle;
121  template<typename> friend class Rectangle;
122 };
123 
124 // --------------------------------------------------------------------------------------------------------------------
125 
126 /**
127  DGL Size class.
128 
129  This class describes a size, defined by a width and height value.
130  */
131 template<typename T>
132 class Size
133 {
134 public:
135  /**
136  Constructor for null size (0x0).
137  */
138  Size() noexcept;
139 
140  /**
141  Constructor using custom width and height values.
142  */
143  Size(const T& width, const T& height) noexcept;
144 
145  /**
146  Constructor using another Size class values.
147  */
148  Size(const Size<T>& size) noexcept;
149 
150  /**
151  Get width.
152  */
153  const T& getWidth() const noexcept;
154 
155  /**
156  Get height.
157  */
158  const T& getHeight() const noexcept;
159 
160  /**
161  Set width.
162  */
163  void setWidth(const T& width) noexcept;
164 
165  /**
166  Set height.
167  */
168  void setHeight(const T& height) noexcept;
169 
170  /**
171  Set size to @a width and @a height.
172  */
173  void setSize(const T& width, const T& height) noexcept;
174 
175  /**
176  Set size.
177  */
178  void setSize(const Size<T>& size) noexcept;
179 
180  /**
181  Grow size by @a multiplier.
182  */
183  void growBy(double multiplier) noexcept;
184 
185  /**
186  Shrink size by @a divider.
187  */
188  void shrinkBy(double divider) noexcept;
189 
190  /**
191  Return true if size is null (0x0).
192  An null size is also invalid.
193  */
194  bool isNull() const noexcept;
195 
196  /**
197  Return true if size is not null (0x0).
198  A non-null size is still invalid if its width or height are negative.
199  */
200  bool isNotNull() const noexcept;
201 
202  /**
203  Return true if size is valid (width and height are higher than zero).
204  */
205  bool isValid() const noexcept;
206 
207  /**
208  Return true if size is invalid (width or height are lower or equal to zero).
209  An invalid size might not be null under some circumstances.
210  */
211  bool isInvalid() const noexcept;
212 
213  Size<int> toInt() const noexcept;
214 
215  Size<T> operator+(const Size<T>& size) noexcept;
216  Size<T> operator-(const Size<T>& size) noexcept;
217  Size<T>& operator=(const Size<T>& size) noexcept;
218  Size<T>& operator+=(const Size<T>& size) noexcept;
219  Size<T>& operator-=(const Size<T>& size) noexcept;
220  Size<T>& operator*=(double m) noexcept;
221  Size<T>& operator/=(double d) noexcept;
222  Size<T> operator*(double m) const noexcept;
223  Size<T> operator/(double m) const noexcept;
224  bool operator==(const Size<T>& size) const noexcept;
225  bool operator!=(const Size<T>& size) const noexcept;
226 
227 private:
228  T fWidth, fHeight;
229  template<typename> friend class Rectangle;
230 };
231 
232 // -----------------------------------------------------------------------
233 
234 /**
235  DGL Line class.
236 
237  This class describes a line, defined by two points.
238  */
239 template<typename T>
240 class Line
241 {
242 public:
243  /**
244  Constructor for a null line ([0,0] to [0,0]).
245  */
246  Line() noexcept;
247 
248  /**
249  Constructor using custom start X, start Y, end X and end Y values.
250  */
251  Line(const T& startX, const T& startY, const T& endX, const T& endY) noexcept;
252 
253  /**
254  Constructor using custom start X, start Y and end pos values.
255  */
256  Line(const T& startX, const T& startY, const Point<T>& endPos) noexcept;
257 
258  /**
259  Constructor using custom start pos, end X and end Y values.
260  */
261  Line(const Point<T>& startPos, const T& endX, const T& endY) noexcept;
262 
263  /**
264  Constructor using custom start and end pos values.
265  */
266  Line(const Point<T>& startPos, const Point<T>& endPos) noexcept;
267 
268  /**
269  Constructor using another Line class values.
270  */
271  Line(const Line<T>& line) noexcept;
272 
273  /**
274  Get start X value.
275  */
276  const T& getStartX() const noexcept;
277 
278  /**
279  Get start Y value.
280  */
281  const T& getStartY() const noexcept;
282 
283  /**
284  Get end X value.
285  */
286  const T& getEndX() const noexcept;
287 
288  /**
289  Get end Y value.
290  */
291  const T& getEndY() const noexcept;
292 
293  /**
294  Get start position.
295  */
296  const Point<T>& getStartPos() const noexcept;
297 
298  /**
299  Get end position.
300  */
301  const Point<T>& getEndPos() const noexcept;
302 
303  /**
304  Set start X value to @a x.
305  */
306  void setStartX(const T& x) noexcept;
307 
308  /**
309  Set start Y value to @a y.
310  */
311  void setStartY(const T& y) noexcept;
312 
313  /**
314  Set start X and Y values to @a x and @a y respectively.
315  */
316  void setStartPos(const T& x, const T& y) noexcept;
317 
318  /**
319  Set start X and Y values according to @a pos.
320  */
321  void setStartPos(const Point<T>& pos) noexcept;
322 
323  /**
324  Set end X value to @a x.
325  */
326  void setEndX(const T& x) noexcept;
327 
328  /**
329  Set end Y value to @a y.
330  */
331  void setEndY(const T& y) noexcept;
332 
333  /**
334  Set end X and Y values to @a x and @a y respectively.
335  */
336  void setEndPos(const T& x, const T& y) noexcept;
337 
338  /**
339  Set end X and Y values according to @a pos.
340  */
341  void setEndPos(const Point<T>& pos) noexcept;
342 
343  /**
344  Move this line by @a x and @a y values.
345  */
346  void moveBy(const T& x, const T& y) noexcept;
347 
348  /**
349  Move this line by @a pos.
350  */
351  void moveBy(const Point<T>& pos) noexcept;
352 
353  /**
354  Return true if line is null (start and end pos are equal).
355  */
356  bool isNull() const noexcept;
357 
358  /**
359  Return true if line is not null (start and end pos are different).
360  */
361  bool isNotNull() const noexcept;
362 
363 #ifndef DPF_TEST_POINT_CPP
364  /**
365  Draw this line using the provided graphics context, optionally specifying line width.
366  */
367  void draw(const GraphicsContext& context, T width = 1);
368 #endif
369 
370  Line<T>& operator=(const Line<T>& line) noexcept;
371  bool operator==(const Line<T>& line) const noexcept;
372  bool operator!=(const Line<T>& line) const noexcept;
373 
374 #ifndef DPF_TEST_POINT_CPP
375  /**
376  Draw this line using the current OpenGL state.@n
377  DEPRECATED Please use draw(const GraphicsContext&) instead.
378  */
379  DISTRHO_DEPRECATED_BY("draw(const GraphicsContext&)")
380  void draw();
381 #endif
382 
383 private:
384  Point<T> posStart, posEnd;
385 };
386 
387 // -----------------------------------------------------------------------
388 
389 /**
390  DGL Circle class.
391 
392  This class describes a circle, defined by position, size and a minimum of 3 segments.
393 
394  TODO: report if circle starts at top-left, bottom-right or center.
395  and size grows from which point?
396  */
397 template<typename T>
398 class Circle
399 {
400 public:
401  /**
402  Constructor for a null circle.
403  */
404  Circle() noexcept;
405 
406  /**
407  Constructor using custom X, Y and size values.
408  */
409  Circle(const T& x, const T& y, const float size, const uint numSegments = 300);
410 
411  /**
412  Constructor using custom position and size values.
413  */
414  Circle(const Point<T>& pos, const float size, const uint numSegments = 300);
415 
416  /**
417  Constructor using another Circle class values.
418  */
419  Circle(const Circle<T>& cir) noexcept;
420 
421  /**
422  Get X value.
423  */
424  const T& getX() const noexcept;
425 
426  /**
427  Get Y value.
428  */
429  const T& getY() const noexcept;
430 
431  /**
432  Get position.
433  */
434  const Point<T>& getPos() const noexcept;
435 
436  /**
437  Set X value to @a x.
438  */
439  void setX(const T& x) noexcept;
440 
441  /**
442  Set Y value to @a y.
443  */
444  void setY(const T& y) noexcept;
445 
446  /**
447  Set X and Y values to @a x and @a y respectively.
448  */
449  void setPos(const T& x, const T& y) noexcept;
450 
451  /**
452  Set X and Y values according to @a pos.
453  */
454  void setPos(const Point<T>& pos) noexcept;
455 
456  /**
457  Get size.
458  */
459  float getSize() const noexcept;
460 
461  /**
462  Set size.
463  @note Must always be > 0
464  */
465  void setSize(const float size) noexcept;
466 
467  /**
468  Get the current number of line segments that make this circle.
469  */
470  uint getNumSegments() const noexcept;
471 
472  /**
473  Set the number of line segments that will make this circle.
474  @note Must always be >= 3
475  */
476  void setNumSegments(const uint num);
477 
478  /**
479  Draw this circle using the provided graphics context.
480  */
481  void draw(const GraphicsContext& context);
482 
483  /**
484  Draw lines (outline of this circle) using the provided graphics context, optionally specifying line width.
485  */
486  void drawOutline(const GraphicsContext& context, T lineWidth = 1);
487 
488  Circle<T>& operator=(const Circle<T>& cir) noexcept;
489  bool operator==(const Circle<T>& cir) const noexcept;
490  bool operator!=(const Circle<T>& cir) const noexcept;
491 
492 #ifndef DPF_TEST_POINT_CPP
493  /**
494  Draw this circle using the current OpenGL state.@n
495  DEPRECATED Please use draw(const GraphicsContext&) instead.
496  */
497  DISTRHO_DEPRECATED_BY("draw(const GraphicsContext&)")
498  void draw();
499 
500  /**
501  Draw lines (outline of this circle) using the current OpenGL state.@n
502  DEPRECATED Please use drawOutline(const GraphicsContext&,T) instead.
503  */
504  DISTRHO_DEPRECATED_BY("drawOutline(const GraphicsContext&)")
505  void drawOutline();
506 #endif
507 
508 private:
509  Point<T> fPos;
510  float fSize;
511  uint fNumSegments;
512 
513  // cached values
514  float fTheta, fCos, fSin;
515 };
516 
517 // -----------------------------------------------------------------------
518 
519 /**
520  DGL Triangle class.
521 
522  This class describes a triangle, defined by 3 points.
523  */
524 template<typename T>
525 class Triangle
526 {
527 public:
528  /**
529  Constructor for a null triangle.
530  */
531  Triangle() noexcept;
532 
533  /**
534  Constructor using custom X and Y values.
535  */
536  Triangle(const T& x1, const T& y1, const T& x2, const T& y2, const T& x3, const T& y3) noexcept;
537 
538  /**
539  Constructor using custom position values.
540  */
541  Triangle(const Point<T>& pos1, const Point<T>& pos2, const Point<T>& pos3) noexcept;
542 
543  /**
544  Constructor using another Triangle class values.
545  */
546  Triangle(const Triangle<T>& tri) noexcept;
547 
548  /**
549  Return true if triangle is null (all its points are equal).
550  An null triangle is also invalid.
551  */
552  bool isNull() const noexcept;
553 
554  /**
555  Return true if triangle is not null (one its points is different from the others).
556  A non-null triangle is still invalid if two of its points are equal.
557  */
558  bool isNotNull() const noexcept;
559 
560  /**
561  Return true if triangle is valid (all its points are different).
562  */
563  bool isValid() const noexcept;
564 
565  /**
566  Return true if triangle is invalid (one or two of its points are equal).
567  An invalid triangle might not be null under some circumstances.
568  */
569  bool isInvalid() const noexcept;
570 
571  /**
572  Draw this triangle using the provided graphics context.
573  */
574  void draw(const GraphicsContext& context);
575 
576  /**
577  Draw lines (outline of this triangle) using the provided graphics context, optionally specifying line width.
578  */
579  void drawOutline(const GraphicsContext& context, T lineWidth = 1);
580 
581  Triangle<T>& operator=(const Triangle<T>& tri) noexcept;
582  bool operator==(const Triangle<T>& tri) const noexcept;
583  bool operator!=(const Triangle<T>& tri) const noexcept;
584 
585 #ifndef DPF_TEST_POINT_CPP
586  /**
587  Draw this triangle using the current OpenGL state.@n
588  DEPRECATED Please use draw(const GraphicsContext&) instead.
589  */
590  DISTRHO_DEPRECATED_BY("draw(const GraphicsContext&)")
591  void draw();
592 
593  /**
594  Draw lines (outline of this triangle) using the current OpenGL state.@n
595  DEPRECATED Please use drawOutline(const GraphicsContext&,T) instead.
596  */
597  DISTRHO_DEPRECATED_BY("drawOutline(const GraphicsContext&)")
598  void drawOutline();
599 #endif
600 
601 private:
602  Point<T> pos1, pos2, pos3;
603 };
604 
605 // -----------------------------------------------------------------------
606 
607 /**
608  DGL Rectangle class.
609 
610  This class describes a rectangle, defined by a starting point and a size.
611  */
612 template<typename T>
614 {
615 public:
616  /**
617  Constructor for a null rectangle.
618  */
619  Rectangle() noexcept;
620 
621  /**
622  Constructor using custom X, Y, width and height values.
623  */
624  Rectangle(const T& x, const T& y, const T& width, const T& height) noexcept;
625 
626  /**
627  Constructor using custom X, Y and size values.
628  */
629  Rectangle(const T& x, const T& y, const Size<T>& size) noexcept;
630 
631  /**
632  Constructor using custom pos, width and height values.
633  */
634  Rectangle(const Point<T>& pos, const T& width, const T& height) noexcept;
635 
636  /**
637  Constructor using custom position and size.
638  */
639  Rectangle(const Point<T>& pos, const Size<T>& size) noexcept;
640 
641  /**
642  Constructor using another Rectangle class values.
643  */
644  Rectangle(const Rectangle<T>& rect) noexcept;
645 
646  /**
647  Get X value.
648  */
649  const T& getX() const noexcept;
650 
651  /**
652  Get Y value.
653  */
654  const T& getY() const noexcept;
655 
656  /**
657  Get width.
658  */
659  const T& getWidth() const noexcept;
660 
661  /**
662  Get height.
663  */
664  const T& getHeight() const noexcept;
665 
666  /**
667  Get position.
668  */
669  const Point<T>& getPos() const noexcept;
670 
671  /**
672  Get size.
673  */
674  const Size<T>& getSize() const noexcept;
675 
676  /**
677  Set X value as @a x.
678  */
679  void setX(const T& x) noexcept;
680 
681  /**
682  Set Y value as @a y.
683  */
684  void setY(const T& y) noexcept;
685 
686  /**
687  Set X and Y values as @a x and @a y respectively.
688  */
689  void setPos(const T& x, const T& y) noexcept;
690 
691  /**
692  Set X and Y values according to @a pos.
693  */
694  void setPos(const Point<T>& pos) noexcept;
695 
696  /**
697  Move this rectangle by @a x and @a y values.
698  */
699  void moveBy(const T& x, const T& y) noexcept;
700 
701  /**
702  Move this rectangle by @a pos.
703  */
704  void moveBy(const Point<T>& pos) noexcept;
705 
706  /**
707  Set width.
708  */
709  void setWidth(const T& width) noexcept;
710 
711  /**
712  Set height.
713  */
714  void setHeight(const T& height) noexcept;
715 
716  /**
717  Set size using @a width and @a height.
718  */
719  void setSize(const T& width, const T& height) noexcept;
720 
721  /**
722  Set size.
723  */
724  void setSize(const Size<T>& size) noexcept;
725 
726  /**
727  Grow size by @a multiplier.
728  */
729  void growBy(double multiplier) noexcept;
730 
731  /**
732  Shrink size by @a divider.
733  */
734  void shrinkBy(double divider) noexcept;
735 
736  /**
737  Set rectangle using @a pos and @a size.
738  */
739  void setRectangle(const Point<T>& pos, const Size<T>& size) noexcept;
740 
741  /**
742  Set rectangle.
743  */
744  void setRectangle(const Rectangle<T>& rect) noexcept;
745 
746  /**
747  Check if this rectangle contains the point defined by @a X and @a Y.
748  */
749  bool contains(const T& x, const T& y) const noexcept;
750 
751  /**
752  Check if this rectangle contains the point @a pos.
753  */
754  bool contains(const Point<T>& pos) const noexcept;
755 
756  /**
757  Check if this rectangle contains the point @a pos affected by a custom scale.
758  */
759  bool containsAfterScaling(const Point<T>& pos, double scaling) const noexcept;
760 
761  /**
762  Check if this rectangle contains the point @a pos of another type.
763  */
764  template<typename T2>
765  bool contains(const Point<T2>& pos) const noexcept;
766 
767  /**
768  Check if this rectangle contains X.
769  */
770  bool containsX(const T& x) const noexcept;
771 
772  /**
773  Check if this rectangle contains Y.
774  */
775  bool containsY(const T& y) const noexcept;
776 
777  /**
778  Return true if size is null (0x0).
779  An null size is also invalid.
780  */
781  bool isNull() const noexcept;
782 
783  /**
784  Return true if size is not null (0x0).
785  A non-null size is still invalid if its width or height are negative.
786  */
787  bool isNotNull() const noexcept;
788 
789  /**
790  Return true if size is valid (width and height are higher than zero).
791  */
792  bool isValid() const noexcept;
793 
794  /**
795  Return true if size is invalid (width or height are lower or equal to zero).
796  An invalid size might not be null under some circumstances.
797  */
798  bool isInvalid() const noexcept;
799 
800  /**
801  Draw this rectangle using the provided graphics context.
802  */
803  void draw(const GraphicsContext& context);
804 
805  /**
806  Draw lines (outline of this rectangle) using the provided graphics context, optionally specifying line width.
807  */
808  void drawOutline(const GraphicsContext& context, T lineWidth = 1);
809 
810  Rectangle<T>& operator=(const Rectangle<T>& rect) noexcept;
811  Rectangle<T>& operator*=(double m) noexcept;
812  Rectangle<T>& operator/=(double d) noexcept;
813  bool operator==(const Rectangle<T>& size) const noexcept;
814  bool operator!=(const Rectangle<T>& size) const noexcept;
815 
816  /**
817  Draw this rectangle using the current OpenGL state.@n
818  DEPRECATED Please use draw(const GraphicsContext&) instead.
819  */
820  DISTRHO_DEPRECATED_BY("draw(const GraphicsContext&)")
821  void draw();
822 
823  /**
824  Draw lines (outline of this rectangle) using the current OpenGL state.@n
825  DEPRECATED Please use drawOutline(const GraphicsContext&,T) instead.
826  */
827  DISTRHO_DEPRECATED_BY("drawOutline(const GraphicsContext&)")
828  void drawOutline();
829 
830 private:
831  Point<T> pos;
832  Size<T> size;
833 };
834 
835 // -----------------------------------------------------------------------
836 
837 END_NAMESPACE_DGL
838 
839 #endif // DGL_GEOMETRY_HPP_INCLUDED
Definition: Geometry.hpp:399
Circle() noexcept
Definition: Geometry.hpp:241
Line() noexcept
void draw(const GraphicsContext &context, T width=1)
Definition: Geometry.hpp:41
void setX(const T &x) noexcept
void moveBy(const T &x, const T &y) noexcept
bool isZero() const noexcept
void setY(const T &y) noexcept
void setPos(const T &x, const T &y) noexcept
const T & getY() const noexcept
Point() noexcept
bool isNotZero() const noexcept
const T & getX() const noexcept
Definition: Geometry.hpp:614
Rectangle() noexcept
Definition: Geometry.hpp:133
Size() noexcept
Definition: Geometry.hpp:526
Triangle() noexcept
Definition: Base.hpp:253