For the following experiments I need a 3D plot. Because I wanted to know how to make a 3D plot I programmed it myself. There is a lot of information on the internet and a lot of examples. This is how I did it:
package util;
import java.awt.Color;
import java.awt.Frame;
public class ShowPlot3d extends Frame {
/**
*
*/
private static final long serialVersionUID = 1L;
private double[][] plotData3d;
java.awt.Button panL = new java.awt.Button();
java.awt.Button panR = new java.awt.Button();
java.awt.Button showMin = new java.awt.Button();
java.awt.Button showMax = new java.awt.Button();
java.awt.Button zoomIn = new java.awt.Button();
java.awt.Button zoomOut = new java.awt.Button();
java.awt.TextArea txaInfo = new java.awt.TextArea();
String txaText = "";
public int zoomFactor = 1;
String title;
public ShowPlot3d(int id) {
plotData3d = null;
setLayout(null);
setSize(1000, 768);
setTitle("Show Figure " + id);
SymWindow aSymWindow = new SymWindow();
this.addWindowListener(aSymWindow);
setVisible(false);
panL.setLabel("panL");
add(panL);
panR.setLabel("panR");
add(panR);
showMin.setLabel("minimum");
add(showMin);
showMax.setLabel("maximum");
add(showMax);
zoomIn.setLabel("zoom in");
add(zoomIn);
zoomOut.setLabel("zoom out");
add(zoomOut);
SymAction lSymAction = new SymAction();
panL.setBackground(java.awt.Color.lightGray);
panL.setBounds(10, 30, 150, 40);
panL.addActionListener(lSymAction);
panR.setBackground(java.awt.Color.lightGray);
panR.setBounds(160, 30, 150, 40);
panR.addActionListener(lSymAction);
showMin.setBackground(java.awt.Color.lightGray);
showMin.setBounds(310, 30, 150, 40);
showMin.addActionListener(lSymAction);
showMax.setBackground(java.awt.Color.lightGray);
showMax.setBounds(460, 30, 150, 40);
showMax.addActionListener(lSymAction);
zoomIn.setBackground(java.awt.Color.lightGray);
zoomIn.setBounds(10, 70, 150, 40);
zoomIn.addActionListener(lSymAction);
zoomOut.setBackground(java.awt.Color.lightGray);
zoomOut.setBounds(160, 70, 150, 40);
zoomOut.addActionListener(lSymAction);
add(txaInfo);
txaInfo.setBounds(610, 30, 200, 200);
txaInfo.setVisible(true);
}
public ShowPlot3d(int id, double[][] plotData3d) {
this(id);
this.plotData3d = plotData3d;
}
public ShowPlot3d(int id, double[][] plotData3d, String title) {
this(id, plotData3d);
this.title = title;
}
class SymWindow extends java.awt.event.WindowAdapter {
public void windowActivated(java.awt.event.WindowEvent event) {
Object object = event.getSource();
if (object == ShowPlot3d.this)
ShowPlot_WindowActivated(event);
}
public void windowClosing(java.awt.event.WindowEvent event) {
Object object = event.getSource();
if (object == ShowPlot3d.this)
ShowPlot_WindowClosing(event);
}
public void windowStateChanged(java.awt.event.WindowEvent event) {
Object object = event.getSource();
if (object == ShowPlot3d.this)
ShowPlot_windowStateChanged(event);
}
}
class SymAction implements java.awt.event.ActionListener {
public void actionPerformed(java.awt.event.ActionEvent event) {
Object object = event.getSource();
if (object == panL)
panL_ActionPerformed(event);
else if (object == panR)
panR_ActionPerformed(event);
else if (object == showMin)
showMin_ActionPerformed(event);
else if (object == showMax)
showMax_ActionPerformed(event);
else if (object == zoomIn)
zoomIn_ActionPerformed(event);
else if (object == zoomOut)
zoomOut_ActionPerformed(event);
}
}
int shift = 0;
void panR_ActionPerformed(java.awt.event.ActionEvent event) {
shift += 100;
txaText += "\n" + "shift = " + shift;
txaInfo.setText(txaText);
repaint();
}
void panL_ActionPerformed(java.awt.event.ActionEvent event) {
shift -= 100;
txaText += "\n" + "shift = " + shift;
txaInfo.setText(txaText);
repaint();
}
void showMin_ActionPerformed(java.awt.event.ActionEvent event) {
shift = xlocmin - 500;
txaText += "\n" + "min = " + minData;
txaInfo.setText(txaText);
repaint();
}
void showMax_ActionPerformed(java.awt.event.ActionEvent event) {
shift = xlocmax - 500;
txaText += "\n" + "max = " + maxData;
txaText += "\n" + "x = " + xlocmax;
txaText += "\n" + "y = " + ylocmax;
txaInfo.setText(txaText);
repaint();
}
void zoomOut_ActionPerformed(java.awt.event.ActionEvent event) {
shift = shift * zoomFactor;
zoomFactor++;
shift = shift / zoomFactor;
txaText += "\n" + "zoomFactor = " + zoomFactor;
txaInfo.setText(txaText);
repaint();
}
void zoomIn_ActionPerformed(java.awt.event.ActionEvent event) {
shift = shift * zoomFactor;
zoomFactor--;
if (zoomFactor <= 0) {
zoomFactor = 1;
}
shift = shift / zoomFactor;
txaText += "\n" + "zoomFactor = " + zoomFactor;
txaInfo.setText(txaText);
repaint();
}
void ShowPlot_WindowClosing(java.awt.event.WindowEvent event) {
setVisible(false); // hide the Frame
System.exit(0);
}
public void ShowPlot_WindowActivated(java.awt.event.WindowEvent event) {
// setVisible(true);
}
public void ShowPlot_windowStateChanged(java.awt.event.WindowEvent event) {
repaint();
}
public void showFigure() {
this.requestFocus();
this.setEnabled(true);
setVisible(true);
setTitle(title);
repaint();
}
public void setZoomFactor(int zoomFactor) {
this.zoomFactor = zoomFactor;
}
double minData = 0;
double maxData = 0;
int xlocmin = 0;
int ylocmin = 0;
int xlocmax = 0;
int ylocmax = 0;
boolean plotSaved = false;
double[] origPlotData;
public void paint(java.awt.Graphics gc) {
// 3D graphics
int height = getHeight();
int width = getWidth();
double phix = 15; // degrees
double phiy = 10; // degrees
double phixrad = (phix / 180) * Math.PI;
double phiyrad = (phiy / 180) * Math.PI;
int xmax3d = plotData3d.length;
int ymax3d = plotData3d[0].length;
int origx = shift + width / 5;
int origy = 2 * height / 3;
// determine min and max z-value
minData = plotData3d[0][0];
maxData = plotData3d[0][0];
for (int x = 0; x < xmax3d; x++) {
for (int y = 0; y < ymax3d; y++) {
double sample = plotData3d[x][y];
if (sample < minData) {
minData = sample;
xlocmin = x;
ylocmin = y;
}
if (sample > maxData) {
maxData = sample;
xlocmax = x;
ylocmax = y;
}
}
}
double rangez = maxData - minData;
double maxhi = 0.4 * height;
double zscale = maxhi / rangez;
for (int x = 0; x < xmax3d; x++) {
for (int y = 0; y < ymax3d; y++) {
int xx = 2 * x;
int yy = 20 * y;
double z3d = plotData3d[x][y];
int xfrom = (int) (origx + xx * Math.cos(phixrad) + yy
* Math.cos(phiyrad)) / 2;
int yfrom = (int) (origy - xx * Math.sin(phixrad) + yy
* Math.sin(phiyrad)) / 2;
int zz = (int) (z3d * zscale);
gc.setColor(Color.blue);
if (zz > (maxhi * 0.25)) {
gc.setColor(Color.green);
}
if (zz > (maxhi * 0.5)) {
gc.setColor(Color.yellow);
}
if (zz > (maxhi * 0.75)) {
gc.setColor(Color.red);
}
gc.drawLine(xfrom, height - yfrom, xfrom, height - yfrom - zz);
}
}
}
}
|
The test-input for the plot-class:
public void fillArray15() { // use fake-data to test 3d-display
int xmax3d = 1023;
int ymax3d = 32;
double[][] plotData3d = new double[xmax3d][ymax3d];
System.out.println("plotData3d[0].length = " + plotData3d[0].length);
System.out.println("plotData3d.length = " + plotData3d.length);
Random r = new Random();
int noise = 5;
for (int x = 0; x < xmax3d; x++) {
for (int y = 0; y < ymax3d; y++) {
int peak = 0;
if (x > 300 && x < 320 && y == 20) {
peak = 20;
} else {
peak = 1;
}
plotData3d[x][y] = peak * Math.abs(noise * r.nextGaussian());
}
}
int id = 1;
ShowPlot3d myPlot = new ShowPlot3d(id, plotData3d, "just testing 3d display");
myPlot.showFigure();
}
|
and the output of this all: