package com.aerodynelabs.habtk.charts;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.geom.Rectangle2D;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.CrosshairState;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.AbstractXYItemRenderer;
import org.jfree.chart.renderer.xy.XYItemRendererState;
import org.jfree.data.xy.XYDataset;
import org.jfree.ui.RectangleEdge;
import com.aerodynelabs.habtk.atmosphere.AtmosphereProfile;
@SuppressWarnings("serial")
public class WindPlot extends XYPlot {
private AtmosphereSeriesCollection data;
public WindPlot() {
super();
data = new AtmosphereSeriesCollection(
AtmosphereSeriesCollection.DOMAIN_PRESSURE,
AtmosphereSeriesCollection.RANGE_WIND);
PressureAxis pAxis = new PressureAxis("Pressure (mbar)");
NumberAxis wAxis = new NumberAxis("Speed (m/s)");
setDomainGridlinePaint(Color.BLACK);
setDomainGridlineStroke(new BasicStroke(1.0f));
setDataset(data);
setOrientation(PlotOrientation.HORIZONTAL);
setDomainAxis(pAxis);
setRangeAxis(wAxis);
setRenderer(new WindVectorRenderer());
}
public void setProfile(AtmosphereProfile profile) {
data.setProfile(profile);
super.fireChangeEvent();
}
public AtmosphereProfile getProfile() {
return data.getProfile();
}
class WindVectorRenderer extends AbstractXYItemRenderer {
private static final int barbLength = 15;
private static final int fletchLength = 8;
public WindVectorRenderer() {
super();
}
@Override
public void drawItem(
Graphics2D g2,
XYItemRendererState state,
Rectangle2D plotArea,
PlotRenderingInfo info,
XYPlot plot,
ValueAxis domainAxis,
ValueAxis rangeAxis,
XYDataset dataset,
int series, int item,
CrosshairState crosshairState,
int pass) {
if(pass > 0) return;
AtmosphereSeriesCollection data = (AtmosphereSeriesCollection) dataset;
Paint seriesPaint = null;
if(series == 0) {
seriesPaint = Color.RED;
} else {
seriesPaint = Color.BLUE;
}
Stroke seriesStroke = getItemStroke(series, item);
g2.setPaint(seriesPaint);
g2.setStroke(seriesStroke);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
double alt = data.getXValue(series, item);
double spd = data.getYValue(0, item);
double dir = Math.toRadians(data.getYValue(1, item));
RectangleEdge domainLocation = plot.getDomainAxisEdge();
RectangleEdge rangeLocation = plot.getRangeAxisEdge();
if(series == 0) { // Draw vector
// Draw barb
double ox = rangeAxis.valueToJava2D(0.0, plotArea, rangeLocation) + barbLength * 1.5;
double oy = domainAxis.valueToJava2D(alt, plotArea, domainLocation);
double dx = barbLength * Math.sin(dir);
double dy = -barbLength * Math.cos(dir);
g2.drawLine((int)(ox + 0.5), (int)(oy + 0.5), (int)(ox + dx + 0.5), (int)(oy + dy + 0.5));
// Draw fletching
ox = ox + dx;
oy = oy + dy;
double s = spd * 1.944;
while(s > 0) {
dx = 0;
dy = 0;
if(s > 50) {
dx = fletchLength * Math.sin(dir + (Math.PI/3));
dy = -fletchLength * Math.cos(dir + (Math.PI/3));
double tx = 3 * Math.sin(dir);
double ty = -3 * Math.cos(dir);
int x[] = {(int)(ox + 0.5), (int)(ox + dx + 0.5), (int)(ox + tx + 0.5)};
int y[] = {(int)(oy + 0.5), (int)(oy + dy + 0.5), (int)(oy + ty + 0.5)};
g2.fillPolygon(x, y, 3);
dx = 0;
dy = 0;
s = s - 50;
} else if(s > 10) {
dx = fletchLength * Math.sin(dir + (Math.PI/3));
dy = -fletchLength * Math.cos(dir + (Math.PI/3));
s = s - 10;
} else if(s > 5) {
dx = 0.5 * fletchLength * Math.sin(dir + (Math.PI/3));
dy = -0.5 * fletchLength * Math.cos(dir + (Math.PI/3));
s = s - 5;
} else {
s = 0;
}
g2.drawLine((int)(ox + 0.5), (int)(oy + 0.5), (int)(ox + dx + 0.5), (int)(oy + dy + 0.5));
dx = 3 * Math.sin(dir + Math.PI);
dy = -3 * Math.cos(dir + Math.PI);
ox = ox + dx;
oy = oy + dy;
}
} else if(series == 1) { // Draw line series
if(item == 0) return;
double x1 = rangeAxis.valueToJava2D(spd, plotArea, rangeLocation);
double y1 = domainAxis.valueToJava2D(alt, plotArea, domainLocation);
double pAlt = data.getXValue(series, item - 1);
double pSpd = data.getYValue(0, item - 1);
double x2 = rangeAxis.valueToJava2D(pSpd, plotArea, rangeLocation);
double y2 = domainAxis.valueToJava2D(pAlt, plotArea, domainLocation);
g2.drawLine((int)(x1 + 0.5), (int)(y1 + 0.5), (int)(x2 + 0.5), (int)(y2 + 0.5));
}
}
}
}