13
$\begingroup$

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"}]]

enter image description here

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]];
adj = Transpose[conn].conn;
arg = Unitize[adj];
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

enter image description here

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

enter image description here

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}]]

enter image description here

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.

$\endgroup$
2
  • $\begingroup$ 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? $\endgroup$
    – MarcoB
    Commented Apr 25, 2020 at 16:18
  • $\begingroup$ 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. $\endgroup$
    – sam wolfe
    Commented Apr 25, 2020 at 19:12

1 Answer 1

10
$\begingroup$

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 = Region`Mesh`MeshMemberCellIndex[vor, pts2][[All, 2]];

C22perm = C22[[cells, cells]];

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

Show[
  pvor,
  AdjacencyGraph[pC22, VertexCoordinates -> pts]
]

$\endgroup$
7
  • $\begingroup$ And how do I get the connectivity/adjacency matrix corresponding to the periodic case? $\endgroup$
    – sam wolfe
    Commented Apr 25, 2020 at 19:24
  • $\begingroup$ Also, the last code does not seem to work with my mesh. $\endgroup$
    – sam wolfe
    Commented Apr 25, 2020 at 19:35
  • $\begingroup$ I'm getting the error "MeshRegion is not a Graphics primitive or directive" $\endgroup$
    – sam wolfe
    Commented Apr 25, 2020 at 19:41
  • $\begingroup$ See if my edit fixes things. $\endgroup$
    – Greg Hurst
    Commented Apr 25, 2020 at 20:37
  • 1
    $\begingroup$ See my edit. ${}$ $\endgroup$
    – Greg Hurst
    Commented Apr 27, 2020 at 0:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.