package org.lemsml.jlems.viz.plot; public final class Box { double xmin; double xmax; double ymin; double ymax; double subdivDx; double subdivDy; private boolean noXdata; private boolean noYdata; public Box(Position p) { this(p.getX(), p.getY()); } public Box(double x, double y) { xmin = x; xmax = x; ymin = y; ymax = y; noXdata = false; noYdata = false; } public Box() { noXdata = true; noYdata = true; } public Box(double x0, double y0, double x1, double y1) { xmin = x0; ymin = y0; xmax = x1; ymax = y1; noXdata = false; noYdata = false; } public Box makeCopy() { return new Box(xmin, ymin, xmax, ymax); } public String toString() { return " Box x0=" + xmin + " y0=" + ymin + " x1=" + xmax + " y1=" + xmax; } public void setXMin(double d) { xmin = d; } public void setXMax(double d) { xmax = d; } public void setYMin(double d) { ymin = d; } public void setYMax(double d) { ymax = d; } public double getXmin() { return xmin; } public double getXmax() { return xmax; } public double getYmin() { return ymin; } public double getYmax() { return ymax; } public void subdivide(int n) { subdivDx = (xmax - xmin) / n; subdivDy = (ymax - ymin) / n; } public int getXSubdivision(double x) { int ret = (int)((x - xmin) / subdivDx); return ret; } public int getYSubdivision(double y) { int ret = (int)((y - ymin) / subdivDy); return ret; } public int getXSubdivision(double x, int n) { double dx = (xmax - xmin) / n; int ret = (int)((x - xmin) / dx); return ret; } public int getYSubdivision(double y, int n) { double dy = (ymax - ymin) / n; int ret = (int)((y - ymin) / dy); return ret; } public void extendTo(Position p) { extendTo(p.getX(), p.getY()); } public void extendTo(Box b) { extendTo(b.xmin, b.ymin); extendTo(b.xmax, b.ymax); } public void extendTo(double[] xp, double[] yp) { for (int i = 0; i < xp.length; i++) { extendTo(xp[i], yp[i]); } } public boolean hasData() { return (! (noXdata || noYdata)); } public void extendXTo(double x) { if (noXdata) { xmin = x; xmax = x; noXdata = false; } if (x < xmin) { xmin = x; } if (x > xmax) { xmax = x; } } public void extendTo(double x, double y) { extendXTo(x); extendYTo(y); } public void extendYTo(double y) { if (noYdata) { ymin = y; ymax = y; noYdata = false; } if (y < ymin) { ymin = y; } if (y > ymax) { ymax = y; } } public void pad() { enlarge(0.1); } public void enlarge(double f) { double dx = f * (xmax - xmin); double dy = f * (ymax - ymin); xmin -= dx; xmax += dx; ymin -= dy; ymax += dy; } public void push(double x, double y) { extendTo(x, y); } public void push(double[] x, double[] y) { pushX(x, x.length); pushY(y, y.length); } public void pushX(double[] v) { pushX(v, v.length); } public void pushX(double[] v, int np) { if (np > 0 && noXdata) { xmin = v[0]; xmax = v[0]; noXdata = false; } for (int i = 0; i < np; i++) { double d = v[i]; if (xmin > d) { xmin = d; } if (xmax < d) { xmax = d; } } } public void pushY(double d) { if (noYdata) { ymin = d; ymax = d; } else { if (ymin > d) { ymin = d; } if (ymax < d) { ymax = d; } } } public void pushY(double[] d) { pushY(d, d.length); } public void pushY(double[] v, int np) { if (np > 0 && noYdata) { ymin = v[0]; ymax = v[0]; noYdata = false; } for (int i = 0; i < np; i++) { double d = v[i]; if (ymin > d) { ymin = d; } if (ymax < d) { ymax = d; } } } public void push(Position position) { extendTo(position.getX(), position.getY()); } public boolean differentFrom(Box b, double d) { boolean ret = false; if (hasData() && b.hasData()) { if (rangesDiffer(xmin, xmax, b.xmin, b.xmax, d) || rangesDiffer(ymin, ymax, b.ymin, b.ymax, d)) { ret = true; } } return ret; } private boolean rangesDiffer(double a, double b, double c, double d, double delta) { boolean ret = false; double u = 0.5 * (b - a + d - c); double f1 = (c - a) / u; double f2 = (d - b) / u; ret = (Math.abs(f1) > delta || Math.abs(f2) > delta); if (ret) { // E.info("ranges differ " + a + " " + b + " " + c + " " + d); } return ret; } public Position getCenter() { double cx = 0.5 * (xmin + xmax); double cy = 0.5 * (ymin + ymax); return new Position(cx, cy); } public double getRadius() { double dx = xmax - xmin; double dy = ymax - ymin; double scl = 0.5 * Math.max(dx, dy); return scl; } public void tidyLimits() { if (xmin > 0. && (xmax - xmin) / xmin > 5.) { xmin = 0.; } else if (xmin < 0. && (xmax - xmin) / -xmin > 20.) { xmin = 0.; } if (ymin > 0. && (ymax - ymin) / ymin > 5.) { ymin = 0.; } else if (ymin < 0. && (ymax - ymin) / -ymin > 20.) { ymin = 0.; } } public void push(double[] xpts, double[] ypts, int npts) { pushX(xpts, npts); pushY(ypts, npts); } }