package org.math.plot.plots;
import java.awt.*;
import org.math.plot.*;
import org.math.plot.render.*;
import org.math.plot.utils.Array;
public class HistogramPlot3D extends Plot {
double[][] topNW;
double[][] topNE;
double[][] topSW;
double[][] topSE;
double[][] bottomNW;
double[][] bottomNE;
double[][] bottomSW;
double[][] bottomSE;
double[][] widths;
double[] width_constant = {-1, -1};
double[][] XY;
boolean fill_shape = true;
public HistogramPlot3D(String n, Color c, double[][] _XY, double[][] w) {
super(n, c);
XY = _XY;
widths = w;
build();
}
public HistogramPlot3D(String n, Color c, double[][] _XY, double wX, double wY) {
super(n, c);
XY = _XY;
width_constant = new double[]{wX, wY};
build();
}
public HistogramPlot3D(String n, Color c, double[][] _XY, double[] w) {
super(n, c);
XY = _XY;
width_constant = w;
build();
}
private void build() {
if (width_constant[0] > 0) {
topNW = new double[XY.length][];
topNE = new double[XY.length][];
topSW = new double[XY.length][];
topSE = new double[XY.length][];
bottomNW = new double[XY.length][];
bottomNE = new double[XY.length][];
bottomSW = new double[XY.length][];
bottomSE = new double[XY.length][];
for (int i = 0; i < XY.length; i++) {
topNW[i] = new double[]{XY[i][0] - width_constant[0] / 2, XY[i][1] + width_constant[1] / 2, XY[i][2]};
topNE[i] = new double[]{XY[i][0] + width_constant[0] / 2, XY[i][1] + width_constant[1] / 2, XY[i][2]};
topSW[i] = new double[]{XY[i][0] - width_constant[0] / 2, XY[i][1] - width_constant[1] / 2, XY[i][2]};
topSE[i] = new double[]{XY[i][0] + width_constant[0] / 2, XY[i][1] - width_constant[1] / 2, XY[i][2]};
bottomNW[i] = new double[]{XY[i][0] - width_constant[0] / 2, XY[i][1] + width_constant[1] / 2, 0};
bottomNE[i] = new double[]{XY[i][0] + width_constant[0] / 2, XY[i][1] + width_constant[1] / 2, 0};
bottomSW[i] = new double[]{XY[i][0] - width_constant[0] / 2, XY[i][1] - width_constant[1] / 2, 0};
bottomSE[i] = new double[]{XY[i][0] + width_constant[0] / 2, XY[i][1] - width_constant[1] / 2, 0};
}
} else {
topNW = new double[XY.length][];
topNE = new double[XY.length][];
topSW = new double[XY.length][];
topSE = new double[XY.length][];
bottomNW = new double[XY.length][];
bottomNE = new double[XY.length][];
bottomSW = new double[XY.length][];
bottomSE = new double[XY.length][];
for (int i = 0; i < XY.length; i++) {
topNW[i] = new double[]{XY[i][0] - widths[i][0] / 2, XY[i][1] + widths[i][1] / 2, XY[i][2]};
topNE[i] = new double[]{XY[i][0] + widths[i][0] / 2, XY[i][1] + widths[i][1] / 2, XY[i][2]};
topSW[i] = new double[]{XY[i][0] - widths[i][0] / 2, XY[i][1] - widths[i][1] / 2, XY[i][2]};
topSE[i] = new double[]{XY[i][0] + widths[i][0] / 2, XY[i][1] - widths[i][1] / 2, XY[i][2]};
bottomNW[i] = new double[]{XY[i][0] - widths[i][0] / 2, XY[i][1] + widths[i][1] / 2, 0};
bottomNE[i] = new double[]{XY[i][0] + widths[i][0] / 2, XY[i][1] + widths[i][1] / 2, 0};
bottomSW[i] = new double[]{XY[i][0] - widths[i][0] / 2, XY[i][1] - widths[i][1] / 2, 0};
bottomSE[i] = new double[]{XY[i][0] + widths[i][0] / 2, XY[i][1] - widths[i][1] / 2, 0};
}
}
}
public void plot(AbstractDrawer draw, Color c) {
if (!visible) {
return;
}
draw.canvas.includeInBounds(bottomSW[0]);
draw.canvas.includeInBounds(topNE[XY.length - 1]);
draw.setColor(c);
draw.setLineType(AbstractDrawer.CONTINOUS_LINE);
for (int i = 0; i < XY.length; i++) {
if (topNW[i][2] != bottomNW[i][2]) {
draw.drawLine(topNW[i], topNE[i]);
draw.drawLine(topNE[i], topSE[i]);
draw.drawLine(topSE[i], topSW[i]);
draw.drawLine(topSW[i], topNW[i]);
draw.drawLine(bottomNW[i], bottomNE[i]);
draw.drawLine(bottomNE[i], bottomSE[i]);
draw.drawLine(bottomSE[i], bottomSW[i]);
draw.drawLine(bottomSW[i], bottomNW[i]);
draw.drawLine(bottomNW[i], topNW[i]);
draw.drawLine(bottomNE[i], topNE[i]);
draw.drawLine(bottomSE[i], topSE[i]);
draw.drawLine(bottomSW[i], topSW[i]);
if (fill_shape) {
draw.fillPolygon(0.2f, topNW[i], topNE[i], topSE[i], topSW[i]);
//draw.fillPolygon(bottomNW[i], bottomNE[i], bottomSE[i], bottomSW[i]);
/*draw.fillPolygon(topNW[i], topNE[i], bottomNE[i], bottomNW[i]);
draw.fillPolygon(topSW[i], topSE[i], bottomSE[i], bottomSW[i]);
draw.fillPolygon(topNE[i], topSE[i], bottomSE[i], bottomNE[i]);
draw.fillPolygon(topNW[i], topSW[i], bottomSW[i], bottomNW[i]);*/
}
}
}
}
@Override
public void setData(double[][] d) {
datapanel = null;
XY = d;
}
@Override
public double[][] getData() {
return XY;
}
@Override
public double[][] getBounds() {
return new double[][]{Array.min(bottomSW), Array.max(topNE)};
}
public void setDataWidth(double[][] w) {
widths = w;
}
public void setDataWidth(double... w) {
width_constant = w;
build();
}
public double[][] getDataWidth() {
if (width_constant[0] > 0) {
widths = new double[XY.length][2];
for (int i = 0; i < widths.length; i++) {
widths[i][0] = width_constant[0];
widths[i][1] = width_constant[1];
}
}
return widths;
}
public void setData(double[][] d, double[][] w) {
setData(d);
widths = w;
}
public void setData(double[][] d, double... w) {
setData(d);
setDataWidth(w);
}
public double[] isSelected(int[] screenCoordTest, AbstractDrawer draw) {
for (int i = 0; i < XY.length; i++) {
int[] screenCoord = draw.project(XY[i]);
if ((screenCoord[0] + note_precision > screenCoordTest[0]) && (screenCoord[0] - note_precision < screenCoordTest[0])
&& (screenCoord[1] + note_precision > screenCoordTest[1]) && (screenCoord[1] - note_precision < screenCoordTest[1])) {
return XY[i];
}
}
return null;
}
public static void main(String[] args) {
double[][] XY = new double[500][2];
for (int i = 0; i < XY.length; i++) {
XY[i][0] = Math.random() + Math.random();
XY[i][1] = Math.random() + Math.random();
}
Plot3DPanel p = new Plot3DPanel("SOUTH");
p.addHistogramPlot("test", XY, 4, 6);
new FrameView(p);
}
}