Geometry.hpp (20371B)
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> 613 class Rectangle 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