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 void _draw(const bool outline); 486 }; 487 488 // ----------------------------------------------------------------------- 489 490 /** 491 DGL Triangle class. 492 493 This class describes a triangle, defined by 3 points. 494 */ 495 template<typename T> 496 class Triangle 497 { 498 public: 499 /** 500 Constructor for a null triangle. 501 */ 502 Triangle() noexcept; 503 504 /** 505 Constructor using custom X and Y values. 506 */ 507 Triangle(const T& x1, const T& y1, const T& x2, const T& y2, const T& x3, const T& y3) noexcept; 508 509 /** 510 Constructor using custom position values. 511 */ 512 Triangle(const Point<T>& pos1, const Point<T>& pos2, const Point<T>& pos3) noexcept; 513 514 /** 515 Constructor using another Triangle class values. 516 */ 517 Triangle(const Triangle<T>& tri) noexcept; 518 519 /** 520 Draw this triangle using the current OpenGL state. 521 */ 522 void draw(); 523 524 /** 525 Draw lines (outline of this triangle) using the current OpenGL state. 526 */ 527 void drawOutline(); 528 529 /** 530 Return true if triangle is null (all its points are equal). 531 An null triangle is also invalid. 532 */ 533 bool isNull() const noexcept; 534 535 /** 536 Return true if triangle is not null (one its points is different from the others). 537 A non-null triangle is still invalid if two of its points are equal. 538 */ 539 bool isNotNull() const noexcept; 540 541 /** 542 Return true if triangle is valid (all its points are different). 543 */ 544 bool isValid() const noexcept; 545 546 /** 547 Return true if triangle is invalid (one or two of its points are equal). 548 An invalid triangle might not be null under some circumstances. 549 */ 550 bool isInvalid() const noexcept; 551 552 Triangle<T>& operator=(const Triangle<T>& tri) noexcept; 553 bool operator==(const Triangle<T>& tri) const noexcept; 554 bool operator!=(const Triangle<T>& tri) const noexcept; 555 556 private: 557 Point<T> fPos1, fPos2, fPos3; 558 559 void _draw(const bool outline); 560 }; 561 562 // ----------------------------------------------------------------------- 563 564 /** 565 DGL Rectangle class. 566 567 This class describes a rectangle, defined by a starting point and a size. 568 */ 569 template<typename T> 570 class Rectangle 571 { 572 public: 573 /** 574 Constructor for a null rectangle. 575 */ 576 Rectangle() noexcept; 577 578 /** 579 Constructor using custom X, Y, width and height values. 580 */ 581 Rectangle(const T& x, const T& y, const T& width, const T& height) noexcept; 582 583 /** 584 Constructor using custom X, Y and size values. 585 */ 586 Rectangle(const T& x, const T& y, const Size<T>& size) noexcept; 587 588 /** 589 Constructor using custom pos, width and height values. 590 */ 591 Rectangle(const Point<T>& pos, const T& width, const T& height) noexcept; 592 593 /** 594 Constructor using custom position and size. 595 */ 596 Rectangle(const Point<T>& pos, const Size<T>& size) noexcept; 597 598 /** 599 Constructor using another Rectangle class values. 600 */ 601 Rectangle(const Rectangle<T>& rect) noexcept; 602 603 /** 604 Get X value. 605 */ 606 const T& getX() const noexcept; 607 608 /** 609 Get Y value. 610 */ 611 const T& getY() const noexcept; 612 613 /** 614 Get width. 615 */ 616 const T& getWidth() const noexcept; 617 618 /** 619 Get height. 620 */ 621 const T& getHeight() const noexcept; 622 623 /** 624 Get position. 625 */ 626 const Point<T>& getPos() const noexcept; 627 628 /** 629 Get size. 630 */ 631 const Size<T>& getSize() const noexcept; 632 633 /** 634 Set X value as @a x. 635 */ 636 void setX(const T& x) noexcept; 637 638 /** 639 Set Y value as @a y. 640 */ 641 void setY(const T& y) noexcept; 642 643 /** 644 Set X and Y values as @a x and @a y respectively. 645 */ 646 void setPos(const T& x, const T& y) noexcept; 647 648 /** 649 Set X and Y values according to @a pos. 650 */ 651 void setPos(const Point<T>& pos) noexcept; 652 653 /** 654 Move this rectangle by @a x and @a y values. 655 */ 656 void moveBy(const T& x, const T& y) noexcept; 657 658 /** 659 Move this rectangle by @a pos. 660 */ 661 void moveBy(const Point<T>& pos) noexcept; 662 663 /** 664 Set width. 665 */ 666 void setWidth(const T& width) noexcept; 667 668 /** 669 Set height. 670 */ 671 void setHeight(const T& height) noexcept; 672 673 /** 674 Set size using @a width and @a height. 675 */ 676 void setSize(const T& width, const T& height) noexcept; 677 678 /** 679 Set size. 680 */ 681 void setSize(const Size<T>& size) noexcept; 682 683 /** 684 Grow size by @a multiplier. 685 */ 686 void growBy(double multiplier) noexcept; 687 688 /** 689 Shrink size by @a divider. 690 */ 691 void shrinkBy(double divider) noexcept; 692 693 /** 694 Set rectangle using @a pos and @a size. 695 */ 696 void setRectangle(const Point<T>& pos, const Size<T>& size) noexcept; 697 698 /** 699 Set rectangle. 700 */ 701 void setRectangle(const Rectangle<T>& rect) noexcept; 702 703 /** 704 Check if this rectangle contains the point defined by @a X and @a Y. 705 */ 706 bool contains(const T& x, const T& y) const noexcept; 707 708 /** 709 Check if this rectangle contains the point @a pos. 710 */ 711 bool contains(const Point<T>& pos) const noexcept; 712 713 /** 714 Check if this rectangle contains X. 715 */ 716 bool containsX(const T& x) const noexcept; 717 718 /** 719 Check if this rectangle contains Y. 720 */ 721 bool containsY(const T& y) const noexcept; 722 723 /** 724 Draw this rectangle using the current OpenGL state. 725 */ 726 void draw(); 727 728 /** 729 Draw lines (outline of this rectangle) using the current OpenGL state. 730 */ 731 void drawOutline(); 732 733 Rectangle<T>& operator=(const Rectangle<T>& rect) noexcept; 734 Rectangle<T>& operator*=(double m) noexcept; 735 Rectangle<T>& operator/=(double d) noexcept; 736 bool operator==(const Rectangle<T>& size) const noexcept; 737 bool operator!=(const Rectangle<T>& size) const noexcept; 738 739 private: 740 Point<T> fPos; 741 Size<T> fSize; 742 743 void _draw(const bool outline); 744 }; 745 746 // ----------------------------------------------------------------------- 747 748 END_NAMESPACE_DGL 749 750 #endif // DGL_GEOMETRY_HPP_INCLUDED 751