package org.jzy3d.plot3d.builder.concrete;

import java.util.List;

import org.jzy3d.colors.Color;
import org.jzy3d.colors.ColorMapper;
import org.jzy3d.plot3d.primitives.AbstractComposite;
import org.jzy3d.plot3d.primitives.AbstractDrawable;
import org.jzy3d.plot3d.primitives.Shape;


public class RingExtrapolator extends OrthonormalTessellator{
	public RingExtrapolator(float ringMax, ColorMapper cmap, Color factor){
		this.ringMax      = ringMax;
		this.cmap         = cmap;
		this.factor       = factor;
		this.interpolator = new RingTessellator(0, ringMax, cmap, factor);
	}
	
	@SuppressWarnings("unused")
	private RingExtrapolator(){
		throw new RuntimeException("Forbidden constructor!");
	}
	
	@Override
    public AbstractComposite build(float[] x, float[] y, float[] z) {
		setData(x, y, z);
		Shape s = new Shape();
		s.add(getExtrapolatedRingPolygons());
		return s;
	}
	
	/******************************************************************************/
	
	public List getExtrapolatedRingPolygons(){
		//backup current coords and extrapolate
		float[]   xbackup = x;
		float[]   ybackup = y;
		float[][] zbackup = z;
		
		// compute required extrapolation
		float step = x[1] - x[0];
		int  nstep = x.length;
		
		int ENLARGE = 2;		
		int required = (int)( Math.ceil( (ringMax*2 - step*nstep) / step )  );
		required = required<0 ? ENLARGE:required+ENLARGE;		
		
		if(required>0)
			extrapolate(required);
		
		interpolator.x = x;
		interpolator.y = y;
		interpolator.z = z;
		List polygons = interpolator.getInterpolatedRingPolygons();
		
		// get back to previous grid
		x = xbackup;
		y = ybackup;
		z = zbackup;
		
		return polygons;
	}
	
	/** Add extrapolated points on the grid. If the grid is too small for extrapolation, the arrays
	 * are maximized */
	public void extrapolate(int n){
		float[]   xnew = new float[x.length+n*2];
		float[]   ynew = new float[y.length+n*2];
		float[][] znew = new float[x.length+n*2][y.length+n*2];
		
		// assume x and y grid are allready sorted and create new grids
		float xmin = x[0];
		float xmax = x[x.length-1];
		float xgap = x[1]-x[0];		
		float ymin = y[0];
		float ymax = y[y.length-1];
		float ygap = y[1]-y[0];
		
		for(int i=0; i=n && i= x.length+n) // fill after
				xnew[i] = xmax + (i-(x.length+n)+1) * xgap;
			
			// --- y grid ---
			for(int j=0; j=n && j< (y.length+n) ){ // copy content
					ynew[j]    = y[j-n];
					
					// copy z grid
					if(i>=n && i= (y.length+n) ){ // fill after
					ynew[j]    = ymax + (j-(y.length+n)+1) * ygap;
					znew[i][j] = Float.NaN;
				}
			}
		}
		
		// extrapolation
		float olddiameter = xgap*(x.length    )/2;
		float newdiameter = xgap*(x.length-1+n*2)/2;
		olddiameter *= olddiameter;
		newdiameter *= newdiameter;
		
		int xmiddle = (xnew.length-1)/2; // assume it is an uneven grid
		int ymiddle = (ynew.length-1)/2; // assume it is an uneven grid		
		
		// start from center, and add extrapolated values iteratively on each quadrant
		for(int i=xmiddle; i= olddiameter){
					
					int xopp = i - 2*(i-xmiddle);
					int yopp = j - 2*(j-ymiddle);
					
					znew[i]   [j]    = getExtrapolatedZ(znew, i, j); // right up quadrant
					znew[xopp][j]    = getExtrapolatedZ(znew, xopp, j); // left  up
					znew[i]   [yopp] = getExtrapolatedZ(znew, i, yopp); // right down
					znew[xopp][yopp] = getExtrapolatedZ(znew, xopp, yopp); // left  down
				}
				
				// ignore values standing outside desired diameter
				else //if(sqrad > newdiameter)
					znew[i][j] = Float.NaN;	
			}
		}
		
		// store result
		x = xnew;
		y = ynew;
		z = znew;
	}
	
	private float getExtrapolatedZ(float[][] grid, int currentXi, int currentYi){
		int left   = currentXi-1>0              ? currentXi-1 : currentXi;
		int right  = currentXi+10              ? currentYi-1 : currentYi;
		int up     = currentYi+10)
			return cumval/nval;
		else
			return Float.NaN;
	}
	
	/*************************************************************************************/
	
	protected float       ringMax;
	protected ColorMapper cmap;
	protected Color       factor;
	
	protected RingTessellator interpolator;
}

 

Ads help maintain this website.