/* $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;
}
}