Commit d7439bd2d4c23936c356370c9fbbf4524c10ba9a
Committed by
Jürgen Knödlseder
1 parent
a72a502b
Added transform_to_global() method. Splitted contains(GSkyDir) method into sub m…
…ethod contains_local(GSkyDir). Implemented contains(GSkyRegion) for rectangle.
Showing
3 changed files
with
102 additions
and
13 deletions
include/GSkyRegionRect.hpp
| ... | ... | @@ -89,11 +89,13 @@ public: |
| 89 | 89 | void read(const std::string& line); |
| 90 | 90 | std::string write(void) const; |
| 91 | 91 | bool contains(const GSkyDir& dir) const; |
| 92 | + bool contains_local(const GSkyDir& locdir) const; | |
| 92 | 93 | bool contains(const GSkyRegion& reg) const; |
| 93 | 94 | bool overlaps(const GSkyRegion& reg) const; |
| 94 | 95 | std::string print(const GChatter& chatter = NORMAL) const; |
| 95 | 96 | |
| 96 | 97 | GSkyDir transform_to_local(const GSkyDir& skydir) const; |
| 98 | + GSkyDir transform_to_global(const GSkyDir& locdir) const; | |
| 97 | 99 | |
| 98 | 100 | protected: |
| 99 | 101 | // Protected methods | ... | ... |
pyext/GSkyRegionRect.i
| ... | ... | @@ -70,10 +70,12 @@ public: |
| 70 | 70 | void read(const std::string& line); |
| 71 | 71 | std::string write(void) const; |
| 72 | 72 | bool contains(const GSkyDir& dir) const; |
| 73 | + bool contains_local(const GSkyDir& locdir) const; | |
| 73 | 74 | bool contains(const GSkyRegion& reg) const; |
| 74 | 75 | bool overlaps(const GSkyRegion& reg) const; |
| 75 | 76 | |
| 76 | 77 | GSkyDir transform_to_local(const GSkyDir& skydir) const; |
| 78 | + GSkyDir transform_to_global(const GSkyDir& localdir) const; | |
| 77 | 79 | }; |
| 78 | 80 | |
| 79 | 81 | ... | ... |
src/sky/GSkyRegionRect.cpp
| ... | ... | @@ -557,17 +557,35 @@ std::string GSkyRegionRect::print(const GChatter& chatter) const |
| 557 | 557 | ***************************************************************************/ |
| 558 | 558 | bool GSkyRegionRect::contains(const GSkyDir& dir) const |
| 559 | 559 | { |
| 560 | + // Compute sky direction in local coordinate system | |
| 561 | + GSkyDir locdir = transform_to_local(dir); | |
| 562 | + | |
| 563 | + // Check containment using local coordinate system | |
| 564 | + bool dir_is_in = contains_local(locdir); | |
| 565 | + | |
| 566 | + // Return bool | |
| 567 | + return dir_is_in; | |
| 568 | +} | |
| 569 | + | |
| 570 | + | |
| 571 | +/***********************************************************************//** | |
| 572 | + * @brief Checks if local direction lies within region | |
| 573 | + * | |
| 574 | + * @param[in] dir Direction in local coordinate system. | |
| 575 | + * | |
| 576 | + * A local direction lies within a region when its distance to the region | |
| 577 | + * centre is not larger than the region extension in both axes directions. | |
| 578 | + ***************************************************************************/ | |
| 579 | +bool GSkyRegionRect::contains_local(const GSkyDir& locdir) const | |
| 580 | +{ | |
| 560 | 581 | // Initialise return value |
| 561 | 582 | bool dir_is_in = false; |
| 562 | 583 | |
| 563 | - // Compute sky direction in local coordinate system | |
| 564 | - GSkyDir local_dir = transform_to_local(dir); | |
| 565 | - | |
| 566 | 584 | // Check containment: declination axis |
| 567 | - if (std::abs(local_dir.dec_deg()) <= m_halfheight) { | |
| 585 | + if (std::abs(locdir.dec_deg()) <= m_halfheight) { | |
| 568 | 586 | |
| 569 | 587 | // Check containment: right ascension axis |
| 570 | - if (std::abs(local_dir.ra_deg()) <= m_halfwidth) { | |
| 588 | + if (std::abs(locdir.ra_deg()) <= m_halfwidth) { | |
| 571 | 589 | |
| 572 | 590 | // Sky direction is inside the rectangle |
| 573 | 591 | dir_is_in = true; |
| ... | ... | @@ -578,13 +596,14 @@ bool GSkyRegionRect::contains(const GSkyDir& dir) const |
| 578 | 596 | return dir_is_in; |
| 579 | 597 | } |
| 580 | 598 | |
| 599 | + | |
| 581 | 600 | /***********************************************************************//** |
| 582 | 601 | * @brief Checks if region is fully contained within this region |
| 583 | 602 | * |
| 584 | 603 | * @param[in] reg Sky region. |
| 585 | 604 | * |
| 586 | 605 | * @exception GException::feature_not_implemented |
| 587 | - * Regions differ in type. | |
| 606 | + * Not all region types supported currently. | |
| 588 | 607 | ***************************************************************************/ |
| 589 | 608 | bool GSkyRegionRect::contains(const GSkyRegion& reg) const |
| 590 | 609 | { |
| ... | ... | @@ -616,10 +635,46 @@ bool GSkyRegionRect::contains(const GSkyRegion& reg) const |
| 616 | 635 | } |
| 617 | 636 | } // Region was of type "Circle" |
| 618 | 637 | |
| 638 | + // If other region is rectangle use a simple way to calculate | |
| 639 | + else if (reg.type() == "Rect") { | |
| 640 | + | |
| 641 | + // Create rectangular region from reg | |
| 642 | + const GSkyRegionRect* regrect = | |
| 643 | + dynamic_cast<const GSkyRegionRect*>(®); | |
| 644 | + | |
| 645 | + // Loop over the four corners of the rectangle :regrect: | |
| 646 | + for(int icorner=0; icorner<4; ++icorner) { | |
| 647 | + | |
| 648 | + // Compute the offset to the corners | |
| 649 | + double dx = 0.5*regrect->width() * (1 - 2*int(icorner < 2)); | |
| 650 | + double dy = 0.5*regrect->height() * (1 - 2*int(icorner % 2)); | |
| 651 | + | |
| 652 | + // Define local corner sky direction | |
| 653 | + GSkyDir corner; | |
| 654 | + corner.radec_deg(dx,dy); | |
| 655 | + | |
| 656 | + // Transform to global sky direction | |
| 657 | + corner = regrect->transform_to_global(corner); | |
| 658 | + | |
| 659 | + // Check corner containment | |
| 660 | + if (!contains(corner)) { | |
| 661 | + break; | |
| 662 | + } | |
| 663 | + // Did we arrive at the last corner? | |
| 664 | + else if (icorner==3) { | |
| 665 | + | |
| 666 | + // As we reached this point, the three prior corners were inside | |
| 667 | + // and the last corner now is also inside: | |
| 668 | + // Rectangle is fully inside | |
| 669 | + is_fully_inside = true; | |
| 670 | + } | |
| 671 | + } // Looped over the four corners | |
| 672 | + } // Region was of type "Rect" | |
| 673 | + | |
| 619 | 674 | // ... otherwise throw an exception |
| 620 | 675 | else { |
| 621 | 676 | throw GException::feature_not_implemented(G_CONTAINS, |
| 622 | - "Cannot compare rectangular region with other than circle yet"); | |
| 677 | + "Cannot compare rectangular region with other than circle yet."); | |
| 623 | 678 | } |
| 624 | 679 | |
| 625 | 680 | // Return value |
| ... | ... | @@ -634,6 +689,7 @@ bool GSkyRegionRect::contains(const GSkyRegion& reg) const |
| 634 | 689 | * |
| 635 | 690 | * @exception GException::feature_not_implemented |
| 636 | 691 | * Regions differ in type. |
| 692 | + * | |
| 637 | 693 | ***************************************************************************/ |
| 638 | 694 | bool GSkyRegionRect::overlaps(const GSkyRegion& reg) const |
| 639 | 695 | { |
| ... | ... | @@ -668,7 +724,7 @@ bool GSkyRegionRect::overlaps(const GSkyRegion& reg) const |
| 668 | 724 | // ... otherwise throw an exception |
| 669 | 725 | else { |
| 670 | 726 | throw GException::feature_not_implemented(G_OVERLAPS, |
| 671 | - "Cannot compare rectangular region with other than circle yet"); | |
| 727 | + "Cannot compare rectangular region with other than circle yet."); | |
| 672 | 728 | } |
| 673 | 729 | |
| 674 | 730 | // Return value |
| ... | ... | @@ -677,13 +733,13 @@ bool GSkyRegionRect::overlaps(const GSkyRegion& reg) const |
| 677 | 733 | |
| 678 | 734 | |
| 679 | 735 | /***********************************************************************//** |
| 680 | - * @brief Transform a sky direction to the local coordinate system. | |
| 736 | + * @brief Transform a sky direction to the local cartesian coordinate system. | |
| 681 | 737 | * |
| 682 | 738 | * @param[in] skydir Sky direction in global coordinate system. |
| 683 | - * @return Sky direction in local region object coordinates. | |
| 739 | + * @return Sky direction in local cartesian region object coordinates. | |
| 684 | 740 | * |
| 685 | - * Transform the sky direction :skydir: to the local coordinate system. The | |
| 686 | - * origin of the local coordinate system is fixed to the center of the | |
| 741 | + * Transform the sky direction :skydir: to the local cartesian coordinate system. | |
| 742 | + * The origin of the local coordinate system is fixed to the center of the | |
| 687 | 743 | * rectangle and aligned in +ra (width) and +dec (height). |
| 688 | 744 | ***************************************************************************/ |
| 689 | 745 | GSkyDir GSkyRegionRect::transform_to_local(const GSkyDir& skydir) const |
| ... | ... | @@ -692,7 +748,7 @@ GSkyDir GSkyRegionRect::transform_to_local(const GSkyDir& skydir) const |
| 692 | 748 | double dx = skydir.ra() - m_centre.ra(); |
| 693 | 749 | double dy = skydir.dec() - m_centre.dec(); |
| 694 | 750 | |
| 695 | - // Correct for spherical coordinate system (global dx -> local dx) | |
| 751 | + // Correction for spherical coordinate system | |
| 696 | 752 | dx *= std::cos(skydir.dec()); |
| 697 | 753 | |
| 698 | 754 | // Rotate with neg. PA |
| ... | ... | @@ -708,6 +764,35 @@ GSkyDir GSkyRegionRect::transform_to_local(const GSkyDir& skydir) const |
| 708 | 764 | } |
| 709 | 765 | |
| 710 | 766 | |
| 767 | +/***********************************************************************//** | |
| 768 | + * @brief Transform a local coordinate to the global coordinate system. | |
| 769 | + * | |
| 770 | + * @param[in] locdir Direction in local coordinate system. | |
| 771 | + * @return Sky direction in global coordinate system. | |
| 772 | + * | |
| 773 | + * Transform the local direction :locdir: to the global coordinate system. | |
| 774 | + * The origin of the local coordinate system is fixed to the center of the | |
| 775 | + * rectangle and aligned in +ra (width) and +dec (height). | |
| 776 | + ***************************************************************************/ | |
| 777 | +GSkyDir GSkyRegionRect::transform_to_global(const GSkyDir& locdir) const | |
| 778 | +{ | |
| 779 | + // Rotate local coordinates with positive PA | |
| 780 | + double dx = (m_posang_cos *locdir.ra()) + (m_posang_sin *locdir.dec()); | |
| 781 | + double dy = (m_posang_cos *locdir.dec()) - (m_posang_sin *locdir.ra()); | |
| 782 | + | |
| 783 | + // Shift by rectangle center, apply spherical coordinate scaling | |
| 784 | + double new_y = m_centre.dec() + dy; | |
| 785 | + double new_x = m_centre.ra() + dx/std::cos(new_y); | |
| 786 | + | |
| 787 | + // Create output sky direction | |
| 788 | + GSkyDir transformed; | |
| 789 | + transformed.radec(new_x, new_y); | |
| 790 | + | |
| 791 | + // Return | |
| 792 | + return transformed; | |
| 793 | +} | |
| 794 | + | |
| 795 | + | |
| 711 | 796 | |
| 712 | 797 | /*========================================================================== |
| 713 | 798 | = = | ... | ... |