float checkSpecialVoxel(Point3f ptA, float rAS, Point3f ptB, float rBS, float dAB, Point3f ptV) {
		/*
		 * Checking here for voxels that are in the situation:
		 * 
		 * A------)-- V ---((--))-- S --(------B |----d--------| or
		 * 
		 * B------)-- V ---((--))-- S --(------A |----d--------|
		 * 
		 * A and B are the two atom centers; V is the voxel; S is a hypothetical PROJECTED solvent center based on the
		 * position of V in relation to first A, then B; ( and ) are atom radii and (( )) are the overlapping
		 * atom+solvent radii.
		 * 
		 * That is, where the projected solvent location for one voxel is within the solvent radius sphere of another,
		 * this voxel should be checked in relation to solvent distance, not atom distance.
		 * 
		 * 
		 * S ++ / \ ++ ++ / | \ ++ + V + x want V such that angle ASV < angle ASB / ****** \ A --+--+----B b
		 * 
		 * A, B are atoms; S is solvent center; V is voxel point objective is to calculate dSV. ++ Here represents the
		 * van der Waals radius for each atom. ***** is the key "trough" location.
		 * 
		 * Getting dVS:
		 * 
		 * Known: rAB, rAS, rBS, giving angle BAS (theta) Known: rAB, rAV, rBV, giving angle VAB (alpha) Determined:
		 * angle VAS (theta - alpha), and from that, dSV, using the cosine law:
		 * 
		 * a^2 + b^2 - 2ab Cos(theta) = c^2.
		 * 
		 * The trough issue:
		 * 
		 * Since the voxel might be at point x (above), outside the triangle, we have to test for that. What we will be
		 * looking for in the "trough" will be that angle ASV < angle ASB that is, cosASB < cosASV
		 * 
		 * If we find the voxel in the "trough", then we set its value to (solvent radius - dVS).
		 * 
		 */
		float dAV = ptA.distance(ptV);
		float dBV = ptB.distance(ptV);
		float dVS = Float.NaN;
		float f = rAS / dAV;
		if (f > 1) {
			ptS.set(ptA.x + (ptV.x - ptA.x) * f, ptA.y + (ptV.y - ptA.y) * f, ptA.z + (ptV.z - ptA.z) * f);
			if (ptB.distance(ptS) < rBS) {
				dVS = solventDistance(ptV, ptA, ptB, rAS, rBS, dAB, dAV, dBV);
				if (!voxelIsInTrough(dVS, rAS * rAS, rBS, dAB, dAV, dBV))
					return Float.NaN;
			}
			return dVS;
		}
		f = rBS / dBV;
		if (f <= 1)
			return dVS;
		ptS.set(ptB.x + (ptV.x - ptB.x) * f, ptB.y + (ptV.y - ptB.y) * f, ptB.z + (ptV.z - ptB.z) * f);
		if (ptA.distance(ptS) < rAS) {
			dVS = solventDistance(ptV, ptB, ptA, rBS, rAS, dAB, dBV, dAV);
			if (!voxelIsInTrough(dVS, rAS * rAS, rBS, dAB, dAV, dBV))
				return Float.NaN;
		}
		return dVS;
	}