Geometry.cpp (22638B)
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 #ifdef _MSC_VER 18 # pragma warning(disable:4661) /* instantiated template classes whose methods are defined elsewhere */ 19 #elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) 20 # pragma GCC diagnostic push 21 # pragma GCC diagnostic ignored "-Wconversion" 22 #endif 23 24 #include "../Geometry.hpp" 25 26 #include <cmath> 27 28 START_NAMESPACE_DGL 29 30 static const float M_2PIf = 3.14159265358979323846f*2.0f; 31 32 // ----------------------------------------------------------------------- 33 // Point 34 35 template<typename T> 36 Point<T>::Point() noexcept 37 : x(0), 38 y(0) {} 39 40 template<typename T> 41 Point<T>::Point(const T& x2, const T& y2) noexcept 42 : x(x2), 43 y(y2) {} 44 45 template<typename T> 46 Point<T>::Point(const Point<T>& pos) noexcept 47 : x(pos.x), 48 y(pos.y) {} 49 50 template<typename T> 51 const T& Point<T>::getX() const noexcept 52 { 53 return x; 54 } 55 56 template<typename T> 57 const T& Point<T>::getY() const noexcept 58 { 59 return y; 60 } 61 62 template<typename T> 63 void Point<T>::setX(const T& x2) noexcept 64 { 65 x = x2; 66 } 67 68 template<typename T> 69 void Point<T>::setY(const T& y2) noexcept 70 { 71 y = y2; 72 } 73 74 template<typename T> 75 void Point<T>::setPos(const T& x2, const T& y2) noexcept 76 { 77 x = x2; 78 y = y2; 79 } 80 81 template<typename T> 82 void Point<T>::setPos(const Point<T>& pos) noexcept 83 { 84 x = pos.x; 85 y = pos.y; 86 } 87 88 template<typename T> 89 void Point<T>::moveBy(const T& x2, const T& y2) noexcept 90 { 91 x = static_cast<T>(x+x2); 92 y = static_cast<T>(y+y2); 93 } 94 95 template<typename T> 96 void Point<T>::moveBy(const Point<T>& pos) noexcept 97 { 98 x = static_cast<T>(x+pos.x); 99 y = static_cast<T>(y+pos.y); 100 } 101 102 template<typename T> 103 bool Point<T>::isZero() const noexcept 104 { 105 return x == 0 && y == 0; 106 } 107 108 template<typename T> 109 bool Point<T>::isNotZero() const noexcept 110 { 111 return x != 0 || y != 0; 112 } 113 114 template<typename T> 115 Point<T> Point<T>::operator+(const Point<T>& pos) noexcept 116 { 117 return Point<T>(x+pos.x, y+pos.y); 118 } 119 120 template<typename T> 121 Point<T> Point<T>::operator-(const Point<T>& pos) noexcept 122 { 123 return Point<T>(x-pos.x, y-pos.y); 124 } 125 126 template<typename T> 127 Point<T>& Point<T>::operator=(const Point<T>& pos) noexcept 128 { 129 x = pos.x; 130 y = pos.y; 131 return *this; 132 } 133 134 template<typename T> 135 Point<T>& Point<T>::operator+=(const Point<T>& pos) noexcept 136 { 137 x = static_cast<T>(x+pos.x); 138 y = static_cast<T>(y+pos.y); 139 return *this; 140 } 141 142 template<typename T> 143 Point<T>& Point<T>::operator-=(const Point<T>& pos) noexcept 144 { 145 x = static_cast<T>(x-pos.x); 146 y = static_cast<T>(y-pos.y); 147 return *this; 148 } 149 150 template<typename T> 151 bool Point<T>::operator==(const Point<T>& pos) const noexcept 152 { 153 return (x == pos.x && y == pos.y); 154 } 155 156 template<typename T> 157 bool Point<T>::operator!=(const Point<T>& pos) const noexcept 158 { 159 return (x != pos.x || y != pos.y); 160 } 161 162 // ----------------------------------------------------------------------- 163 // Size 164 165 template<typename T> 166 Size<T>::Size() noexcept 167 : fWidth(0), 168 fHeight(0) {} 169 170 template<typename T> 171 Size<T>::Size(const T& width, const T& height) noexcept 172 : fWidth(width), 173 fHeight(height) {} 174 175 template<typename T> 176 Size<T>::Size(const Size<T>& size) noexcept 177 : fWidth(size.fWidth), 178 fHeight(size.fHeight) {} 179 180 template<typename T> 181 const T& Size<T>::getWidth() const noexcept 182 { 183 return fWidth; 184 } 185 186 template<typename T> 187 const T& Size<T>::getHeight() const noexcept 188 { 189 return fHeight; 190 } 191 192 template<typename T> 193 void Size<T>::setWidth(const T& width) noexcept 194 { 195 fWidth = width; 196 } 197 198 template<typename T> 199 void Size<T>::setHeight(const T& height) noexcept 200 { 201 fHeight = height; 202 } 203 204 template<typename T> 205 void Size<T>::setSize(const T& width, const T& height) noexcept 206 { 207 fWidth = width; 208 fHeight = height; 209 } 210 211 template<typename T> 212 void Size<T>::setSize(const Size<T>& size) noexcept 213 { 214 fWidth = size.fWidth; 215 fHeight = size.fHeight; 216 } 217 218 template<typename T> 219 void Size<T>::growBy(double multiplier) noexcept 220 { 221 fWidth = static_cast<T>(static_cast<double>(fWidth)*multiplier); 222 fHeight = static_cast<T>(static_cast<double>(fHeight)*multiplier); 223 } 224 225 template<typename T> 226 void Size<T>::shrinkBy(double divider) noexcept 227 { 228 fWidth = static_cast<T>(static_cast<double>(fWidth)/divider); 229 fHeight = static_cast<T>(static_cast<double>(fHeight)/divider); 230 } 231 232 template<typename T> 233 bool Size<T>::isNull() const noexcept 234 { 235 return fWidth == 0 && fHeight == 0; 236 } 237 238 template<typename T> 239 bool Size<T>::isNotNull() const noexcept 240 { 241 return fWidth != 0 || fHeight != 0; 242 } 243 244 template<typename T> 245 bool Size<T>::isValid() const noexcept 246 { 247 return fWidth > 0 && fHeight > 0; 248 } 249 250 template<typename T> 251 bool Size<T>::isInvalid() const noexcept 252 { 253 return fWidth <= 0 || fHeight <= 0; 254 } 255 256 template<typename T> 257 Size<int> Size<T>::toInt() const noexcept 258 { 259 return Size<int>(static_cast<int>(fWidth), 260 static_cast<int>(fHeight)); 261 } 262 263 template<> 264 Size<int> Size<double>::toInt() const noexcept 265 { 266 return Size<int>(static_cast<int>(fWidth + 0.5), 267 static_cast<int>(fHeight + 0.5)); 268 } 269 270 template<> 271 Size<int> Size<float>::toInt() const noexcept 272 { 273 return Size<int>(static_cast<int>(fWidth + 0.5f), 274 static_cast<int>(fHeight + 0.5f)); 275 } 276 277 template<typename T> 278 Size<T> Size<T>::operator+(const Size<T>& size) noexcept 279 { 280 return Size<T>(fWidth+size.fWidth, fHeight+size.fHeight); 281 } 282 283 template<typename T> 284 Size<T> Size<T>::operator-(const Size<T>& size) noexcept 285 { 286 return Size<T>(fWidth-size.fWidth, fHeight-size.fHeight); 287 } 288 289 template<typename T> 290 Size<T>& Size<T>::operator=(const Size<T>& size) noexcept 291 { 292 fWidth = size.fWidth; 293 fHeight = size.fHeight; 294 return *this; 295 } 296 297 template<typename T> 298 Size<T>& Size<T>::operator+=(const Size<T>& size) noexcept 299 { 300 fWidth = static_cast<T>(fWidth+size.fWidth); 301 fHeight = static_cast<T>(fHeight+size.fHeight); 302 return *this; 303 } 304 305 template<typename T> 306 Size<T>& Size<T>::operator-=(const Size<T>& size) noexcept 307 { 308 fWidth = static_cast<T>(fWidth-size.fWidth); 309 fHeight = static_cast<T>(fHeight-size.fHeight); 310 return *this; 311 } 312 313 template<typename T> 314 Size<T>& Size<T>::operator*=(double m) noexcept 315 { 316 fWidth = static_cast<T>(static_cast<double>(fWidth)*m); 317 fHeight = static_cast<T>(static_cast<double>(fHeight)*m); 318 return *this; 319 } 320 321 template<typename T> 322 Size<T>& Size<T>::operator/=(double d) noexcept 323 { 324 fWidth = static_cast<T>(static_cast<double>(fWidth)/d); 325 fHeight = static_cast<T>(static_cast<double>(fHeight)/d); 326 return *this; 327 } 328 329 template<typename T> 330 Size<T> Size<T>::operator*(const double m) const noexcept 331 { 332 Size<T> size(fWidth, fHeight); 333 size *= m; 334 return size; 335 } 336 337 template<typename T> 338 Size<T> Size<T>::operator/(const double m) const noexcept 339 { 340 Size<T> size(fWidth, fHeight); 341 size /= m; 342 return size; 343 } 344 345 template<typename T> 346 bool Size<T>::operator==(const Size<T>& size) const noexcept 347 { 348 return (fWidth == size.fWidth && fHeight == size.fHeight); 349 } 350 351 template<typename T> 352 bool Size<T>::operator!=(const Size<T>& size) const noexcept 353 { 354 return (fWidth != size.fWidth || fHeight != size.fHeight); 355 } 356 357 // ----------------------------------------------------------------------- 358 // Line 359 360 template<typename T> 361 Line<T>::Line() noexcept 362 : posStart(0, 0), 363 posEnd(0, 0) {} 364 365 template<typename T> 366 Line<T>::Line(const T& startX, const T& startY, const T& endX, const T& endY) noexcept 367 : posStart(startX, startY), 368 posEnd(endX, endY) {} 369 370 template<typename T> 371 Line<T>::Line(const T& startX, const T& startY, const Point<T>& endPos) noexcept 372 : posStart(startX, startY), 373 posEnd(endPos) {} 374 375 template<typename T> 376 Line<T>::Line(const Point<T>& startPos, const T& endX, const T& endY) noexcept 377 : posStart(startPos), 378 posEnd(endX, endY) {} 379 380 template<typename T> 381 Line<T>::Line(const Point<T>& startPos, const Point<T>& endPos) noexcept 382 : posStart(startPos), 383 posEnd(endPos) {} 384 385 template<typename T> 386 Line<T>::Line(const Line<T>& line) noexcept 387 : posStart(line.posStart), 388 posEnd(line.posEnd) {} 389 390 template<typename T> 391 const T& Line<T>::getStartX() const noexcept 392 { 393 return posStart.x; 394 } 395 396 template<typename T> 397 const T& Line<T>::getStartY() const noexcept 398 { 399 return posStart.y; 400 } 401 402 template<typename T> 403 const T& Line<T>::getEndX() const noexcept 404 { 405 return posEnd.x; 406 } 407 408 template<typename T> 409 const T& Line<T>::getEndY() const noexcept 410 { 411 return posEnd.y; 412 } 413 414 template<typename T> 415 const Point<T>& Line<T>::getStartPos() const noexcept 416 { 417 return posStart; 418 } 419 420 template<typename T> 421 const Point<T>& Line<T>::getEndPos() const noexcept 422 { 423 return posEnd; 424 } 425 426 template<typename T> 427 void Line<T>::setStartX(const T& x) noexcept 428 { 429 posStart.x = x; 430 } 431 432 template<typename T> 433 void Line<T>::setStartY(const T& y) noexcept 434 { 435 posStart.y = y; 436 } 437 438 template<typename T> 439 void Line<T>::setStartPos(const T& x, const T& y) noexcept 440 { 441 posStart = Point<T>(x, y); 442 } 443 444 template<typename T> 445 void Line<T>::setStartPos(const Point<T>& pos) noexcept 446 { 447 posStart = pos; 448 } 449 450 template<typename T> 451 void Line<T>::setEndX(const T& x) noexcept 452 { 453 posEnd.x = x; 454 } 455 456 template<typename T> 457 void Line<T>::setEndY(const T& y) noexcept 458 { 459 posEnd.y = y; 460 } 461 462 template<typename T> 463 void Line<T>::setEndPos(const T& x, const T& y) noexcept 464 { 465 posEnd = Point<T>(x, y); 466 } 467 468 template<typename T> 469 void Line<T>::setEndPos(const Point<T>& pos) noexcept 470 { 471 posEnd = pos; 472 } 473 474 template<typename T> 475 void Line<T>::moveBy(const T& x, const T& y) noexcept 476 { 477 posStart.moveBy(x, y); 478 posEnd.moveBy(x, y); 479 } 480 481 template<typename T> 482 void Line<T>::moveBy(const Point<T>& pos) noexcept 483 { 484 posStart.moveBy(pos); 485 posEnd.moveBy(pos); 486 } 487 488 template<typename T> 489 bool Line<T>::isNull() const noexcept 490 { 491 return posStart == posEnd; 492 } 493 494 template<typename T> 495 bool Line<T>::isNotNull() const noexcept 496 { 497 return posStart != posEnd; 498 } 499 500 template<typename T> 501 Line<T>& Line<T>::operator=(const Line<T>& line) noexcept 502 { 503 posStart = line.posStart; 504 posEnd = line.posEnd; 505 return *this; 506 } 507 508 template<typename T> 509 bool Line<T>::operator==(const Line<T>& line) const noexcept 510 { 511 return (posStart == line.posStart && posEnd == line.posEnd); 512 } 513 514 template<typename T> 515 bool Line<T>::operator!=(const Line<T>& line) const noexcept 516 { 517 return (posStart != line.posStart || posEnd != line.posEnd); 518 } 519 520 // ----------------------------------------------------------------------- 521 // Circle 522 523 template<typename T> 524 Circle<T>::Circle() noexcept 525 : fPos(0, 0), 526 fSize(0.0f), 527 fNumSegments(0), 528 fTheta(0.0f), 529 fCos(0.0f), 530 fSin(0.0f) {} 531 532 template<typename T> 533 Circle<T>::Circle(const T& x, const T& y, const float size, const uint numSegments) 534 : fPos(x, y), 535 fSize(size), 536 fNumSegments(numSegments >= 3 ? numSegments : 3), 537 fTheta(M_2PIf / static_cast<float>(fNumSegments)), 538 fCos(std::cos(fTheta)), 539 fSin(std::sin(fTheta)) 540 { 541 DISTRHO_SAFE_ASSERT(fSize > 0.0f); 542 } 543 544 template<typename T> 545 Circle<T>::Circle(const Point<T>& pos, const float size, const uint numSegments) 546 : fPos(pos), 547 fSize(size), 548 fNumSegments(numSegments >= 3 ? numSegments : 3), 549 fTheta(M_2PIf / static_cast<float>(fNumSegments)), 550 fCos(std::cos(fTheta)), 551 fSin(std::sin(fTheta)) 552 { 553 DISTRHO_SAFE_ASSERT(fSize > 0.0f); 554 } 555 556 template<typename T> 557 Circle<T>::Circle(const Circle<T>& cir) noexcept 558 : fPos(cir.fPos), 559 fSize(cir.fSize), 560 fNumSegments(cir.fNumSegments), 561 fTheta(cir.fTheta), 562 fCos(cir.fCos), 563 fSin(cir.fSin) 564 { 565 DISTRHO_SAFE_ASSERT(fSize > 0.0f); 566 } 567 568 template<typename T> 569 const T& Circle<T>::getX() const noexcept 570 { 571 return fPos.x; 572 } 573 574 template<typename T> 575 const T& Circle<T>::getY() const noexcept 576 { 577 return fPos.y; 578 } 579 580 template<typename T> 581 const Point<T>& Circle<T>::getPos() const noexcept 582 { 583 return fPos; 584 } 585 586 template<typename T> 587 void Circle<T>::setX(const T& x) noexcept 588 { 589 fPos.x = x; 590 } 591 592 template<typename T> 593 void Circle<T>::setY(const T& y) noexcept 594 { 595 fPos.y = y; 596 } 597 598 template<typename T> 599 void Circle<T>::setPos(const T& x, const T& y) noexcept 600 { 601 fPos.x = x; 602 fPos.y = y; 603 } 604 605 template<typename T> 606 void Circle<T>::setPos(const Point<T>& pos) noexcept 607 { 608 fPos = pos; 609 } 610 611 template<typename T> 612 float Circle<T>::getSize() const noexcept 613 { 614 return fSize; 615 } 616 617 template<typename T> 618 void Circle<T>::setSize(const float size) noexcept 619 { 620 DISTRHO_SAFE_ASSERT_RETURN(size > 0.0f,); 621 622 fSize = size; 623 } 624 625 template<typename T> 626 uint Circle<T>::getNumSegments() const noexcept 627 { 628 return fNumSegments; 629 } 630 631 template<typename T> 632 void Circle<T>::setNumSegments(const uint num) 633 { 634 DISTRHO_SAFE_ASSERT_RETURN(num >= 3,); 635 636 if (fNumSegments == num) 637 return; 638 639 fNumSegments = num; 640 641 fTheta = M_2PIf / static_cast<float>(fNumSegments); 642 fCos = std::cos(fTheta); 643 fSin = std::sin(fTheta); 644 } 645 646 template<typename T> 647 Circle<T>& Circle<T>::operator=(const Circle<T>& cir) noexcept 648 { 649 fPos = cir.fPos; 650 fSize = cir.fSize; 651 fTheta = cir.fTheta; 652 fCos = cir.fCos; 653 fSin = cir.fSin; 654 fNumSegments = cir.fNumSegments; 655 return *this; 656 } 657 658 template<typename T> 659 bool Circle<T>::operator==(const Circle<T>& cir) const noexcept 660 { 661 return (fPos == cir.fPos && d_isEqual(fSize, cir.fSize) && fNumSegments == cir.fNumSegments); 662 } 663 664 template<typename T> 665 bool Circle<T>::operator!=(const Circle<T>& cir) const noexcept 666 { 667 return (fPos != cir.fPos || d_isNotEqual(fSize, cir.fSize) || fNumSegments != cir.fNumSegments); 668 } 669 670 // ----------------------------------------------------------------------- 671 // Triangle 672 673 template<typename T> 674 Triangle<T>::Triangle() noexcept 675 : pos1(0, 0), 676 pos2(0, 0), 677 pos3(0, 0) {} 678 679 template<typename T> 680 Triangle<T>::Triangle(const T& x1, const T& y1, const T& x2, const T& y2, const T& x3, const T& y3) noexcept 681 : pos1(x1, y1), 682 pos2(x2, y2), 683 pos3(x3, y3) {} 684 685 template<typename T> 686 Triangle<T>::Triangle(const Point<T>& p1, const Point<T>& p2, const Point<T>& p3) noexcept 687 : pos1(p1), 688 pos2(p2), 689 pos3(p3) {} 690 691 template<typename T> 692 Triangle<T>::Triangle(const Triangle<T>& tri) noexcept 693 : pos1(tri.pos1), 694 pos2(tri.pos2), 695 pos3(tri.pos3) {} 696 697 template<typename T> 698 bool Triangle<T>::isNull() const noexcept 699 { 700 return pos1 == pos2 && pos1 == pos3; 701 } 702 703 template<typename T> 704 bool Triangle<T>::isNotNull() const noexcept 705 { 706 return pos1 != pos2 || pos1 != pos3; 707 } 708 709 template<typename T> 710 bool Triangle<T>::isValid() const noexcept 711 { 712 return pos1 != pos2 && pos1 != pos3; 713 } 714 715 template<typename T> 716 bool Triangle<T>::isInvalid() const noexcept 717 { 718 return pos1 == pos2 || pos1 == pos3; 719 } 720 721 template<typename T> 722 Triangle<T>& Triangle<T>::operator=(const Triangle<T>& tri) noexcept 723 { 724 pos1 = tri.pos1; 725 pos2 = tri.pos2; 726 pos3 = tri.pos3; 727 return *this; 728 } 729 730 template<typename T> 731 bool Triangle<T>::operator==(const Triangle<T>& tri) const noexcept 732 { 733 return (pos1 == tri.pos1 && pos2 == tri.pos2 && pos3 == tri.pos3); 734 } 735 736 template<typename T> 737 bool Triangle<T>::operator!=(const Triangle<T>& tri) const noexcept 738 { 739 return (pos1 != tri.pos1 || pos2 != tri.pos2 || pos3 != tri.pos3); 740 } 741 742 // ----------------------------------------------------------------------- 743 // Rectangle 744 745 template<typename T> 746 Rectangle<T>::Rectangle() noexcept 747 : pos(0, 0), 748 size(0, 0) {} 749 750 template<typename T> 751 Rectangle<T>::Rectangle(const T& x, const T& y, const T& w, const T& h) noexcept 752 : pos(x, y), 753 size(w, h) {} 754 755 template<typename T> 756 Rectangle<T>::Rectangle(const T& x, const T& y, const Size<T>& s) noexcept 757 : pos(x, y), 758 size(s) {} 759 760 template<typename T> 761 Rectangle<T>::Rectangle(const Point<T>& p, const T& w, const T& h) noexcept 762 : pos(p), 763 size(w, h) {} 764 765 template<typename T> 766 Rectangle<T>::Rectangle(const Point<T>& p, const Size<T>& s) noexcept 767 : pos(p), 768 size(s) {} 769 770 template<typename T> 771 Rectangle<T>::Rectangle(const Rectangle<T>& rect) noexcept 772 : pos(rect.pos), 773 size(rect.size) {} 774 775 template<typename T> 776 const T& Rectangle<T>::getX() const noexcept 777 { 778 return pos.x; 779 } 780 781 template<typename T> 782 const T& Rectangle<T>::getY() const noexcept 783 { 784 return pos.y; 785 } 786 787 template<typename T> 788 const T& Rectangle<T>::getWidth() const noexcept 789 { 790 return size.fWidth; 791 } 792 793 template<typename T> 794 const T& Rectangle<T>::getHeight() const noexcept 795 { 796 return size.fHeight; 797 } 798 799 template<typename T> 800 const Point<T>& Rectangle<T>::getPos() const noexcept 801 { 802 return pos; 803 } 804 805 template<typename T> 806 const Size<T>& Rectangle<T>::getSize() const noexcept 807 { 808 return size; 809 } 810 811 template<typename T> 812 void Rectangle<T>::setX(const T& x) noexcept 813 { 814 pos.x = x; 815 } 816 817 template<typename T> 818 void Rectangle<T>::setY(const T& y) noexcept 819 { 820 pos.y = y; 821 } 822 823 template<typename T> 824 void Rectangle<T>::setPos(const T& x, const T& y) noexcept 825 { 826 pos.x = x; 827 pos.y = y; 828 } 829 830 template<typename T> 831 void Rectangle<T>::setPos(const Point<T>& pos2) noexcept 832 { 833 pos = pos2; 834 } 835 836 template<typename T> 837 void Rectangle<T>::moveBy(const T& x, const T& y) noexcept 838 { 839 pos.moveBy(x, y); 840 } 841 842 template<typename T> 843 void Rectangle<T>::moveBy(const Point<T>& pos2) noexcept 844 { 845 pos.moveBy(pos2); 846 } 847 848 template<typename T> 849 void Rectangle<T>::setWidth(const T& width) noexcept 850 { 851 size.fWidth = width; 852 } 853 854 template<typename T> 855 void Rectangle<T>::setHeight(const T& height) noexcept 856 { 857 size.fHeight = height; 858 } 859 860 template<typename T> 861 void Rectangle<T>::setSize(const T& width, const T& height) noexcept 862 { 863 size.fWidth = width; 864 size.fHeight = height; 865 } 866 867 template<typename T> 868 void Rectangle<T>::setSize(const Size<T>& size2) noexcept 869 { 870 size = size2; 871 } 872 873 template<typename T> 874 void Rectangle<T>::growBy(double multiplier) noexcept 875 { 876 size.growBy(multiplier); 877 } 878 879 template<typename T> 880 void Rectangle<T>::shrinkBy(double divider) noexcept 881 { 882 size.shrinkBy(divider); 883 } 884 885 template<typename T> 886 void Rectangle<T>::setRectangle(const Point<T>& pos2, const Size<T>& size2) noexcept 887 { 888 pos = pos2; 889 size = size2; 890 } 891 892 template<typename T> 893 void Rectangle<T>::setRectangle(const Rectangle<T>& rect) noexcept 894 { 895 pos = rect.pos; 896 size = rect.size; 897 } 898 899 template<typename T> 900 bool Rectangle<T>::contains(const T& x, const T& y) const noexcept 901 { 902 return (x >= pos.x && y >= pos.y && x <= pos.x+size.fWidth && y <= pos.y+size.fHeight); 903 } 904 905 template<typename T> 906 bool Rectangle<T>::contains(const Point<T>& p) const noexcept 907 { 908 return contains(p.x, p.y); 909 } 910 911 template<typename T> 912 template<typename T2> 913 bool Rectangle<T>::contains(const Point<T2>& p) const noexcept 914 { 915 return (p.x >= pos.x && p.y >= pos.y && p.x <= pos.x+size.fWidth && p.y <= pos.y+size.fHeight); 916 } 917 918 template<> template<> 919 bool Rectangle<int>::contains(const Point<double>& p) const noexcept 920 { 921 return (p.x >= pos.x && p.y >= pos.y && p.x <= pos.x+size.fWidth && p.y <= pos.y+size.fHeight); 922 } 923 924 template<> template<> 925 bool Rectangle<uint>::contains(const Point<double>& p) const noexcept 926 { 927 return (p.x >= pos.x && p.y >= pos.y && p.x <= pos.x+size.fWidth && p.y <= pos.y+size.fHeight); 928 } 929 930 template<typename T> 931 bool Rectangle<T>::containsAfterScaling(const Point<T>& p, const double scaling) const noexcept 932 { 933 return (p.x >= pos.x && p.y >= pos.y && p.x/scaling <= pos.x+size.fWidth && p.y/scaling <= pos.y+size.fHeight); 934 } 935 936 template<typename T> 937 bool Rectangle<T>::containsX(const T& x) const noexcept 938 { 939 return (x >= pos.x && x <= pos.x + size.fWidth); 940 } 941 942 template<typename T> 943 bool Rectangle<T>::containsY(const T& y) const noexcept 944 { 945 return (y >= pos.y && y <= pos.y + size.fHeight); 946 } 947 948 template<typename T> 949 bool Rectangle<T>::isNull() const noexcept 950 { 951 return size.isNull(); 952 } 953 954 template<typename T> 955 bool Rectangle<T>::isNotNull() const noexcept 956 { 957 return size.isNotNull(); 958 } 959 960 template<typename T> 961 bool Rectangle<T>::isValid() const noexcept 962 { 963 return size.isValid(); 964 } 965 966 template<typename T> 967 bool Rectangle<T>::isInvalid() const noexcept 968 { 969 return size.isInvalid(); 970 } 971 972 template<typename T> 973 Rectangle<T>& Rectangle<T>::operator=(const Rectangle<T>& rect) noexcept 974 { 975 pos = rect.pos; 976 size = rect.size; 977 return *this; 978 } 979 980 template<typename T> 981 Rectangle<T>& Rectangle<T>::operator*=(double m) noexcept 982 { 983 size *= m; 984 return *this; 985 } 986 987 template<typename T> 988 Rectangle<T>& Rectangle<T>::operator/=(double d) noexcept 989 { 990 size /= d; 991 return *this; 992 } 993 994 template<typename T> 995 bool Rectangle<T>::operator==(const Rectangle<T>& rect) const noexcept 996 { 997 return (pos == rect.pos && size == rect.size); 998 } 999 1000 template<typename T> 1001 bool Rectangle<T>::operator!=(const Rectangle<T>& rect) const noexcept 1002 { 1003 return (pos != rect.pos || size != rect.size); 1004 } 1005 1006 // ----------------------------------------------------------------------- 1007 // Possible template data types 1008 1009 template class Point<double>; 1010 template class Point<float>; 1011 template class Point<int>; 1012 template class Point<uint>; 1013 template class Point<short>; 1014 template class Point<ushort>; 1015 1016 template class Size<double>; 1017 template class Size<float>; 1018 template class Size<int>; 1019 template class Size<uint>; 1020 template class Size<short>; 1021 template class Size<ushort>; 1022 1023 template class Line<double>; 1024 template class Line<float>; 1025 template class Line<int>; 1026 template class Line<uint>; 1027 template class Line<short>; 1028 template class Line<ushort>; 1029 1030 template class Circle<double>; 1031 template class Circle<float>; 1032 template class Circle<int>; 1033 template class Circle<uint>; 1034 template class Circle<short>; 1035 template class Circle<ushort>; 1036 1037 template class Triangle<double>; 1038 template class Triangle<float>; 1039 template class Triangle<int>; 1040 template class Triangle<uint>; 1041 template class Triangle<short>; 1042 template class Triangle<ushort>; 1043 1044 template class Rectangle<double>; 1045 template class Rectangle<float>; 1046 template class Rectangle<int>; 1047 template class Rectangle<uint>; 1048 template class Rectangle<short>; 1049 template class Rectangle<ushort>; 1050 1051 // ----------------------------------------------------------------------- 1052 1053 END_NAMESPACE_DGL