/* * Open Source Physics software is free software as described near the bottom of this code file. * * For additional information and documentation on Open Source Physics please see: * <http://www.opensourcephysics.org/> */ package org.opensourcephysics.display; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Shape; import java.awt.geom.AffineTransform; import java.awt.geom.GeneralPath; import java.awt.geom.Point2D; /** * Grid draws a rectangular grid on a data panel. * * @author Wolfgang Christian * @version 1.0 */ public class Grid implements Drawable { protected int nx, ny; // number of cells in x and y directions protected double xmin, xmax, ymin, ymax; protected double dx, dy; protected Color color = new Color(200, 200, 200, 100); protected GeneralPath generalPath = new GeneralPath(); protected boolean visible = true; /** * Constructs a square grid of the given size with a spacing of 1. * @param n number of cells on a side */ public Grid(int n) { this(n, n, 0, n, 0, n); } /** * Constructs an (nx,ny) grid an x spacing of 1 and a y spacing of 1. * * @param nx the number of grid lines in the x direction * @param ny the number of grid lines in the y direction */ public Grid(int nx, int ny) { this(nx, ny, 0, nx, 0, ny); } /** * Constructs a grid with the given number of x and y points and the given range. * * @param _nx the number of grid lines in the x direction * @param _ny the number of grid lines in the y direction * @param xmin * @param xmax * @param ymin * @param ymax */ public Grid(int _nx, int _ny, double xmin, double xmax, double ymin, double ymax) { nx = _nx; ny = _ny; setMinMax(xmin, xmax, ymin, ymax); } /** * Sets the visible flag. * Drawing will be disabled if visible is false. * * @param isVisible */ public void setVisible(boolean isVisible) { visible = isVisible; } /** * Checks if the grid is visible. * * @return true if visible; false otherwise */ public boolean isVisible() { return visible; } /** * Sets the drawing color. * * @param _color */ public void setColor(Color _color) { color = _color; } /** * Gets the drawing color. * * @return the color */ public Color getColor() { return color; } /** * Gets the x separation between x gid lines. * @return dx */ public double getDx() { return dx; } /** * Gets the minimum value of x. * @return xmin */ public double getXMin() { return xmin; } /** * Gets the maximum value of x. * @return xamx */ public double getXMax() { return xmax; } /** * Gets the minimum value of y. * @return ymin */ public double getYMin() { return ymin; } /** * Gets the maximum value of y. * @return ymax */ public double getYMax() { return ymax; } /** * Gets the y separation between x gid lines. * @return dy */ public double getDy() { return dy; } /** * Assigns a scale to the grid in world units. * * @param _xmin * @param _xmax * @param _ymin * @param _ymax */ public void setMinMax(double _xmin, double _xmax, double _ymin, double _ymax) { generalPath.reset(); xmin = (float) _xmin; xmax = (float) _xmax; ymin = (float) _ymin; ymax = (float) _ymax; if(nx>0) { dx = (float) ((xmax-xmin)/nx); } else { dx = 1; } if(ny>0) { dy = (float) ((ymax-ymin)/ny); } else { dy = 1; } if(!visible) { // don't calculate the general path unless this grid is visible return; } float y = (float) ymin; if(ny<=512) { for(int i = 0; i<=ny; i++) { generalPath.moveTo((float) xmin, y); generalPath.lineTo((float) xmax, y); y += dy; } } float x = (float) xmin; if(nx<=512) { for(int i = 0; i<=nx; i++) { generalPath.moveTo(x, (float) ymin); generalPath.lineTo(x, (float) ymax); x += dx; } } } public void draw(DrawingPanel panel, Graphics g) { if(!visible) { return; } if(Math.abs(panel.getXPixPerUnit()*(xmax-xmin)/nx)<4) { return; } if(Math.abs(panel.getYPixPerUnit()*(ymax-ymin)/ny)<4) { return; } Graphics2D g2 = (Graphics2D) g; AffineTransform at = panel.getPixelTransform(); Shape s = generalPath.createTransformedShape(at); g2.setColor(color); g2.draw(s); g2.setColor(Color.black); } /** * Gets the cell column and row index for the specified location */ public int[] getCellPoint(double x, double y) { int xindex = 0; xindex = (int) Math.floor((x-xmin)/dx); xindex = Math.max(0, xindex); // cannot be less than xmin xindex = Math.min(nx, xindex); // cannot be greater than xmax int yindex = 0; yindex = (int) Math.floor((y-ymin)/dy); yindex = Math.max(0, yindex); // cannot be less than ymin yindex = Math.min(ny, yindex); // cannot be greater than ymax return new int[] {xindex, xindex}; } /** * Gets the grid point closest to the specified location */ public Point2D.Double getClosestGridPoint(double x, double y) { int index = 0; index = (int) Math.round((x-xmin)/dx); index = Math.max(0, index); // cannot be less than xmin index = Math.min(nx, index); // cannot be greater than xmax double gridx = xmin+dx*index; index = (int) Math.round((y-ymin)/dy); index = Math.max(0, index); // cannot be less than ymin index = Math.min(ny, index); // cannot be greater than ymax double gridy = ymin+dy*index; return new Point2D.Double(gridx, gridy); } } /* * Open Source Physics software is free software; you can redistribute * it and/or modify it under the terms of the GNU General Public License (GPL) as * published by the Free Software Foundation; either version 2 of the License, * or(at your option) any later version. * Code that uses any portion of the code in the org.opensourcephysics package * or any subpackage (subdirectory) of this package must must also be be released * under the GNU GPL license. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston MA 02111-1307 USA * or view the license online at http://www.gnu.org/copyleft/gpl.html * * Copyright (c) 2007 The Open Source Physics project * http://www.opensourcephysics.org */