Commit d7439bd2d4c23936c356370c9fbbf4524c10ba9a

Authored by Andreas Specovius
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.
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&amp; 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&amp; 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*>(&reg);
  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&amp; 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&amp; 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&amp; 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&amp; 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&amp; 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 = =
... ...