1 /* 2 * DISTRHO Plugin Framework (DPF) 3 * Copyright (C) 2012-2016 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 fX, fY; 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 is 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<T> operator+(const Size<T>& size) noexcept; 214 Size<T> operator-(const Size<T>& size) noexcept; 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*=(double m) noexcept; 219 Size<T>& operator/=(double d) noexcept; 220 bool operator==(const Size<T>& size) const noexcept; 221 bool operator!=(const Size<T>& size) const noexcept; 222 223 private: 224 T fWidth, fHeight; 225 template<typename> friend class Rectangle; 226 }; 227 228 // ----------------------------------------------------------------------- 229 230 /** 231 DGL Line class. 232 233 This class describes a line, defined by two points. 234 */ 235 template<typename T> 236 class Line 237 { 238 public: 239 /** 240 Constructor for a null line ([0,0] to [0,0]). 241 */ 242 Line() noexcept; 243 244 /** 245 Constructor using custom start X, start Y, end X and end Y values. 246 */ 247 Line(const T& startX, const T& startY, const T& endX, const T& endY) noexcept; 248 249 /** 250 Constructor using custom start X, start Y and end pos values. 251 */ 252 Line(const T& startX, const T& startY, const Point<T>& endPos) noexcept; 253 254 /** 255 Constructor using custom start pos, end X and end Y values. 256 */ 257 Line(const Point<T>& startPos, const T& endX, const T& endY) noexcept; 258 259 /** 260 Constructor using custom start and end pos values. 261 */ 262 Line(const Point<T>& startPos, const Point<T>& endPos) noexcept; 263 264 /** 265 Constructor using another Line class values. 266 */ 267 Line(const Line<T>& line) noexcept; 268 269 /** 270 Get start X value. 271 */ 272 const T& getStartX() const noexcept; 273 274 /** 275 Get start Y value. 276 */ 277 const T& getStartY() const noexcept; 278 279 /** 280 Get end X value. 281 */ 282 const T& getEndX() const noexcept; 283 284 /** 285 Get end Y value. 286 */ 287 const T& getEndY() const noexcept; 288 289 /** 290 Get start position. 291 */ 292 const Point<T>& getStartPos() const noexcept; 293 294 /** 295 Get end position. 296 */ 297 const Point<T>& getEndPos() const noexcept; 298 299 /** 300 Set start X value to @a x. 301 */ 302 void setStartX(const T& x) noexcept; 303 304 /** 305 Set start Y value to @a y. 306 */ 307 void setStartY(const T& y) noexcept; 308 309 /** 310 Set start X and Y values to @a x and @a y respectively. 311 */ 312 void setStartPos(const T& x, const T& y) noexcept; 313 314 /** 315 Set start X and Y values according to @a pos. 316 */ 317 void setStartPos(const Point<T>& pos) noexcept; 318 319 /** 320 Set end X value to @a x. 321 */ 322 void setEndX(const T& x) noexcept; 323 324 /** 325 Set end Y value to @a y. 326 */ 327 void setEndY(const T& y) noexcept; 328 329 /** 330 Set end X and Y values to @a x and @a y respectively. 331 */ 332 void setEndPos(const T& x, const T& y) noexcept; 333 334 /** 335 Set end X and Y values according to @a pos. 336 */ 337 void setEndPos(const Point<T>& pos) noexcept; 338 339 /** 340 Move this line by @a x and @a y values. 341 */ 342 void moveBy(const T& x, const T& y) noexcept; 343 344 /** 345 Move this line by @a pos. 346 */ 347 void moveBy(const Point<T>& pos) noexcept; 348 349 /** 350 Draw this line using the current OpenGL state. 351 */ 352 void draw(); 353 354 /** 355 Return true if line is null (start and end pos are equal). 356 */ 357 bool isNull() const noexcept; 358 359 /** 360 Return true if line is not null (start and end pos are different). 361 */ 362 bool isNotNull() const noexcept; 363 364 Line<T>& operator=(const Line<T>& line) noexcept; 365 bool operator==(const Line<T>& line) const noexcept; 366 bool operator!=(const Line<T>& line) const noexcept; 367 368 private: 369 Point<T> fPosStart, fPosEnd; 370 }; 371 372 // ----------------------------------------------------------------------- 373 374 /** 375 DGL Circle class. 376 377 This class describes a circle, defined by position, size and a minimum of 3 segments. 378 379 TODO: report if circle starts at top-left, bottom-right or center. 380 and size grows from which point? 381 */ 382 template<typename T> 383 class Circle 384 { 385 public: 386 /** 387 Constructor for a null circle. 388 */ 389 Circle() noexcept; 390 391 /** 392 Constructor using custom X, Y and size values. 393 */ 394 Circle(const T& x, const T& y, const float size, const uint numSegments = 300); 395 396 /** 397 Constructor using custom position and size values. 398 */ 399 Circle(const Point<T>& pos, const float size, const uint numSegments = 300); 400 401 /** 402 Constructor using another Circle class values. 403 */ 404 Circle(const Circle<T>& cir) noexcept; 405 406 /** 407 Get X value. 408 */ 409 const T& getX() const noexcept; 410 411 /** 412 Get Y value. 413 */ 414 const T& getY() const noexcept; 415 416 /** 417 Get position. 418 */ 419 const Point<T>& getPos() const noexcept; 420 421 /** 422 Set X value to @a x. 423 */ 424 void setX(const T& x) noexcept; 425 426 /** 427 Set Y value to @a y. 428 */ 429 void setY(const T& y) noexcept; 430 431 /** 432 Set X and Y values to @a x and @a y respectively. 433 */ 434 void setPos(const T& x, const T& y) noexcept; 435 436 /** 437 Set X and Y values according to @a pos. 438 */ 439 void setPos(const Point<T>& pos) noexcept; 440 441 /** 442 Get size. 443 */ 444 float getSize() const noexcept; 445 446 /** 447 Set size. 448 @note Must always be > 0 449 */ 450 void setSize(const float size) noexcept; 451 452 /** 453 Get the current number of line segments that make this circle. 454 */ 455 uint getNumSegments() const noexcept; 456 457 /** 458 Set the number of line segments that will make this circle. 459 @note Must always be >= 3 460 */ 461 void setNumSegments(const uint num); 462 463 /** 464 Draw this circle using the current OpenGL state. 465 */ 466 void draw(); 467 468 /** 469 Draw lines (outline of this circle) using the current OpenGL state. 470 */ 471 void drawOutline(); 472 473 Circle<T>& operator=(const Circle<T>& cir) noexcept; 474 bool operator==(const Circle<T>& cir) const noexcept; 475 bool operator!=(const Circle<T>& cir) const noexcept; 476 477 private: 478 Point<T> fPos; 479 float fSize; 480 uint fNumSegments; 481 482 // cached values 483 float fTheta, fCos, fSin; 484 485 /** @internal */ 486 void _draw(const bool outline); 487 }; 488 489 // ----------------------------------------------------------------------- 490 491 /** 492 DGL Triangle class. 493 494 This class describes a triangle, defined by 3 points. 495 */ 496 template<typename T> 497 class Triangle 498 { 499 public: 500 /** 501 Constructor for a null triangle. 502 */ 503 Triangle() noexcept; 504 505 /** 506 Constructor using custom X and Y values. 507 */ 508 Triangle(const T& x1, const T& y1, const T& x2, const T& y2, const T& x3, const T& y3) noexcept; 509 510 /** 511 Constructor using custom position values. 512 */ 513 Triangle(const Point<T>& pos1, const Point<T>& pos2, const Point<T>& pos3) noexcept; 514 515 /** 516 Constructor using another Triangle class values. 517 */ 518 Triangle(const Triangle<T>& tri) noexcept; 519 520 /** 521 Return true if triangle is null (all its points are equal). 522 An null triangle is also invalid. 523 */ 524 bool isNull() const noexcept; 525 526 /** 527 Return true if triangle is not null (one its points is different from the others). 528 A non-null triangle is still invalid if two of its points are equal. 529 */ 530 bool isNotNull() const noexcept; 531 532 /** 533 Return true if triangle is valid (all its points are different). 534 */ 535 bool isValid() const noexcept; 536 537 /** 538 Return true if triangle is invalid (one or two of its points are equal). 539 An invalid triangle might not be null under some circumstances. 540 */ 541 bool isInvalid() const noexcept; 542 543 /** 544 Draw this triangle using the current OpenGL state. 545 */ 546 void draw(); 547 548 /** 549 Draw lines (outline of this triangle) using the current OpenGL state. 550 */ 551 void drawOutline(); 552 553 Triangle<T>& operator=(const Triangle<T>& tri) noexcept; 554 bool operator==(const Triangle<T>& tri) const noexcept; 555 bool operator!=(const Triangle<T>& tri) const noexcept; 556 557 private: 558 Point<T> fPos1, fPos2, fPos3; 559 560 /** @internal */ 561 void _draw(const bool outline); 562 }; 563 564 // ----------------------------------------------------------------------- 565 566 /** 567 DGL Rectangle class. 568 569 This class describes a rectangle, defined by a starting point and a size. 570 */ 571 template<typename T> 572 class Rectangle 573 { 574 public: 575 /** 576 Constructor for a null rectangle. 577 */ 578 Rectangle() noexcept; 579 580 /** 581 Constructor using custom X, Y, width and height values. 582 */ 583 Rectangle(const T& x, const T& y, const T& width, const T& height) noexcept; 584 585 /** 586 Constructor using custom X, Y and size values. 587 */ 588 Rectangle(const T& x, const T& y, const Size<T>& size) noexcept; 589 590 /** 591 Constructor using custom pos, width and height values. 592 */ 593 Rectangle(const Point<T>& pos, const T& width, const T& height) noexcept; 594 595 /** 596 Constructor using custom position and size. 597 */ 598 Rectangle(const Point<T>& pos, const Size<T>& size) noexcept; 599 600 /** 601 Constructor using another Rectangle class values. 602 */ 603 Rectangle(const Rectangle<T>& rect) noexcept; 604 605 /** 606 Get X value. 607 */ 608 const T& getX() const noexcept; 609 610 /** 611 Get Y value. 612 */ 613 const T& getY() const noexcept; 614 615 /** 616 Get width. 617 */ 618 const T& getWidth() const noexcept; 619 620 /** 621 Get height. 622 */ 623 const T& getHeight() const noexcept; 624 625 /** 626 Get position. 627 */ 628 const Point<T>& getPos() const noexcept; 629 630 /** 631 Get size. 632 */ 633 const Size<T>& getSize() const noexcept; 634 635 /** 636 Set X value as @a x. 637 */ 638 void setX(const T& x) noexcept; 639 640 /** 641 Set Y value as @a y. 642 */ 643 void setY(const T& y) noexcept; 644 645 /** 646 Set X and Y values as @a x and @a y respectively. 647 */ 648 void setPos(const T& x, const T& y) noexcept; 649 650 /** 651 Set X and Y values according to @a pos. 652 */ 653 void setPos(const Point<T>& pos) noexcept; 654 655 /** 656 Move this rectangle by @a x and @a y values. 657 */ 658 void moveBy(const T& x, const T& y) noexcept; 659 660 /** 661 Move this rectangle by @a pos. 662 */ 663 void moveBy(const Point<T>& pos) noexcept; 664 665 /** 666 Set width. 667 */ 668 void setWidth(const T& width) noexcept; 669 670 /** 671 Set height. 672 */ 673 void setHeight(const T& height) noexcept; 674 675 /** 676 Set size using @a width and @a height. 677 */ 678 void setSize(const T& width, const T& height) noexcept; 679 680 /** 681 Set size. 682 */ 683 void setSize(const Size<T>& size) noexcept; 684 685 /** 686 Grow size by @a multiplier. 687 */ 688 void growBy(double multiplier) noexcept; 689 690 /** 691 Shrink size by @a divider. 692 */ 693 void shrinkBy(double divider) noexcept; 694 695 /** 696 Set rectangle using @a pos and @a size. 697 */ 698 void setRectangle(const Point<T>& pos, const Size<T>& size) noexcept; 699 700 /** 701 Set rectangle. 702 */ 703 void setRectangle(const Rectangle<T>& rect) noexcept; 704 705 /** 706 Check if this rectangle contains the point defined by @a X and @a Y. 707 */ 708 bool contains(const T& x, const T& y) const noexcept; 709 710 /** 711 Check if this rectangle contains the point @a pos. 712 */ 713 bool contains(const Point<T>& pos) const noexcept; 714 715 /** 716 Check if this rectangle contains X. 717 */ 718 bool containsX(const T& x) const noexcept; 719 720 /** 721 Check if this rectangle contains Y. 722 */ 723 bool containsY(const T& y) const noexcept; 724 725 /** 726 Draw this rectangle using the current OpenGL state. 727 */ 728 void draw(); 729 730 /** 731 Draw lines (outline of this rectangle) using the current OpenGL state. 732 */ 733 void drawOutline(); 734 735 Rectangle<T>& operator=(const Rectangle<T>& rect) noexcept; 736 Rectangle<T>& operator*=(double m) noexcept; 737 Rectangle<T>& operator/=(double d) noexcept; 738 bool operator==(const Rectangle<T>& size) const noexcept; 739 bool operator!=(const Rectangle<T>& size) const noexcept; 740 741 private: 742 Point<T> fPos; 743 Size<T> fSize; 744 745 /** @internal */ 746 void _draw(const bool outline); 747 }; 748 749 // ----------------------------------------------------------------------- 750 751 END_NAMESPACE_DGL 752 753 #endif // DGL_GEOMETRY_HPP_INCLUDED 754