diff --git a/src/hydro/Shadowswift/voronoi2d_algorithm.h b/src/hydro/Shadowswift/voronoi2d_algorithm.h
index c956c731ac84b89d6b5c8a239554f305b2bdae6d..1a30d02e558f5b3810ff0ae25f66a264597a8fd9 100644
--- a/src/hydro/Shadowswift/voronoi2d_algorithm.h
+++ b/src/hydro/Shadowswift/voronoi2d_algorithm.h
@@ -28,11 +28,10 @@
 #include "minmax.h"
 #include "voronoi2d_cell.h"
 
-/* Check if the test variable contains a value that is small enough to be
-   affected by round off error */
-#define VORONOI_CHECK_TEST()     \
-  if (fabs(test) < 1.e-10) {     \
-    error("Too close to call!"); \
+/* Check if the number of vertices exceeds the maximal allowed number */
+#define VORONOI_CHECK_SIZE()          \
+  if (nvert > VORONOI2D_MAXNUMVERT) { \
+    error("Too many vertices!");      \
   }
 
 /* IDs used to keep track of cells neighbouring walls of the simulation box
@@ -187,7 +186,6 @@ __attribute__((always_inline)) INLINE void voronoi_cell_interact(
   /* start testing a random vertex: the first one */
   test = cell->vertices[0][0] * half_dx[0] + cell->vertices[0][1] * half_dx[1] -
          r2;
-  VORONOI_CHECK_TEST();
   if (test < 0.) {
 /* vertex is below midline */
 #ifdef VORONOI_VERBOSE
@@ -200,18 +198,16 @@ __attribute__((always_inline)) INLINE void voronoi_cell_interact(
        coordinates */
     b1 = test;
 
-    /* move on until we find a vertex that is above the midline */
+    /* move on until we find a vertex that is above or on the midline */
     i = 1;
     test = cell->vertices[i][0] * half_dx[0] +
            cell->vertices[i][1] * half_dx[1] - r2;
-    VORONOI_CHECK_TEST();
     while (i < cell->nvert && test < 0.) {
       /* make sure we always store the latest test result */
       b1 = test;
       ++i;
       test = cell->vertices[i][0] * half_dx[0] +
              cell->vertices[i][1] * half_dx[1] - r2;
-      VORONOI_CHECK_TEST();
     }
 
     /* loop finished, there are two possibilities:
@@ -236,7 +232,10 @@ __attribute__((always_inline)) INLINE void voronoi_cell_interact(
     a1 = test;
     increment = 1;
   } else {
-/* vertex is above midline */
+/* vertex is above or on midline
+   in the case where it is on the midline, we count that as above as well:
+   the vertex will be removed, and a new vertex will be created at the same
+   position */
 #ifdef VORONOI_VERBOSE
     message("First vertex is above midline (%g %g --> %g)!",
             cell->vertices[0][0] + cell->x[0],
@@ -250,14 +249,12 @@ __attribute__((always_inline)) INLINE void voronoi_cell_interact(
     i = 1;
     test = cell->vertices[i][0] * half_dx[0] +
            cell->vertices[i][1] * half_dx[1] - r2;
-    VORONOI_CHECK_TEST();
-    while (i < cell->nvert && test > 0.) {
+    while (i < cell->nvert && test >= 0.) {
       /* make sure we always store the most recent test result */
       a1 = test;
       ++i;
       test = cell->vertices[i][0] * half_dx[0] +
              cell->vertices[i][1] * half_dx[1] - r2;
-      VORONOI_CHECK_TEST();
     }
 
     /* loop finished, there are two possibilities:
@@ -290,9 +287,9 @@ __attribute__((always_inline)) INLINE void voronoi_cell_interact(
 #endif
 
   /* now we need to find the second intersected edge
-     we start from the vertex above the midline and search in the direction
-     opposite to the intersected edge direction until we find a vertex below the
-     midline */
+     we start from the vertex above (or on) the midline and search in the
+     direction opposite to the intersected edge direction until we find a vertex
+     below the midline */
 
   /* we make sure we store the test result for the second vertex above the
      midline as well, since we need this for intersection point computations
@@ -307,10 +304,9 @@ __attribute__((always_inline)) INLINE void voronoi_cell_interact(
   }
   test = cell->vertices[i][0] * half_dx[0] + cell->vertices[i][1] * half_dx[1] -
          r2;
-  VORONOI_CHECK_TEST();
   /* this loop can never deadlock, as we know there is at least 1 vertex below
      the midline */
-  while (test > 0.) {
+  while (test >= 0.) {
     /* make sure we always store the most recent test result */
     a2 = test;
     i += increment;
@@ -322,7 +318,6 @@ __attribute__((always_inline)) INLINE void voronoi_cell_interact(
     }
     test = cell->vertices[i][0] * half_dx[0] +
            cell->vertices[i][1] * half_dx[1] - r2;
-    VORONOI_CHECK_TEST();
   }
 
   index_below2 = i;
@@ -343,6 +338,15 @@ __attribute__((always_inline)) INLINE void voronoi_cell_interact(
     error("Only 1 intersected edge found!");
   }
 
+  /* there is exactly one degenerate case we have not addressed yet: the case
+     where index_above1 and index_above2 are the same and are on the midline.
+     In this case we don't want to create 2 new vertices. Instead, we just keep
+     index_above1, which basically means nothing happens at all and we can just
+     return */
+  if (index_above1 == index_above2 && a1 == 0.) {
+    return;
+  }
+
   /* to make the code below more clear, we make sure index_above1 always holds
      the first vertex to remove, and index_above2 the last one, in clockwise
      order
@@ -378,6 +382,10 @@ __attribute__((always_inline)) INLINE void voronoi_cell_interact(
           cell->vertices[index_above2][1] + cell->x[1], index_above2, a2);
 #endif
 
+  if (b1 == 0. || b2 == 0.) {
+    error("Vertex below midline is on midline!");
+  }
+
   /* convert the test results (which correspond to the projected distance
      between the vertex and the midline) to the fractions of the intersected
      edges above and below the midline */
@@ -400,6 +408,7 @@ __attribute__((always_inline)) INLINE void voronoi_cell_interact(
     vertices[nvert][0] = cell->vertices[i][0];
     vertices[nvert][1] = cell->vertices[i][1];
     ++nvert;
+    VORONOI_CHECK_SIZE();
     ++i;
     if (i == cell->nvert) {
       i = 0;
@@ -411,11 +420,13 @@ __attribute__((always_inline)) INLINE void voronoi_cell_interact(
   vertices[nvert][1] = a1 * cell->vertices[index_below1][1] +
                        b1 * cell->vertices[index_above1][1];
   ++nvert;
+  VORONOI_CHECK_SIZE();
   vertices[nvert][0] = a2 * cell->vertices[index_below2][0] +
                        b2 * cell->vertices[index_above2][0];
   vertices[nvert][1] = a2 * cell->vertices[index_below2][1] +
                        b2 * cell->vertices[index_above2][1];
   ++nvert;
+  VORONOI_CHECK_SIZE();
 
   /* overwrite the original vertices */
   cell->nvert = nvert;
diff --git a/tests/testVoronoi2D.c b/tests/testVoronoi2D.c
index 47eb40bf0e0a922f75296c6d08e0d49448490bcb..308f83d221fb6419308d0aa620de19c179a44a3d 100644
--- a/tests/testVoronoi2D.c
+++ b/tests/testVoronoi2D.c
@@ -49,7 +49,7 @@ int main() {
     assert(cell.centroid[1] == 0.5f);
   }
 
-  /* test interaction algorithm */
+  /* test interaction algorithm: normal case */
   {
     /* create 100 cells with random positions in [0,1]x[0,1] */
     struct voronoi_cell cells[TESTVORONOI2D_NUMCELL];
@@ -110,5 +110,64 @@ int main() {
     assert(fabs(Atot - 1.0f) < 1.e-6);
   }
 
+  /* test interaction algorithm */
+  {
+    struct voronoi_cell cells[100];
+    double x[2];
+    float dx[2];
+    int i, j;
+    float Atot;
+    struct voronoi_cell *cell_i, *cell_j;
+
+    for (i = 0; i < 10; ++i) {
+      for (j = 0; j < 10; ++j) {
+        x[0] = (i + 0.5f) * 0.1;
+        x[1] = (j + 0.5f) * 0.1;
+        voronoi_cell_init(&cells[10 * i + j], x);
+      }
+    }
+
+    /* interact the cells (with periodic boundaries) */
+    for (i = 0; i < 100; ++i) {
+      cell_i = &cells[i];
+      for (j = 0; j < 100; ++j) {
+        if (i != j) {
+          cell_j = &cells[j];
+          dx[0] = cell_i->x[0] - cell_j->x[0];
+          dx[1] = cell_i->x[1] - cell_j->x[1];
+          /* periodic boundaries */
+          if (dx[0] >= 0.5f) {
+            dx[0] -= 1.0f;
+          }
+          if (dx[0] < -0.5f) {
+            dx[0] += 1.0f;
+          }
+          if (dx[1] >= 0.5f) {
+            dx[1] -= 1.0f;
+          }
+          if (dx[1] < -0.5f) {
+            dx[1] += 1.0f;
+          }
+#ifdef VORONOI_VERBOSE
+          message("Cell %i before:", i);
+          voronoi_print_cell(&cells[i]);
+          message("Interacting cell %i with cell %i (%g %g, %g %g", i, j,
+                  cells[i].x[0], cells[i].x[1], cells[j].x[0], cells[j].x[1]);
+#endif
+          voronoi_cell_interact(cell_i, dx, j);
+        }
+      }
+    }
+
+    /* print the cells to the stdout */
+    for (i = 0; i < 100; ++i) {
+      voronoi_print_cell(&cells[i]);
+      voronoi_cell_finalize(&cells[i]);
+      Atot += cells[i].volume;
+    }
+
+    assert(fabs(Atot - 1.0f) < 1.e-6);
+  }
+
   return 0;
 }