001    package edu.nrao.sss.measure;
002    
003    import java.util.Comparator;
004    
005    import edu.nrao.sss.sort.CompoundComparator;
006    import edu.nrao.sss.sort.DoubleSortKey;
007    import edu.nrao.sss.sort.SortKey;
008    
009    /**
010     * A {@link SortKey sort key} and {@link Comparator comparator} that works with
011     * {@link Angle angles}.
012     * <p>
013     * Because this class is a <tt>SortKey</tt>, you may configure its instances with
014     * a particular {@code SortOrder}.  You may place instances of this
015     * class in a {@link CompoundComparator}.</p>
016     * <p>
017     * <b>Version Info:</b>
018     * <table style="margin-left:2em">
019     *   <tr><td>$Revision: 1239 $</td></tr>
020     *   <tr><td>$Date: 2008-04-25 10:34:57 -0600 (Fri, 25 Apr 2008) $</td></tr>
021     *   <tr><td>$Author: dharland $</td></tr>
022     * </table></p>
023     * 
024     * @author David M. Harland
025     * @since 2007-05-07
026     */
027    public class AngleSortKey
028      extends DoubleSortKey
029      implements Comparator<Angle>
030    {
031      private boolean normalized;
032      
033      /** Creates a new instance. */
034      public AngleSortKey()
035      {
036        normalized = false;
037      }
038      
039      /**
040       * Tells this key whether or not it should work with the raw angles fed to it
041       * or with {@link Angle#normalize() normalized} versions thereof.  Note that
042       * even if {@code normalizeBeforeComparing} is <i>true</i>, this class will
043       * not alter the actual angles sent to it.  It will instead, though, work
044       * with normalized copies of those angles.
045       * 
046       * @param normalizeBeforeComparing <i>true</i> if the caller wants this key
047       *          to do a comparison on normalized angles.  For example, the
048       *          angle 400 degrees is greater than 90 degrees if not normalized,
049       *          but less than 90 degrees if normalized.  (The normalized value
050       *          of 400 degrees is 60 degrees.)
051       */
052      public void setNormalized(boolean normalizeBeforeComparing)
053      {
054        normalized = normalizeBeforeComparing;
055      }
056      
057      /* (non-Javadoc)
058       * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
059       */
060      public int compare(Angle a1, Angle a2)
061      {
062        //Make angles less than one full circle, if desired
063        if (normalized)
064        {
065          if (a1 != null)
066            a1 = a1.clone().normalize();
067          
068          if (a2 != null)
069            a2 = a2.clone().normalize();
070        }
071        
072        //Use units from one of the angles (unless both angles are null)
073        ArcUnits units = null;
074        
075        if (a1 != null)
076        {
077          units = a1.getUnits();
078        }
079        else
080        {
081          if (a2 != null)
082            units = a2.getUnits();
083        }
084        
085        //Convert to same units (or leave as null)
086        Double d1 = (a1 == null) ? null : a1.toUnits(units).doubleValue();
087        Double d2 = (a2 == null) ? null : a2.toUnits(units).doubleValue();
088        
089        return compareObjects(d1, d2);
090      }
091    }