class InterpolatedFromSurfacesDoublesCube extends Cube<Double, Double, Double, Double> {

  @Override
  public Double getValue(final Double x, final Double y, final Double z) {
    Validate.notNull(x, "x");
    Validate.notNull(y, "y");
    Validate.notNull(z, "z");
    final double[] values = new double[_nSurfaces];
    int i = 0;
    double x1, y1, z1;
    switch (_plane) {
      case XY:
        x1 = x;
        y1 = y;
        z1 = z;
        break;
      case ZX:
        x1 = x;
        y1 = z;
        z1 = y;
        break;
      case YZ:
        x1 = y;
        y1 = z;
        z1 = x;
        break;
      default:
        throw new IllegalArgumentException("Cannot handle type " + _plane);
    }
    final int index = Arrays.binarySearch(_points, z1);
    if (index < 0) {
      for (final Surface<Double, Double, Double> surface : _surfaces) {
        values[i++] = surface.getZValue(x1, y1);
      }
      return InterpolatedDoublesCurve.fromSorted(_points, values, _interpolator).getYValue(z1);
    }
    return _surfaces[index].getZValue(x1, y1);
  }

  public  InterpolatedFromSurfacesDoublesCube(final Plane plane, final double[] points, final Surface<Double, Double, Double>[] surfaces,
      final Interpolator1D interpolator, final boolean isSorted);
  @SuppressWarnings("unchecked") public  InterpolatedFromSurfacesDoublesCube(final Plane plane, final Double[] points, final Surface<Double, Double, Double>[] surfaces,
      final Interpolator1D interpolator, final boolean isSorted);
  @SuppressWarnings("unchecked") public  InterpolatedFromSurfacesDoublesCube(final Plane plane, final List<Double> points, final List<Surface<Double, Double, Double>> surfaces,
      final Interpolator1D interpolator, final boolean isSorted);
  @SuppressWarnings("unchecked") public  InterpolatedFromSurfacesDoublesCube(final Plane plane, final Map<Double, Surface<Double, Double, Double>> surfaces,
      final Interpolator1D interpolator, final boolean isSorted);
  public  InterpolatedFromSurfacesDoublesCube(final Plane plane, final double[] points, final Surface<Double, Double, Double>[] surfaces,
      final Interpolator1D interpolator, final boolean isSorted, final String name);
  @SuppressWarnings("unchecked") public  InterpolatedFromSurfacesDoublesCube(final Plane plane, final Double[] points, final Surface<Double, Double, Double>[] surfaces,
      final Interpolator1D interpolator, final boolean isSorted, final String name);
  @SuppressWarnings("unchecked") public  InterpolatedFromSurfacesDoublesCube(final Plane plane, final List<Double> points, final List<Surface<Double, Double, Double>> surfaces,
      final Interpolator1D interpolator, final boolean isSorted, final String name);
  @SuppressWarnings("unchecked") public  InterpolatedFromSurfacesDoublesCube(final Plane plane, final Map<Double, Surface<Double, Double, Double>> surfaces,
      final Interpolator1D interpolator, final boolean isSorted, final String name);

}