# Generating a Periodic Voronoi Mesh

Consider the following hexagonal mesh, created from VoronoiMesh

L1 = 4; L2 = 4;
pts = Flatten[Table[{3/2 i ,
(Sqrt[3] j + Mod[i, 2] Sqrt[3]/2)
}, {i, L1 + 4}, {j, L2 + 4}], 1] // N;
mesh0 = VoronoiMesh[pts];
mesh1 = MeshRegion[MeshCoordinates[mesh0],
With[{a = PropertyValue[{mesh0, 2}, MeshCellMeasure]},
With[{m = 3}, Pick[MeshCells[mesh0, 2], UnitStep[a - m], 0]]]];
mesh = MeshRegion[MeshCoordinates[mesh1],
MeshCells[mesh1, {2, "Interior"}]]


I can get the connectivity matrix of such mesh by doing

conn = mesh["ConnectivityMatrix"[1, 2]];
lens = PropertyValue[{mesh, 1}, MeshCellMeasure];
$$threshold = 0.; keep = Pick[Range[MeshCellCount[mesh, 1]], UnitStep[Subtract[$$threshold, lens]], 0];
conn = conn[[keep]];
ag = (UpperTriangularize[arg, 1] + LowerTriangularize[arg, -1]);
ag // MatrixForm


Is it possible to easily change this matrix such that it considers the periodic hexagonal mesh case? I'm aware of this question, but I am looking for something more general, that could be specifically applied to Voronoi meshes.

More generally, is it possible at all to get the periodic connectivity matrices of meshes like

which are generated by VoronoiMesh?

Ultimately, and this might be reaching too far for now, how hard could it be to fabricate a Voronoi periodic mesh that takes into account the "need to fit" condition, that is, either of the following

Edit: Following Chip Hurst's answer below, I can get the periodicity of the hexagonal mesh by setting

Show[Table[
MeshRegion[
TransformedRegion[mesh,
TranslationTransform[{1.5 L1 i, Sqrt[3] L2 j}]],
MeshCellStyle -> {1 -> Black,
2 -> ColorData[112, 7 i + j + 25]}], {i, 0, 1}, {j, i, 1}]]


This is rather useful, as I can possibly even consider cylindrical periodicity. How would I now get the connectivity matrix from this setting? That is last step I need.

• The question you linked on the heganonal lattice has multiple very detailed answer. Is nothing from there really applicable here? You would want to point out exactly what functionality you seek that was not addressed. Also, Have you seen Cropping a Voronoi diagram and Making a Voronoi diagram bounded by the convex hull? Commented Apr 25, 2020 at 16:18
• Regarding the linked question, specifically, I would like to avoid using Szabolcs package, since I intend to use this in a CDF, and seems tricky to incorporate IGraph/M in a CDF, in an automated fashion. Regarding the other answer, I can't get ntab to yield the matrix that I want, but I'm still trying. Thank you for the other links, I will take a look. Commented Apr 25, 2020 at 19:12

One way to periodically tile a Voronoi diagram is to translate your seeds in all directions you'd like to tile, find the Voronoi diagram of this set, then take the cells that correspond to the original data.

Here, I'll tile it in the cardinal directions.

Initial data:

SeedRandom[1];
pts = RandomReal[{-1, 1}, {20, 2}];


Now we augment this data and find a larger Voronoi mesh:

pts2 = Flatten[Table[TranslationTransform[{2 i, 2 j}][pts], {i, -1, 1}, {j, -1, 1}], 2];

vor = VoronoiMesh[pts2, {{-3, 3}, {-3, 3}}]


Now pick only the cells the original data lies in:

vcells = Catenate[NearestMeshCells[{vor, 2}, #] & /@ pts];

pvor = MeshRegion[MeshCoordinates[vor], MeshCells[vor, vcells]]


And tile:

Show[Table[
MeshRegion[
TransformedRegion[pvor, TranslationTransform[{2 i, 2 j}]],
MeshCellStyle -> {1 -> Black, 2 -> ColorData[112, 7 i + j + 25]}
],
{i, -3, 3}, {j, -3, 3}
]]


To get the periodic connectivity matrix, we can start with the connectivity matrix of the larger Voronoi, partition it into a 3x3 collection and sum them.

len = Length[pts];

C22 = #.Transpose[#]& @ vor["ConnectivityMatrix"[2, 1]];

cells = RegionMeshMeshMemberCellIndex[vor, pts2][[All, 2]];

C22perm = C22[[cells, cells]];

pC22 = SparseArray[Unitize[Total[Partition[Unitize[C22perm], {len, len}], 2]]];
pC22 -= IdentityMatrix[len, SparseArray];

Show[
pvor,

• Also, the last code does not seem to work with my mesh. Commented Apr 25, 2020 at 19:35
• See my edit. ${}$ Commented Apr 27, 2020 at 0:31