Greetings,
I'm trying to plot values at specific points between to boundaries. If
you look at:
http://www.cimms.ou.edu/~kmanross/VCPRPE/VisADSamples/Gridded2DSet.gif
You can see that I have been able to get the points and set them up in a
Gridded2DSet(MathType, samples[][], NUM_POINTS, 1). (Note this area is
not "filled" - if you zoom in, you will see individual points.)
Since this is an irregular shape, I also tried creating an
Irregular2DSet from the same points. The Irregular2DSet follows the
bottom boundary fairly well, but does not do so well with the top boundary.
Please see:
http://www.cimms.ou.edu/~kmanross/VCPRPE/VisADSamples/Delaunay.gif
Why is there such a discrepancy between the way the Delaunay fits to the
bottom boundary and the way it doesn't fit the top boundary?
I would like to
A) Get the Irregular2DSet to follow the top boundary as well as it does
the bottom
or
B) Possibly use a Gridded2DSet (man dim = 2).
Can I do B given the irregularity of the data. (I have 28700 points
arranged in 400 columns = 71.75 rows?)
Here is my test program:
import java.*;
import java.awt.*;
import java.awt.event.*;
import java.rmi.RemoteException;
import java.util.Vector;
import javax.swing.*;
import javax.swing.event.*;
import visad.*;
import visad.java3d.DisplayImplJ3D;
import visad.java3d.TwoDDisplayRendererJ3D;
import visad.data.units.*;
public class rangeHeightGridTest extends JPanel implements ActionListener
{
private DisplayImpl display;
private RealType ran, ht;
private RealTupleType ranHt_tt;
private ScalarMap ranMap, htMap;
private DataReferenceImpl dataRef;
private Unit kilometer, km;
private double[] projMatrix;
private JButton reset = new JButton("Reset");
final static double INDEX_OF_REFRACTION = (4.0/3.0);
final static double EARTH_RADIUS = 6378; // km at Equator
final static double RADIANS = (Math.PI/180);
public rangeHeightGridTest() throws VisADException, RemoteException
{
reset.addActionListener(this);
try
{ kilometer = Parser.parse("kilometer").clone("km"); }
catch (ParseException P)
{ System.out.println("ParseException: " + P); }
catch (UnitException U)
{ System.out.println("UnitException: " + U); }
ran = RealType.getRealType("range", km, null);
ht = RealType.getRealType("height", km, null);
RealType value = RealType.getRealType("value", null, null);
RealTupleType ranHt_tt = new RealTupleType(ran, ht);
ranMap = new ScalarMap(ran, Display.XAxis);
htMap = new ScalarMap(ht, Display.YAxis);
ScalarMap valueMap = new ScalarMap(value, Display.RGB);
htMap.setRange(0.0, 25.0);
display = new DisplayImplJ3D( "TextDisplay", new
TwoDDisplayRendererJ3D() );
display.addMap(ranMap);
display.addMap(htMap);
display.addMap(valueMap);
ConstantMap[] setMap = { new ConstantMap (1.0f, Display.Red),
new ConstantMap (0.0f, Display.Green),
new ConstantMap (0.0f, Display.Blue) };
ConstantMap[] ffMap = { new ConstantMap (0.0f, Display.Red),
new ConstantMap (0.0f, Display.Green),
new ConstantMap (1.0f, Display.Blue) };
ConstantMap[] pointMap = { new ConstantMap (0.0f, Display.Red),
new ConstantMap (0.0f, Display.Green),
new ConstantMap (0.0f, Display.Blue),
new ConstantMap (0.1f,
Display.PointSize) };
ProjectionControl initPC = display.getProjectionControl();
projMatrix = initPC.getMatrix();
GraphicsModeControl gmc = display.getGraphicsModeControl();
gmc.setScaleEnable(true);
// ##### Create two beampaths using FlatFields
float[][] beamPath1 = calcBeamPath(0.00, 400.0, 100.0);
float[][] ranVals1 = new float[1][];
float[][] htVals1 = new float[1][];
ranVals1[0] = beamPath1[0];
htVals1[0] = beamPath1[1];
Irregular1DSet ranSet1 = new Irregular1DSet(ran, ranVals1);
FunctionType ranHt_func1 = new FunctionType(ran, ht);
FlatField ranHt_ff1 = new FlatField(ranHt_func1, ranSet1);
ranHt_ff1.setSamples(htVals1);
float[][] beamPath2 = calcBeamPath(1.00, 400.0, 100.0);
float[][] ranVals2 = new float[1][];
float[][] htVals2 = new float[1][];
ranVals2[0] = beamPath2[0];
htVals2[0] = beamPath2[1];
Irregular1DSet ranSet2 = new Irregular1DSet(ran, ranVals2);
FunctionType ranHt_func2 = new FunctionType(ran, ht);
FlatField ranHt_ff2 = new FlatField(ranHt_func2, ranSet2);
ranHt_ff2.setSamples(htVals2);
// ##### This first loop is to get the number of points needed to
initialize
// ##### the "ranHtVals" array. (I'm sure there is an easier way
to do this)
int total = 0;
int numPoints = 0;
for (int j = 1; j < 400; j++)
{
Real ranIndex = new Real(ran, j);
//System.out.println("Ht1 at ran: " + ranIndex + " is: " +
ranHt_ff1.evaluate(ranIndex) );
//System.out.println("Ht2 at ran: " + ranIndex + " is: " +
ranHt_ff2.evaluate(ranIndex) );
Real realTop = (Real)ranHt_ff2.evaluate(ranIndex);
Real realBottom = (Real)ranHt_ff1.evaluate(ranIndex);
float top = (float) realTop.getValue();
float bottom = (float) realBottom.getValue();
float heightDiff = top - bottom;
if (heightDiff < 0.05)
{ numPoints = 1; }
else
{ numPoints = Math.round((float) (heightDiff / 0.05f));}
float width = (float) (heightDiff / numPoints);
//System.out.println(j +"): Top: " + top + ", Bottom: " + bottom
+ ", Diff: "
// + heightDiff + ", Points: " + numPoints + ",
boxWidth: " + width);
// System.out.println(j + "): boxWidth: " + width);
total = total + numPoints + 2;
}
float[][] ranHtVals = new float[2][total];
float[][] valueVals = new float[1][total];
int index = 0;
for (int j = 1; j < 400; j++)
{
Real ranIndex = new Real(ran, j);
Real realTop = (Real)ranHt_ff2.evaluate(ranIndex);
Real realBottom = (Real)ranHt_ff1.evaluate(ranIndex);
float top = (float) realTop.getValue();
float bottom = (float) realBottom.getValue();
float heightDiff = top - bottom;
if (heightDiff < 0.05)
{ numPoints = 1; }
else
{ numPoints = Math.round((float) (heightDiff / 0.05f)); }
float width = (float) (heightDiff / numPoints);
for (int i = 0; i < numPoints+2; i++)
{
ranHtVals[0][index] = (float)ranIndex.getValue();
if (i == 0)
{ ranHtVals[1][index] = (float) (top); }
if (i == numPoints+1)
{ ranHtVals[1][index] = (float) (bottom); }
else
{ ranHtVals[1][index] = (float) (top - width * i); }
valueVals[0][index] = (float)((top - width * i) - bottom);
index++;
}
}
// ##### To view difference in plotting, uncomment this section and
comment out the next section
/*
// ###### Section 1
Irregular2DSet iSet = new Irregular2DSet(ranHt_tt, ranHtVals);
DataReferenceImpl iSetRef = new DataReferenceImpl("iSetRef");
iSetRef.setData(iSet);
display.addReference(iSetRef);
*/
// ##### To view difference in plotting, comment this section and
uncomment the previous section
// ###### Section 2
Gridded2DSet loadem = new Gridded2DSet(ranHt_tt, ranHtVals, total, 1);
DataReferenceImpl setRef = new DataReferenceImpl("setRef");
display.addReference(setRef);
setRef.setData(loadem);
DataReferenceImpl ffRef1 = new DataReferenceImpl("ffRef1");
display.addReference(ffRef1, ffMap);
ffRef1.setData(ranHt_ff1);
DataReferenceImpl ffRef2 = new DataReferenceImpl("ffRef2");
display.addReference(ffRef2, setMap);
ffRef2.setData(ranHt_ff2);
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
setAlignmentY(JPanel.TOP_ALIGNMENT);
setAlignmentX(JPanel.LEFT_ALIGNMENT);
Component comp = display.getComponent();
((JComponent)comp).setPreferredSize( new Dimension(500,500) );
add(comp);
add(reset);
}
public void actionPerformed(ActionEvent e)
{ resetOrientation(); }
/**
* Resets the display projection to its original value.
* Borrowed from VisAD SpreadSheet
*/
public void resetOrientation() {
if (display != null) {
ProjectionControl pc = display.getProjectionControl();
if (pc != null) {
try {
pc.setMatrix(projMatrix);
}
catch (VisADException exc) {
System.out.println("Cannot reset orientation" + exc);
}
catch (RemoteException exc) {
System.out.println("Cannot reset orientation" + exc);
}
}
}
}
public float[][] calcBeamPath(double elevAngle, double maxRange,
double radarElevation)
throws VisADException,
RemoteException
{
double MAX_RANGE = maxRange;
int BEAMPATHSAMPLING = 400;
double E_ANGLE = elevAngle * RADIANS;
double EFFECTIVE_EARTH_RADIUS = INDEX_OF_REFRACTION * EARTH_RADIUS;
Vector h = new Vector();
Vector r = new Vector();
float[][] heightVals;
float[][] rangeVals;
Linear1DSet r_set = new Linear1DSet(0.0, maxRange+10.0,
BEAMPATHSAMPLING);
float[][] slantRange = r_set.getSamples(true);
Irregular1DSet rangeSet;
FlatField beamPath_ff;
FunctionType rangeHeightFunc = new FunctionType(ran, ht);
for (int i = 0; i < BEAMPATHSAMPLING; i++)
{
double inside = ((Math.pow(slantRange[0][i],2)) +
(Math.pow(EFFECTIVE_EARTH_RADIUS,2))
+
(2*slantRange[0][i]*EFFECTIVE_EARTH_RADIUS*Math.sin(E_ANGLE)));
double outside = EFFECTIVE_EARTH_RADIUS;
Float n = new Float( (float)( (radarElevation/1000) +
((Math.pow(inside,0.5)) - outside)) );
h.add(n);
double numer = (slantRange[0][i]*Math.cos(E_ANGLE));
double denom = (EFFECTIVE_EARTH_RADIUS + n.floatValue() );
double quo = (numer/denom);
Float o = new Float(
(float)(EFFECTIVE_EARTH_RADIUS*Math.asin(quo)) );
r.add(o);
if (n.floatValue() > 25.0)
{ break; }
else if (o.floatValue() > MAX_RANGE)
{ break; }
}
float[][] rangeAndHeight = new float[2][r.size()];
Float[] e = (Float[]) h.toArray(new Float[h.size()]);
Float[] f = (Float[]) r.toArray(new Float[r.size()]);
for (int g = 0; g < h.size(); g++)
{
rangeAndHeight[0][g] = f[g].floatValue();
rangeAndHeight[1][g] = e[g].floatValue();
}
return rangeAndHeight;
}
public static void main(String[] args) throws VisADException,
RemoteException
{
JFrame frame = new JFrame("First VisAd Example");
rangeHeightGridTest me = new rangeHeightGridTest();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(me);
frame.pack();
frame.setVisible(true);
}
}
--
+------------------------------------------------------------+
Kevin L. Manross [KD5MYD] <>< (405)-366-0557
CIMMS Research Associate kevin.manross@xxxxxxxx
[NSSL-WRDD/SWATN] http://www.cimms.ou.edu/~kmanross
"My opinions are my own and not representative of CIMMS, NSSL,
NOAA or any affiliates"
+------------------------------------------------------------+