public void DrawSemivariogramSurface(double Radius,boolean AnIsotropic){
  double[][] data=new double[3][BinSurface.length * BinSurface[0].length];
  int n=0;
  double max=Double.MIN_VALUE;
  for (int i=0; i < BinSurface.length; i++) {
    for (int j=0; j < BinSurface[i].length; j++) {
      data[0][n]=BinSurface[i][j].GridHorDistance;
      data[1][n]=BinSurface[i][j].GridVerDistance;
      if ((Math.pow(data[0][n],2) + Math.pow(data[1][n],2)) <= Radius * Radius && !Double.isNaN(BinSurface[i][j].Value)) {
        data[2][n]=BinSurface[i][j].Value;
        if (max < data[2][n]) {
          max=data[2][n];
        }
      }
 else {
        data[2][n]=-1;
      }
      n++;
    }
  }
  DefaultXYZDataset dataset=new DefaultXYZDataset();
  dataset.addSeries("Value",data);
  NumberAxis xAxis=new NumberAxis();
  xAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
  xAxis.setLowerMargin(0.0);
  xAxis.setUpperMargin(0.0);
  NumberAxis yAxis=new NumberAxis();
  yAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
  yAxis.setLowerMargin(0.0);
  yAxis.setUpperMargin(0.0);
  XYBlockRenderer renderer=new XYBlockRenderer();
  renderer.setBlockWidth(LagSize);
  renderer.setBlockHeight(LagSize);
  renderer.setBlockAnchor(RectangleAnchor.CENTER);
  LookupPaintScale paintScale=new LookupPaintScale(0,max,Color.white);
  double colorRange=max / 6;
  paintScale.add(0.0,Color.blue);
  paintScale.add(1 * colorRange,Color.green);
  paintScale.add(2 * colorRange,Color.cyan);
  paintScale.add(3 * colorRange,Color.yellow);
  paintScale.add(4 * colorRange,Color.ORANGE);
  paintScale.add(5 * colorRange,Color.red);
  renderer.setPaintScale(paintScale);
  XYPlot plot=new XYPlot(dataset,xAxis,yAxis,renderer);
  plot.setBackgroundPaint(Color.lightGray);
  plot.setDomainGridlinesVisible(false);
  plot.setRangeGridlinePaint(Color.white);
  if (AnIsotropic) {
    CombinedRangeXYPlot combinedrangexyplot=new CombinedRangeXYPlot();
    XYSeries seriesT1=new XYSeries("1");
    XYSeriesCollection AngleCollct=new XYSeriesCollection();
    double bw=BandWidth;
    double r=bw / Math.sin(Tolerance);
    if (r > Radius) {
      bw=Radius * Math.sin(Tolerance);
      r=Radius;
    }
    seriesT1.add(r * Math.cos(Angle + Tolerance),r * Math.sin(Angle + Tolerance));
    if ((double)Math.round(Math.sin(Angle) * 10000) / 10000 != 0) {
      if ((double)Math.round(Math.cos(Angle) * 10000) / 10000 != 0) {
        double a=(1 + Math.pow(Math.tan(Angle),2));
        double b=2 * bw / Math.sin(Angle) * Math.pow(Math.tan(Angle),2);
        double c=Math.pow(Math.tan(Angle),2) * Math.pow(bw / Math.sin(Angle),2) - Math.pow(Radius,2);
        double x1=(-b + Math.sqrt(Math.pow(b,2) - 4 * a * c)) / (2 * a);
        double y1=Math.tan(Angle) * (x1 + bw / Math.sin(Angle));
        double x2=(-b - Math.sqrt(Math.pow(b,2) - 4 * a * c)) / (2 * a);
        double y2=Math.tan(Angle) * (x2 + bw / Math.sin(Angle));
        double d1=Math.sqrt((Math.pow((Radius * Math.cos(Angle) - x1),2)) + (Math.pow((Radius * Math.sin(Angle) - y1),2)));
        double d2=Math.sqrt((Math.pow((Radius * Math.cos(Angle) - x2),2)) + (Math.pow((Radius * Math.sin(Angle) - y2),2)));
        if (d1 < d2) {
          seriesT1.add(x1,y1);
        }
 else {
          seriesT1.add(x2,y2);
        }
      }
 else {
        double x1=-bw * Math.sin(Angle);
        double y1=Math.sqrt(Math.pow(Radius,2) - Math.pow(x1,2));
        double y2=-Math.sqrt(Math.pow(Radius,2) - Math.pow(x1,2));
        double d1=Math.sqrt((Math.pow((Radius * Math.cos(Angle) - x1),2)) + (Math.pow((Radius * Math.sin(Angle) - y1),2)));
        double d2=Math.sqrt((Math.pow((Radius * Math.cos(Angle) - x1),2)) + (Math.pow((Radius * Math.sin(Angle) - y2),2)));
        if (d1 < d2) {
          seriesT1.add(x1,y1);
        }
 else {
          seriesT1.add(x1,y2);
        }
      }
    }
 else {
      double y1=bw * Math.cos(Angle);
      double x1=Math.sqrt(Math.pow(Radius,2) - Math.pow(y1,2));
      double x2=-Math.sqrt(Math.pow(Radius,2) - Math.pow(y1,2));
      double d1=Math.sqrt((Math.pow((Radius * Math.cos(Angle) - x1),2)) + (Math.pow((Radius * Math.sin(Angle) - y1),2)));
      double d2=Math.sqrt((Math.pow((Radius * Math.cos(Angle) - x2),2)) + (Math.pow((Radius * Math.sin(Angle) - y1),2)));
      if (d1 < d2) {
        seriesT1.add(x1,y1);
      }
 else {
        seriesT1.add(x2,y1);
      }
    }
    AngleCollct.addSeries(seriesT1);
    XYSeries seriesT2=new XYSeries("2");
    seriesT2.add(r * Math.cos(Angle + Tolerance),r * Math.sin(Angle + Tolerance));
    seriesT2.add(0.0,0.0);
    AngleCollct.addSeries(seriesT2);
    XYSeries seriesT3=new XYSeries("3");
    seriesT3.add(Radius * Math.cos(Angle),Radius * Math.sin(Angle));
    seriesT3.add(0,0);
    AngleCollct.addSeries(seriesT3);
    XYSeries seriesT4=new XYSeries("4");
    seriesT4.add(r * Math.cos(Angle - Tolerance),r * Math.sin(Angle - Tolerance));
    seriesT4.add(0,0);
    AngleCollct.addSeries(seriesT4);
    XYSeries seriesT5=new XYSeries("5");
    seriesT5.add(r * Math.cos(Angle - Tolerance),r * Math.sin(Angle - Tolerance));
    if ((double)Math.round(Math.sin(Angle) * 10000) / 10000 != 0) {
      if ((double)Math.round(Math.cos(Angle) * 10000) / 10000 != 0) {
        double a=(1 + Math.pow(Math.tan(Angle),2));
        double b=-2 * bw / Math.sin(Angle) * Math.pow(Math.tan(Angle),2);
        double c=Math.pow(Math.tan(Angle),2) * Math.pow(bw / Math.sin(Angle),2) - Math.pow(Radius,2);
        double x1=(-b + Math.sqrt(Math.pow(b,2) - 4 * a * c)) / (2 * a);
        double y1=Math.tan(Angle) * (x1 - bw / Math.sin(Angle));
        double x2=(-b - Math.sqrt(Math.pow(b,2) - 4 * a * c)) / (2 * a);
        double y2=Math.tan(Angle) * (x2 - bw / Math.sin(Angle));
        double d1=Math.sqrt((Math.pow((Radius * Math.cos(Angle) - x1),2)) + (Math.pow((Radius * Math.sin(Angle) - y1),2)));
        double d2=Math.sqrt((Math.pow((Radius * Math.cos(Angle) - x2),2)) + (Math.pow((Radius * Math.sin(Angle) - y2),2)));
        if (d1 < d2) {
          seriesT5.add(x1,y1);
        }
 else {
          seriesT5.add(x2,y2);
        }
      }
 else {
        double x1=bw * Math.sin(Angle);
        double y1=Math.sqrt(Math.pow(Radius,2) - Math.pow(x1,2));
        double y2=-Math.sqrt(Math.pow(Radius,2) - Math.pow(x1,2));
        double d1=Math.sqrt((Math.pow((Radius * Math.cos(Angle) - x1),2)) + (Math.pow((Radius * Math.sin(Angle) - y1),2)));
        double d2=Math.sqrt((Math.pow((Radius * Math.cos(Angle) - x1),2)) + (Math.pow((Radius * Math.sin(Angle) - y2),2)));
        if (d1 < d2) {
          seriesT5.add(x1,y1);
        }
 else {
          seriesT5.add(x1,y2);
        }
      }
    }
 else {
      double y1=-bw * Math.cos(Angle);
      double x1=Math.sqrt(Math.pow(Radius,2) - Math.pow(y1,2));
      double x2=-Math.sqrt(Math.pow(Radius,2) - Math.pow(y1,2));
      double d1=Math.sqrt((Math.pow((Radius * Math.cos(Angle) - x1),2)) + (Math.pow((Radius * Math.sin(Angle) - y1),2)));
      double d2=Math.sqrt((Math.pow((Radius * Math.cos(Angle) - x2),2)) + (Math.pow((Radius * Math.sin(Angle) - y1),2)));
      if (d1 < d2) {
        seriesT5.add(x1,y1);
      }
 else {
        seriesT5.add(x2,y1);
      }
    }
    AngleCollct.addSeries(seriesT5);
    plot.setDataset(1,AngleCollct);
    XYLineAndShapeRenderer lineshapRend=new XYLineAndShapeRenderer(true,false);
    for (int i=0; i < AngleCollct.getSeriesCount(); i++) {
      lineshapRend.setSeriesPaint(i,Color.BLACK);
    }
    plot.setRenderer(1,lineshapRend);
    combinedrangexyplot.add(plot);
  }
  plot.setDatasetRenderingOrder(DatasetRenderingOrder.FORWARD);
  JFreeChart chart=new JFreeChart("Semivariogram Surface",plot);
  chart.removeLegend();
  chart.setBackgroundPaint(Color.white);
  ChartFrame frame=new ChartFrame("",chart);
  frame.pack();
  frame.setVisible(true);
}

public void DrawSemivariogramSurface ( double Radius , boolean AnIsotropic ) { double [ ] [ ] data = new double [ 3 ] [ BinSurface . length * BinSurface [ 0 ] . length ] ; int n = 0 ; double max = Double . MIN_VALUE ; for ( int i = 0 ; i < BinSurface . length ; i ++ ) { for ( int j = 0 ; j < BinSurface [ i ] . length ; j ++ ) { data [ 0 ] [ n ] = BinSurface [ i ] [ j ] . GridHorDistance ; data [ 1 ] [ n ] = BinSurface [ i ] [ j ] . GridVerDistance ; if ( ( Math . pow ( data [ 0 ] [ n ] , 2 ) + Math . pow ( data [ 1 ] [ n ] , 2 ) ) <= Radius * Radius && ! Double . isNaN ( BinSurface [ i ] [ j ] . Value ) ) { data [ 2 ] [ n ] = BinSurface [ i ] [ j ] . Value ; if ( max < data [ 2 ] [ n ] ) { max = data [ 2 ] [ n ] ; } } else { data [ 2 ] [ n ] = - 1 ; } n ++ ; } } DefaultXYZDataset dataset = new DefaultXYZDataset ( ) ; dataset . addSeries ( "Value" , data ) ; NumberAxis xAxis = new NumberAxis ( ) ; xAxis . setStandardTickUnits ( NumberAxis . createIntegerTickUnits ( ) ) ; xAxis . setLowerMargin ( 0.0 ) ; xAxis . setUpperMargin ( 0.0 ) ; NumberAxis yAxis = new NumberAxis ( ) ; yAxis . setStandardTickUnits ( NumberAxis . createIntegerTickUnits ( ) ) ; yAxis . setLowerMargin ( 0.0 ) ; yAxis . setUpperMargin ( 0.0 ) ; XYBlockRenderer renderer = new XYBlockRenderer ( ) ; renderer . setBlockWidth ( LagSize ) ; renderer . setBlockHeight ( LagSize ) ; renderer . setBlockAnchor ( RectangleAnchor . CENTER ) ; LookupPaintScale paintScale = new LookupPaintScale ( 0 , max , Color . white ) ; double colorRange = max / 6 ; paintScale . add ( 0.0 , Color . blue ) ; paintScale . add ( 1 * colorRange , Color . green ) ; paintScale . add ( 2 * colorRange , Color . cyan ) ; paintScale . add ( 3 * colorRange , Color . yellow ) ; paintScale . add ( 4 * colorRange , Color . ORANGE ) ; paintScale . add ( 5 * colorRange , Color . red ) ; renderer . setPaintScale ( paintScale ) ; XYPlot plot = new XYPlot ( dataset , xAxis , yAxis , renderer ) ; plot . setBackgroundPaint ( Color . lightGray ) ; plot . setDomainGridlinesVisible ( false ) ; plot . setRangeGridlinePaint ( Color . white ) ; if ( AnIsotropic ) { CombinedRangeXYPlot combinedrangexyplot = new CombinedRangeXYPlot ( ) ; XYSeries seriesT1 = new XYSeries ( "1" ) ; XYSeriesCollection AngleCollct = new XYSeriesCollection ( ) ; double bw = BandWidth ; double r = bw / Math . sin ( Tolerance ) ; if ( r > Radius ) { bw = Radius * Math . sin ( Tolerance ) ; r = Radius ; } seriesT1 . add ( r * Math . cos ( Angle + Tolerance ) , r * Math . sin ( Angle + Tolerance ) ) ; if ( ( double ) Math . round ( Math . sin ( Angle ) * 10000 ) / 10000 != 0 ) { if ( ( double ) Math . round ( Math . cos ( Angle ) * 10000 ) / 10000 != 0 ) { double a = ( 1 + Math . pow ( Math . tan ( Angle ) , 2 ) ) ; double b = 2 * bw / Math . sin ( Angle ) * Math . pow ( Math . tan ( Angle ) , 2 ) ; double c = Math . pow ( Math . tan ( Angle ) , 2 ) * Math . pow ( bw / Math . sin ( Angle ) , 2 ) - Math . pow ( Radius , 2 ) ; double x1 = ( - b + Math . sqrt ( Math . pow ( b , 2 ) - 4 * a * c ) ) / ( 2 * a ) ; double y1 = Math . tan ( Angle ) * ( x1 + bw / Math . sin ( Angle ) ) ; double x2 = ( - b - Math . sqrt ( Math . pow ( b , 2 ) - 4 * a * c ) ) / ( 2 * a ) ; double y2 = Math . tan ( Angle ) * ( x2 + bw / Math . sin ( Angle ) ) ; double d1 = Math . sqrt ( ( Math . pow ( ( Radius * Math . cos ( Angle ) - x1 ) , 2 ) ) + ( Math . pow ( ( Radius * Math . sin ( Angle ) - y1 ) , 2 ) ) ) ; double d2 = Math . sqrt ( ( Math . pow ( ( Radius * Math . cos ( Angle ) - x2 ) , 2 ) ) + ( Math . pow ( ( Radius * Math . sin ( Angle ) - y2 ) , 2 ) ) ) ; if ( d1 < d2 ) { seriesT1 . add ( x1 , y1 ) ; } else { seriesT1 . add ( x2 , y2 ) ; } } else { double x1 = - bw * Math . sin ( Angle ) ; double y1 = Math . sqrt ( Math . pow ( Radius , 2 ) - Math . pow ( x1 , 2 ) ) ; double y2 = - Math . sqrt ( Math . pow ( Radius , 2 ) - Math . pow ( x1 , 2 ) ) ; double d1 = Math . sqrt ( ( Math . pow ( ( Radius * Math . cos ( Angle ) - x1 ) , 2 ) ) + ( Math . pow ( ( Radius * Math . sin ( Angle ) - y1 ) , 2 ) ) ) ; double d2 = Math . sqrt ( ( Math . pow ( ( Radius * Math . cos ( Angle ) - x1 ) , 2 ) ) + ( Math . pow ( ( Radius * Math . sin ( Angle ) - y2 ) , 2 ) ) ) ; if ( d1 < d2 ) { seriesT1 . add ( x1 , y1 ) ; } else { seriesT1 . add ( x1 , y2 ) ; } } } else { double y1 = bw * Math . cos ( Angle ) ; double x1 = Math . sqrt ( Math . pow ( Radius , 2 ) - Math . pow ( y1 , 2 ) ) ; double x2 = - Math . sqrt ( Math . pow ( Radius , 2 ) - Math . pow ( y1 , 2 ) ) ; double d1 = Math . sqrt ( ( Math . pow ( ( Radius * Math . cos ( Angle ) - x1 ) , 2 ) ) + ( Math . pow ( ( Radius * Math . sin ( Angle ) - y1 ) , 2 ) ) ) ; double d2 = Math . sqrt ( ( Math . pow ( ( Radius * Math . cos ( Angle ) - x2 ) , 2 ) ) + ( Math . pow ( ( Radius * Math . sin ( Angle ) - y1 ) , 2 ) ) ) ; if ( d1 < d2 ) { seriesT1 . add ( x1 , y1 ) ; } else { seriesT1 . add ( x2 , y1 ) ; } } AngleCollct . addSeries ( seriesT1 ) ; XYSeries seriesT2 = new XYSeries ( "2" ) ; seriesT2 . add ( r * Math . cos ( Angle + Tolerance ) , r * Math . sin ( Angle + Tolerance ) ) ; seriesT2 . add ( 0.0 , 0.0 ) ; AngleCollct . addSeries ( seriesT2 ) ; XYSeries seriesT3 = new XYSeries ( "3" ) ; seriesT3 . add ( Radius * Math . cos ( Angle ) , Radius * Math . sin ( Angle ) ) ; seriesT3 . add ( 0 , 0 ) ; AngleCollct . addSeries ( seriesT3 ) ; XYSeries seriesT4 = new XYSeries ( "4" ) ; seriesT4 . add ( r * Math . cos ( Angle - Tolerance ) , r * Math . sin ( Angle - Tolerance ) ) ; seriesT4 . add ( 0 , 0 ) ; AngleCollct . addSeries ( seriesT4 ) ; XYSeries seriesT5 = new XYSeries ( "5" ) ; seriesT5 . add ( r * Math . cos ( Angle - Tolerance ) , r * Math . sin ( Angle - Tolerance ) ) ; if ( ( double ) Math . round ( Math . sin ( Angle ) * 10000 ) / 10000 != 0 ) { if ( ( double ) Math . round ( Math . cos ( Angle ) * 10000 ) / 10000 != 0 ) { double a = ( 1 + Math . pow ( Math . tan ( Angle ) , 2 ) ) ; double b = - 2 * bw / Math . sin ( Angle ) * Math . pow ( Math . tan ( Angle ) , 2 ) ; double c = Math . pow ( Math . tan ( Angle ) , 2 ) * Math . pow ( bw / Math . sin ( Angle ) , 2 ) - Math . pow ( Radius , 2 ) ; double x1 = ( - b + Math . sqrt ( Math . pow ( b , 2 ) - 4 * a * c ) ) / ( 2 * a ) ; double y1 = Math . tan ( Angle ) * ( x1 - bw / Math . sin ( Angle ) ) ; double x2 = ( - b - Math . sqrt ( Math . pow ( b , 2 ) - 4 * a * c ) ) / ( 2 * a ) ; double y2 = Math . tan ( Angle ) * ( x2 - bw / Math . sin ( Angle ) ) ; double d1 = Math . sqrt ( ( Math . pow ( ( Radius * Math . cos ( Angle ) - x1 ) , 2 ) ) + ( Math . pow ( ( Radius * Math . sin ( Angle ) - y1 ) , 2 ) ) ) ; double d2 = Math . sqrt ( ( Math . pow ( ( Radius * Math . cos ( Angle ) - x2 ) , 2 ) ) + ( Math . pow ( ( Radius * Math . sin ( Angle ) - y2 ) , 2 ) ) ) ; if ( d1 < d2 ) { seriesT5 . add ( x1 , y1 ) ; } else { seriesT5 . add ( x2 , y2 ) ; } } else { double x1 = bw * Math . sin ( Angle ) ; double y1 = Math . sqrt ( Math . pow ( Radius , 2 ) - Math . pow ( x1 , 2 ) ) ; double y2 = - Math . sqrt ( Math . pow ( Radius , 2 ) - Math . pow ( x1 , 2 ) ) ; double d1 = Math . sqrt ( ( Math . pow ( ( Radius * Math . cos ( Angle ) - x1 ) , 2 ) ) + ( Math . pow ( ( Radius * Math . sin ( Angle ) - y1 ) , 2 ) ) ) ; double d2 = Math . sqrt ( ( Math . pow ( ( Radius * Math . cos ( Angle ) - x1 ) , 2 ) ) + ( Math . pow ( ( Radius * Math . sin ( Angle ) - y2 ) , 2 ) ) ) ; if ( d1 < d2 ) { seriesT5 . add ( x1 , y1 ) ; } else { seriesT5 . add ( x1 , y2 ) ; } } } else { double y1 = - bw * Math . cos ( Angle ) ; double x1 = Math . sqrt ( Math . pow ( Radius , 2 ) - Math . pow ( y1 , 2 ) ) ; double x2 = - Math . sqrt ( Math . pow ( Radius , 2 ) - Math . pow ( y1 , 2 ) ) ; double d1 = Math . sqrt ( ( Math . pow ( ( Radius * Math . cos ( Angle ) - x1 ) , 2 ) ) + ( Math . pow ( ( Radius * Math . sin ( Angle ) - y1 ) , 2 ) ) ) ; double d2 = Math . sqrt ( ( Math . pow ( ( Radius * Math . cos ( Angle ) - x2 ) , 2 ) ) + ( Math . pow ( ( Radius * Math . sin ( Angle ) - y1 ) , 2 ) ) ) ; if ( d1 < d2 ) { seriesT5 . add ( x1 , y1 ) ; } else { seriesT5 . add ( x2 , y1 ) ; } } AngleCollct . addSeries ( seriesT5 ) ; plot . setDataset ( 1 , AngleCollct ) ; XYLineAndShapeRenderer lineshapRend = new XYLineAndShapeRenderer ( true , false ) ; for ( int i = 0 ; i < AngleCollct . getSeriesCount ( ) ; i ++ ) { lineshapRend . setSeriesPaint ( i , Color . BLACK ) ; } plot . setRenderer ( 1 , lineshapRend ) ; combinedrangexyplot . add ( plot ) ; } plot . setDatasetRenderingOrder ( DatasetRenderingOrder . FORWARD ) ; JFreeChart chart = new JFreeChart ( "Semivariogram Surface" , plot ) ; chart . removeLegend ( ) ; chart . setBackgroundPaint ( Color . white ) ; ChartFrame frame = new ChartFrame ( "" , chart ) ; frame . pack ( ) ; frame . setVisible ( true ) ; }
draw semivariogram surface map and also draw the search are if anisotropic
