/**
  * Returns a hierarchical index of a cone.
  *
  * @param index Healpix index
  * @param shape cone
  * @return the pixel numbers as a hierarchical index
  * @throws Exception Healpix Exception
  */
 protected static HealpixMoc computeConeIndex(final HealpixIndex index, final Shape shape)
     throws Exception {
   final HealpixMoc moc = new HealpixMoc();
   final Cone cone = (Cone) shape;
   final RangeSet rangeSet =
       index.queryDiscInclusive(cone.getCenter(), cone.getRadius(), TYPICAL_CHOICE_FACT);
   final RangeSet.ValueIterator valueIter = rangeSet.valueIterator();
   while (valueIter.hasNext()) {
     final long pixNest = valueIter.next();
     moc.add(new MocCell(index.getOrder(), pixNest));
   }
   return moc;
 }
 /**
  * Draws a Healpix pixel according to a coordinate system.
  *
  * <p>When the pixel area is "small", only the four points of the pixel are used to plot it. When
  * the pixel area is "large", intermediate points on boundaries pixel are automatically computed
  * to smooth the boundary of the pixel on the plot.
  *
  * @param graphic2D graph component to decore
  * @param healpix Healpix index
  * @param pix Pixel to draw
  * @param coordinateTransformation Coordinate transformation
  */
 @Override
 protected final void drawHealpixPolygon(
     final Graphics2D graphic2D,
     final HealpixIndex healpix,
     final long pix,
     final CoordinateTransformation coordinateTransformation) {
   try {
     final int numberOfVectors = computeNumberPointsForPixel(getHealpixBase().getNside(), pix);
     final Vec3[] vectors = healpix.boundaries(pix, numberOfVectors);
     computeReferenceFrameTransformation(vectors, coordinateTransformation);
     final Coordinates[] shapes = splitHealpixPixelForDetectedBorder(vectors);
     final Polygon2D poly = new Polygon2D();
     for (int i = 0; i < shapes.length; i++) {
       final Coordinates shape = shapes[i];
       final List<Point2D.Double> pixels =
           shape.getPixelsFromProjection(
               this.getProjection(), getRange(), getPixelWidth(), getPixelHeight());
       poly.setPoints(pixels);
       graphic2D.draw(poly);
       graphic2D.fill(poly);
     }
   } catch (Exception ex) {
     LOG.log(Level.SEVERE, null, ex);
   }
 }
 /**
  * Returns a range of Healpix pixels from the a list of points.
  *
  * @param points List of points of the polygon
  * @param index Healpix index
  * @return the rangeSet of pixels
  * @throws Exception Helapix Exception
  */
 protected static RangeSet computePolygon(final List<Point> points, final HealpixIndex index)
     throws Exception {
   RangeSet result;
   final Pointing[] pointings = new Pointing[points.size()];
   int i = 0;
   for (Point p : points) {
     pointings[i] = p;
     i++;
   }
   result = index.queryPolygonInclusive(pointings, TYPICAL_CHOICE_FACT);
   return result;
 }
  /**
   * Returns a hierarchical index of a polygon.
   *
   * <p>When the polygon is clockwise, the index is computed on this polygon.<br>
   * When the polygon is counterclockwised, the index is computed on the complement of this polygon
   *
   * @param index Healpix index
   * @param shape polygon
   * @return the HealpixMoc;
   * @throws Exception Healpix Exception
   */
  protected static HealpixMoc computePolygonIndex(final HealpixIndex index, final Shape shape)
      throws Exception {
    RangeSet rangeSet;
    HealpixMoc moc = new HealpixMoc();
    Polygon polygon = (Polygon) shape;

    final Resampling resample = new Resampling(polygon);
    polygon = resample.processResampling();
    final List<Polygon> polygons = polygon.triangulate();
    rangeSet = new RangeSet();
    for (Polygon p : polygons) {
      final RangeSet rangeSetTmp = new RangeSet(rangeSet);
      rangeSet.setToUnion(rangeSetTmp, computePolygon(p.getPoints(), index));
    }

    final RangeSet.ValueIterator valueIter = rangeSet.valueIterator();
    while (valueIter.hasNext()) {
      moc.add(new MocCell(index.getOrder(), valueIter.next()));
    }
    if (polygon.isClockwised()) {
      moc = moc.complement();
    }
    return moc;
  }
 /**
  * Returns the pixel resolution at a given order.
  *
  * @param order Healpix order
  * @return the pixel resolution in arcsec
  */
 public static double getPixelResolution(final int order) {
   return HealpixIndex.getPixRes((long) Math.pow(2, order));
 }
 /**
  * Computes the pixel related to the point.
  *
  * @param index Healpix index
  * @param shape point
  * @return the pixel number
  * @throws Exception Healpix Exception
  */
 protected static long computePointIndex(final HealpixIndex index, final Shape shape)
     throws Exception {
   Point point = (Point) shape;
   return index.ang2pix(point);
 }