/* * Copyright (C) 2004-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.geometry.surface; import org.openscience.cdk.interfaces.IAtom; import java.util.ArrayList; import java.util.HashMap; import java.util.List; /** * Creates a list of atoms neighboring each atom in the molecule. * * <p>The routine is a simplified version of the neighbor list described * in {@cdk.cite EIS95} and is based on the implementation by Peter McCluskey. * Due to the fact that it divides the cube into a fixed number of sub cubes, * some accuracy may be lost. * * @author Rajarshi Guha * @cdk.created 2005-05-09 * @cdk.module extra * @cdk.githash */ public class NeighborList { HashMap<String,List> boxes; double boxSize; IAtom[] atoms; public NeighborList(IAtom[] atoms, double radius) { this.atoms = atoms; this.boxes = new HashMap<String,List>(); this.boxSize = 2 * radius; for (int i = 0; i < atoms.length; i++) { String key = getKeyString(atoms[i]); if (this.boxes.containsKey(key)) { List arl = this.boxes.get(key); arl.add(i); this.boxes.put( key, arl ); } else { this.boxes.put( key, new ArrayList() ); } } } private String getKeyString(IAtom atom) { double x = atom.getPoint3d().x; double y = atom.getPoint3d().y; double z = atom.getPoint3d().z; int k1,k2,k3; k1 = (int)(Math.floor(x/ boxSize)); k2 = (int)(Math.floor(y/ boxSize)); k3 = (int)(Math.floor(z/ boxSize)); String key = Integer.toString(k1) + " " + Integer.toString(k2) + " " + Integer.toString(k3) + " " ; return(key); } private int[] getKeyArray(IAtom atom) { double x = atom.getPoint3d().x; double y = atom.getPoint3d().y; double z = atom.getPoint3d().z; int k1,k2,k3; k1 = (int)(Math.floor(x/ boxSize)); k2 = (int)(Math.floor(y/ boxSize)); k3 = (int)(Math.floor(z/ boxSize)); int[] ret = { k1, k2, k3 }; return(ret); } public int getNumberOfNeighbors(int i) { return getNeighbors(i).length; } public int[] getNeighbors(int ii) { double maxDist2 = this.boxSize *this.boxSize; IAtom ai = this.atoms[ii]; int[] key = getKeyArray(ai); ArrayList nlist = new ArrayList(); int[] bval = {-1,0,1}; for (int i = 0; i < bval.length; i++) { int x = bval[i]; for (int j = 0; j < bval.length; j++) { int y = bval[j]; for (int k = 0; k < bval.length; k++) { int z = bval[k]; String keyj = Integer.toString(key[0]+x) + " " + Integer.toString(key[1]+y) + " " + Integer.toString(key[2]+z) + " " ; if (boxes.containsKey(keyj)) { ArrayList nbrs = (ArrayList)boxes.get(keyj); for (int l = 0; l < nbrs.size(); l++) { int i2 = (Integer) nbrs.get(l); if (i2 != ii) { IAtom aj = atoms[i2]; double x12 = aj.getPoint3d().x - ai.getPoint3d().x; double y12 = aj.getPoint3d().y - ai.getPoint3d().y; double z12 = aj.getPoint3d().z - ai.getPoint3d().z; double d2 = x12*x12 + y12*y12 + z12*z12; if (d2 < maxDist2) nlist.add(i2); } } } } } } Object[] tmp = nlist.toArray(); int[] ret = new int[ tmp.length ]; for (int j = 0; j < tmp.length; j++) ret[j] = (Integer) tmp[j]; return(ret); } }