
org.biojava.nbio.structure.symmetry.geometry.DistanceBox Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of biojava-structure Show documentation
Show all versions of biojava-structure Show documentation
The protein structure modules of BioJava.
/*
* BioJava development code
*
* This code may be freely distributed and modified under the
* terms of the GNU Lesser General Public Licence. This should
* be distributed with the code. If you do not have a copy,
* see:
*
* http://www.gnu.org/copyleft/lesser.html
*
* Copyright for this code is held jointly by the individual
* authors. These should be listed in @author doc comments.
*
* For more information on the BioJava project and its aims,
* or to join the biojava-l mailing list, visit the home page
* at:
*
* http://www.biojava.org/
*
*/
package org.biojava.nbio.structure.symmetry.geometry;
import javax.vecmath.Point3d;
import java.util.*;
/**
*
* @author Peter
*/
public class DistanceBox {
private Map> map;
private Map> layerMap;
private boolean modified;
private double inverseBinWidth;
// relative locations of 26 boxes surrounding a box at (0, 0, 0)
private static final long[] offset = new long[] {
0 + ( 0 * 10000) + ( 0 * 1000000000L),
-1 + (-1 * 10000) + (-1 * 1000000000L),
-1 + (-1 * 10000) + ( 0 * 1000000000L),
-1 + (-1 * 10000) + ( 1 * 1000000000L),
-1 + ( 0 * 10000) + (-1 * 1000000000L),
-1 + ( 0 * 10000) + ( 0 * 1000000000L),
-1 + ( 0 * 10000) + ( 1 * 1000000000L),
-1 + ( 1 * 10000) + (-1 * 1000000000L),
-1 + ( 1 * 10000) + ( 0 * 1000000000L),
-1 + ( 1 * 10000) + ( 1 * 1000000000L),
0 + (-1 * 10000) + (-1 * 1000000000L),
0 + (-1 * 10000) + ( 0 * 1000000000L),
0 + (-1 * 10000) + ( 1 * 1000000000L),
0 + ( 0 * 10000) + (-1 * 1000000000L),
0 + ( 0 * 10000) + ( 1 * 1000000000L),
0 + ( 1 * 10000) + (-1 * 1000000000L),
0 + ( 1 * 10000) + ( 0 * 1000000000L),
0 + ( 1 * 10000) + ( 1 * 1000000000L),
1 + (-1 * 10000) + (-1 * 1000000000L),
1 + (-1 * 10000) + ( 0 * 1000000000L),
1 + (-1 * 10000) + ( 1 * 1000000000L),
1 + ( 0 * 10000) + (-1 * 1000000000L),
1 + ( 0 * 10000) + ( 0 * 1000000000L),
1 + ( 0 * 10000) + ( 1 * 1000000000L),
1 + ( 1 * 10000) + (-1 * 1000000000L),
1 + ( 1 * 10000) + ( 0 * 1000000000L),
1 + ( 1 * 10000) + ( 1 * 1000000000L)
};
private List tempBox = new ArrayList(offset.length);
/** Creates a new instance of DistanceBox */
public DistanceBox(double binWidth) {
map = new HashMap>();
layerMap = new HashMap>();
this.inverseBinWidth = 1.0f/binWidth;
this.modified = true;
}
public void addPoint(Point3d point, T object) {
long i = (long) StrictMath.rint(point.x * inverseBinWidth);
long j = (long) StrictMath.rint(point.y * inverseBinWidth);
long k = (long) StrictMath.rint(point.z * inverseBinWidth);
long location = i + (j * 10000L) + (k * 1000000000L);
List box = map.get(location);
if (box == null) {
box = new ArrayList();
map.put(location, box);
}
box.add(object);
modified = true;
}
public List getNeighborsWithCache(Point3d point) {
if (modified) {
layerMap.clear();
modified = false;
}
long i = (long) StrictMath.rint(point.x * inverseBinWidth);
long j = (long) StrictMath.rint(point.y * inverseBinWidth);
long k = (long) StrictMath.rint(point.z * inverseBinWidth);
long location = i + (j * 10000L) + (k * 1000000000L);
List box = layerMap.get(location);
if (box == null) {
box = getBoxTwo(location);
layerMap.put(location, box);
}
return box;
}
public List getNeighbors(Point3d point) {
if (modified) {
layerMap.clear();
modified = false;
}
long i = (long) StrictMath.rint(point.x * inverseBinWidth);
long j = (long) StrictMath.rint(point.y * inverseBinWidth);
long k = (long) StrictMath.rint(point.z * inverseBinWidth);
long location = i + (j * 10000L) + (k * 1000000000L);
List box = getBoxTwo(location);
return box;
}
public List getIntersection(DistanceBox distanceBox) {
List intersection = new ArrayList();
HashSet checkedLocations = new HashSet();
for (Iterator iter = map.keySet().iterator(); iter.hasNext();) {
long location = iter.next();
boolean overlap = false;
for (int i = 0, n = offset.length; i < n; i++) {
long loc = location + offset[i];
if (distanceBox.contains(loc)) {
overlap = true;
break;
}
}
if (overlap) {
for (int i = 0, n = offset.length; i < n; i++) {
long loc = location + offset[i];
if (checkedLocations.contains(loc))
continue;
checkedLocations.add(loc);
if (contains(loc)) {
intersection.addAll(map.get(loc));
}
}
}
}
return intersection;
}
private List getBoxTwo(long location) {
tempBox.clear();
for (int i = 0, n = offset.length; i < n; i++) {
List box = map.get(location + offset[i]);
if (box != null) {
tempBox.addAll(box);
}
}
// ensure that boxTwo has no empty element by copying from tempBox of defined size
List boxTwo = null;
if (tempBox.size() == 0) {
boxTwo = Collections.emptyList();
} else if (tempBox.size() == 1) {
boxTwo = Collections.singletonList(tempBox.get(0));
} else {
boxTwo = new ArrayList(tempBox);
}
return boxTwo;
}
private boolean contains(long location) {
return map.containsKey(location);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy