[Math] Distance in a periodic system

algorithms

I have two random points in a 3D unit cell and I want to write a computer program that calculates their distance. The system is periodic in all directions in the sense that a point in the unit cell is equivalent to the corresponding point in any other unit cell.
enter image description here

The cell can be cubic, monoclinic, etc… (just one of the different lattice strucutres like here: Lattice systems)

The problem is that "distance" of two points in a cell is not defined by the difference vector in the the unit cell but by the shortest distance from one point to any equivalent of the other point in a neighbouring unit cell.

My naive approach was to take the second point and find all its 26 equivalents in the 26 neighbouring unit cells. Then calculate all 27 distances from the first point two the second point and its equivalents. Then take the shortest distance.

However this is very inefficient. Are there some common tricks to do that in a more efficient way?

Best Answer

For cubic cells, I think the way to do it is to calculate distance for just one point component-wise, and if the distance in any component is greater than 1/2, switch to a different point.

I thought about this in 2-d: There's two points, $A$ and $B$. Since both $A$ and $B$ form a grid, because they're periodic, you can forget about the original unit grid and simply imagine that $A$ is randomly placed within a square created by the points of $B$. Now if I draw lines that represent the points equidistant from any two corner points of this $B$ square, they will form a cross in the middle of the square. So the maximum distance that $A$ can be from $B$, component-wise, is 1/2. If I take any $B$ and calculate the distance to $A$, that will tell me what to do:

  • If $A_x-B_x > 1/2$, move to the next $B$ point in the -x direction
  • If $A_x-B_x < 1/2$, move to the next $B$ point in the +x direction
  • If $A_y-B_y > 1/2$, move to the next $B$ point in the -y direction
  • If $A_y-B_y < 1/2$, move to the next $B$ point in the +y direction
  • Else, keep the same $B$ point

In 3-d it's the same idea, but you can move in the z-direction.

For non-cubic cells, I can't think of a way that's as quick and simple. One thing you could do is pre-compute the distances between different points in the lattice, so that if you calculate the distance to $A$ and $B_1$ and find that it's less than half of the distance between $B_1$ and $B_i$, then you know that $B_i$ will not be the closest point to $A$, and you didn't have to calculate $B_i$'s position explicitly. There might be a way to do a similar trick as the 3-d one with planes: if you pre-compute vectors $d_{ij}=B_i-B_j$ and then if $d_{ij}\cdot A - \frac{d_{ij}^2}{2} >0$, then $a$ is closer to $B_i$ than $B_j$. This should work because $d_{ij}\cdot r = c$ defines a plane parallel to the plane of points equidistant between $B_i$ and $B_j$; since it should be half-way between $B_i$ and $B_j$ substitute $d_{ij}/2$: $d_{ij}\cdot d_{ij}/2=c$. The problem here is that unlike the simple 3-d case, knowing that $A$ is closer to $B_i$ than $B_j$ doesn't help for any other point $B_k$. Still, 27+ dot products with pre-computed vectors might still be a big speed-up.

Related Question