protected boolean intersection(Cell cell) { double k = box.k; double vz = box.viewZone; double x1 = cell.getSpace().getLoAnchor().x; double y1 = cell.getSpace().getLoAnchor().y; double z1 = cell.getSpace().getLoAnchor().z; double x2 = cell.getSpace().getHiAnchor().x; double y2 = cell.getSpace().getHiAnchor().y; double z2 = cell.getSpace().getHiAnchor().z; double X1 = pos.x - (k * vz); double Y1 = pos.y - (k * vz); double Z1 = pos.z - (k * vz); double X2 = pos.x + (k * vz); double Y2 = pos.y + (k * vz); double Z2 = pos.z + (k * vz); // Only when the area is before or after the cell there cannot // exist an intersection (case a and b). Else there must be an // intersection (cases c, d, e and f). // // |-a-| +---------+ |-b-| // | | // |-c-| |-d-| // | | // | |-e-| | // | | // |-+----f----+-| // | | // +---------+ // // (04/21/11) here lies my beautiful comment. Sorry if it is // no more readable, barbarians ruined it. if (X2 < x1 || X1 > x2) return false; if (Y2 < y1 || Y1 > y2) return false; if (Z2 < z1 || Z1 > z2) return false; return true; }
protected void recurseRepulsion(Cell cell, Vector3 delta) { if (intersection(cell)) { if (cell.isLeaf()) { Iterator<? extends Particle> i = cell.getParticles(); while (i.hasNext()) { NodeParticle node = (NodeParticle) i.next(); if (node != this) { delta.set(node.pos.x - pos.x, node.pos.y - pos.y, box.is3D ? node.pos.z - pos.z : 0); double len = delta.normalize(); if (len > 0) // && len < ( box.k * box.viewZone ) ) { if (len < box.k) len = box.k; // XXX NEW To prevent infinite // repulsion. double factor = len != 0 ? ((box.K2 / (len * len)) * node.weight) : 0.00001; box.energies.accumulateEnergy(factor); // TODO check // this repE += factor; delta.scalarMult(-factor); disp.add(delta); } } } } else { int div = cell.getSpace().getDivisions(); for (int i = 0; i < div; i++) recurseRepulsion(cell.getSub(i), delta); } } else { if (cell != this.cell) { BarycenterCellData bary = (BarycenterCellData) cell.getData(); double dist = bary.distanceFrom(pos); double size = cell.getSpace().getSize(); if ((!cell.isLeaf()) && ((size / dist) > box.theta)) { int div = cell.getSpace().getDivisions(); for (int i = 0; i < div; i++) recurseRepulsion(cell.getSub(i), delta); } else { if (bary.weight != 0) { // System.err.printf( // "applying bary %s [depth=%d weight=%d]%n", // cell.getId(), cell.getDepth(), (int)bary.weight ); delta.set( bary.center.x - pos.x, bary.center.y - pos.y, box.is3D ? bary.center.z - pos.z : 0); double len = delta.normalize(); if (len > 0) { if (len < box.k) len = box.k; // XXX NEW To prevent infinite // repulsion. double factor = len != 0 ? ((box.K2 / (len * len)) * (bary.weight)) : 0.00001f; box.energies.accumulateEnergy(factor); delta.scalarMult(-factor); repE += factor; disp.add(delta); } } } } } }