/* $RCSfile$ * $Author$ * $Date$ * $Revision$ * * Copyright (C) 2005-2007 The Chemistry Development Kit (CDK) project * * Contact: cdk-devel@lists.sourceforge.net * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 * of the License, or (at your option) any later version. * * This program 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ package org.openscience.cdk.tools; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import javax.vecmath.Point3d; /** * Generates a grid of points in 3D space within given boundaries. * * @author cho * @cdk.githash * @cdk.created 2005-09-30 */ public class GridGenerator { double latticeConstant = 0.5; double extendGrid = 2; double[][][] grid = null; double[] gridArray = null; double maxx = 0; double maxy = 0; double maxz = 0; double minx = 0; double miny = 0; double minz = 0; int[] dim = { 0, 0, 0 }; public GridGenerator() { } public GridGenerator(double min, double max) { setDimension(min, max); generateGrid(); } /** * @param initialValue used as initial value for the grid points */ public GridGenerator(double min, double max, double initialValue) { setDimension(min, max); generateGrid(); initializeGrid(initialValue); } public GridGenerator(double[] minMax, double initialValue, boolean cubicGridFlag) { setDimension(minMax, cubicGridFlag); generateGrid(); initializeGrid(initialValue); } /** * Method sets the maximal 3d dimensions to given min and max values. */ public void setDimension(double min, double max) { this.minx = min; this.maxx = max; this.miny = min; this.maxy = max; this.minz = min; this.maxz = max; } /** * Method sets the maximal 3d dimensions to given min and max values. */ public void setDimension(double[] minMax, boolean cubicGridFlag) { if (cubicGridFlag) { double min = minMax[0]; double max = minMax[0]; for (int i = 0; i < minMax.length; i++) { if (minMax[i] < min) { min = minMax[i]; } else if (minMax[i] > max) { max = minMax[i]; } } setDimension(min, max); } else { this.minx = minMax[0]; this.maxx = minMax[1]; this.miny = minMax[2]; this.maxy = minMax[3]; this.minz = minMax[4]; this.maxz = minMax[5]; } } /** * Method sets the maximal 3d dimensions to given min and max values. */ public void setDimension(double minx, double maxx, double miny, double maxy, double minz, double maxz) { this.minx = minx; this.maxx = maxx; this.miny = miny; this.maxy = maxy; this.minz = minz; this.maxz = maxz; } /** * Main method creates a grid between given boundaries (dimensions). * The grid my be extended over the given boundaries with the * variable extendGrid. */ public void generateGrid() { minx = minx - extendGrid; maxx = maxx + extendGrid; miny = miny - extendGrid; maxy = maxy + extendGrid; minz = minz - extendGrid; maxz = maxz + extendGrid; dim[0] = (int) Math.round(Math.abs(maxx - minx) / latticeConstant); dim[1] = (int) Math.round(Math.abs(maxy - miny) / latticeConstant); dim[2] = (int) Math.round(Math.abs(maxz - minz) / latticeConstant); grid = new double[dim[0] + 1][dim[1] + 1][dim[2] + 1]; } /** * Method initialise the given grid points with a value. */ public void initializeGrid(double value) { for (int i = 0; i < grid.length; i++) { for (int j = 0; j < grid[0].length; j++) { for (int k = 0; k < grid[0][0].length; k++) { grid[k][j][i] = value; } } } } /** * Method initialise the given grid points with a value. */ public double[][][] initializeGrid(double grid[][][], double value) { for (int i = 0; i < grid.length; i++) { for (int j = 0; j < grid[0].length; j++) { for (int k = 0; k < grid[0][0].length; k++) { grid[k][j][i] = value; } } } return grid; } /** * Method transforms the grid to an array. */ public double[] gridToGridArray(double[][][] grid) { if (grid == null) { grid = this.grid; } gridArray = new double[dim[0] * dim[1] * dim[2] + 3]; int dimCounter = 0; for (int z = 0; z < grid[0][0].length; z++) { for (int y = 0; y < grid[0].length; y++) { for (int x = 0; x < grid.length; x++) { gridArray[dimCounter] = grid[x][y][z]; dimCounter++; } } } return gridArray; } /** * Method calculates coordiantes from a given grid point. */ public Point3d getCoordinatesFromGridPoint(Point3d gridPoint) { double dx = minx + latticeConstant * gridPoint.x; double dy = miny + latticeConstant * gridPoint.y; double dz = minz + latticeConstant * gridPoint.z; return new Point3d(dx, dy, dz); } /** * Method calculates coordiantes from a given grid array position. */ public Point3d getCoordinatesFromGridPoint(int gridPoint) { int dimCounter = 0; Point3d point = new Point3d(0, 0, 0); for (int z = 0; z < grid[0][0].length; z++) { for (int y = 0; y < grid[0].length; y++) { for (int x = 0; x < grid.length; x++) { if (dimCounter == gridPoint) { point.x = minx + latticeConstant * x; point.y = miny + latticeConstant * y; point.z = minz + latticeConstant * z; return point; } dimCounter++; } } } return point; } /** * Method calculates the nearest grid point from given coordinates. */ public Point3d getGridPointFrom3dCoordinates(Point3d coord) throws Exception { Point3d gridPoint = new Point3d(); if (coord.x >= minx & coord.x <= maxx) { gridPoint.x = (int) Math.round(Math.abs(minx - coord.x) / latticeConstant); } else { throw new Exception( "CDKGridError: Given coordinates are not in grid"); } if (coord.y >= miny & coord.y <= maxy) { gridPoint.y = (int) Math.round(Math.abs(miny - coord.y) / latticeConstant); } else { throw new Exception( "CDKGridError: Given coordinates are not in grid"); } if (coord.z >= minz & coord.z <= maxz) { gridPoint.z = (int) Math.round(Math.abs(minz - coord.z) / latticeConstant); } else { throw new Exception( "CDKGridError: Given coordinates are not in grid"); } return gridPoint; } /** * Method transforms the grid into pmesh format. */ public void writeGridInPmeshFormat(String outPutFileName) throws IOException { BufferedWriter writer = new BufferedWriter(new FileWriter( outPutFileName + ".pmesh")); int numberOfGridPoints = grid.length * grid[0].length * grid[0][0].length; writer.write(numberOfGridPoints + "\n"); for (int z = 0; z < grid[0][0].length; z++) { for (int y = 0; y < grid[0].length; y++) { for (int x = 0; x < grid.length; x++) { Point3d coords = getCoordinatesFromGridPoint(new Point3d(x, y, z)); writer.write(coords.x + "\t" + coords.y + "\t" + coords.z + "\n"); } } } writer.close(); } /** * Method transforms the grid into pmesh format. Only grid points * with specific value defined with cutoff are considered. * <pre> * cutoff <0, the values considered must be <=cutoff * cutoff >0, the values considered must be >=cutoff * </pre> */ public void writeGridInPmeshFormat(String outPutFileName, double cutOff) throws IOException { BufferedWriter writer = new BufferedWriter(new FileWriter( outPutFileName + ".pmesh")); boolean negative = false; if (cutOff < 0) { negative = true; } else { negative = false; } int numberOfGridPoints = 0; for (int z = 0; z < grid[0][0].length; z++) { for (int y = 0; y < grid[0].length; y++) { for (int x = 0; x < grid.length; x++) { if (negative) { if (grid[x][y][z] <= cutOff) { numberOfGridPoints++; } } else { if (grid[x][y][z] >= cutOff) { numberOfGridPoints++; } } } } } writer.write(numberOfGridPoints + "\n"); for (int z = 0; z < grid[0][0].length; z++) { for (int y = 0; y < grid[0].length; y++) { for (int x = 0; x < grid.length; x++) { Point3d coords = getCoordinatesFromGridPoint(new Point3d(x, y, z)); if (negative) { if (grid[x][y][z] <= cutOff) { writer.write(coords.x + "\t" + coords.y + "\t" + coords.z + "\n"); } } else { if (grid[x][y][z] >= cutOff) { writer.write(coords.x + "\t" + coords.y + "\t" + coords.z + "\n"); } } } } } writer.close(); } public String toString() { return "Dim:" + dim + " SizeX:" + grid.length + " SizeY:" + grid[0].length + " SizeZ:" + grid[0][0].length + "\nminx:" + minx + " maxx:" + maxx + "\nminy:" + miny + " maxy:" + maxy + "\nminz:" + minz + " maxz:" + maxz; } /** * @return Returns the dim. */ public int[] getDim() { return dim; } /** * @param dim The dim to set. */ public void setDim(int[] dim) { this.dim = dim; } /** * @return Returns the extendGrid. */ public double getExtendGrid() { return extendGrid; } /** * @param extendGrid The extendGrid to set. */ public void setExtendGrid(double extendGrid) { this.extendGrid = extendGrid; } /** * @return Returns the grid. */ public double[][][] getGrid() { return grid; } /** * @param grid The grid to set. */ public void setGrid(double[][][] grid) { this.grid = grid; } /** * @return Returns the latticeConstant. */ public double getLatticeConstant() { return latticeConstant; } /** * @param latticeConstant The latticeConstant to set. */ public void setLatticeConstant(double latticeConstant) { this.latticeConstant = latticeConstant; } /** * @return Returns the gridArray. */ public double[] getGridArray() { return gridArray; } /** * @return Returns the maxx. */ public double getMaxx() { return maxx; } /** * @return Returns the maxy. */ public double getMaxy() { return maxy; } /** * @return Returns the maxz. */ public double getMaxz() { return maxz; } /** * @return Returns the minx. */ public double getMinx() { return minx; } /** * @return Returns the miny. */ public double getMiny() { return miny; } /** * @return Returns the minz. */ public double getMinz() { return minz; } }