/**
  * Overlays layers of {@code Sampleable}s with the first element of {@code layers} being on top.
  * This method respects the transparency in the alpha component of each layer
  *
  * @param layers the array of layers
  */
 public static Sampleable overlay(Sampleable... layers) {
   if (layers.length == 0) {
     throw new IllegalArgumentException("Empty array was passed into overlay");
   }
   if (layers.length == 1) {
     return new AbstractSampleable(layers[0].getBoundingBox()) {
       @Override
       public Color getColorAt(Point<Double> point) {
         return layers[0].getColorAt(point);
       }
     };
   }
   return overlay(
       BoundingBox.containing(layers), layers[layers.length - 1], layers.length - 1, layers);
 }
  /**
   * Overlays several sampleables from top to bottom. This method ignores the alpha channel in the
   * sense that it doesn't show lower layers through semi-transparent upper layers.
   *
   * @param elements the sampleables to overlay, top first
   * @return the composed sampleable
   */
  public static Sampleable opaqueOverlay(Sampleable... elements) {
    return new AbstractSampleable(BoundingBox.containing(elements)) {
      @Override
      public Color getColorAt(Point<Double> point) {
        for (Sampleable element : elements) {
          BoundingBox bb = element.getBoundingBox();
          if (bb.contains(point)) {
            Color color = element.getColorAt(point);
            if (!color.isTransparent()) {
              return color;
            }
          }
        }

        return Colors.TRANSPARENT;
      }
    };
  }