# How to create a quality periodic Voronoi mesh bounded by the unit square featuring only regular or irregular hexagons?

I have been trying to build a 2D periodic Voronoi mesh ideally containing only hexagons (apart near the boundaries of the unit square). Here is an example of what I am after. Here I have perfect hexagons but I would also like to have the option to perturb the seeds to get a more natural pattern that is widely found in Nature for cellular materials (like the orange pattern below):

The geometry should feature finite thickness for cell edges (I will use EdgeForm to do that). The edges and the inside of the cells will be meshed with triangular finite element elements to represent a cellular material with 2 phases. Geometric peridocity of this structure is essential.

I found examples of the algorithm which consists in using LLoyd's relaxation and creating a tiling using 9 copies of the original Voroinoi mesh centroids to create periodicity (see answer by Greg Hurst, here: ): .

This approach works but the results are not satisfying: 1/ I get cells which feature 5 or 4 sides instead of 6. 2/ The resulting geometric features (mainly triangles) along the boundaries of the periodic representative unit square are too small: it would be better for me if the hexagons touching the boundaries were roughly cut in half. As I will increase the edge thickness, if the boundary areas are too small, these areas will become covered by cell edges.

QUESTION: What could be a possible approach to address the 2 points above and improve the generation of periodic representative volume element featuring regular or irregular hexagons? Any suggestion would be very much appreciated. Thank you.

SeedRandom[1234];
nPoints = 50;

pts = Nest[
PropertyValue[{VoronoiMesh[#, {{0, 1}, {0, 1}}], {2, All}},
MeshCellCentroid] &, RandomReal[{0, 1}, {nPoints, 2}], 600];
vor0 = VoronoiMesh[pts, {{0, 1}, {0, 1}},
MeshCellStyle -> {1 -> {Opacity[1], Black},
2 -> {Opacity[1], Orange}}, Epilog -> {Black, Point@pts}]

vor0 = VoronoiMesh[pts, {{0, 1}, {0, 1}},MeshCellStyle -> {1 -> Black, 2 -> Orange}]


   pts2 = Flatten[
Table[TranslationTransform[{i, j}][pts], {i, -1, 1}, {j, -1, 1}],
2];
vor = VoronoiMesh[pts2, {{-1, 2}, {-1, 2}}, Frame -> True,
Epilog -> {Black, Point@pts2}];

vor0b = VoronoiMesh[pts, {{0, 1}, {0, 1}},
MeshCellStyle -> {1 -> {Opacity[0.01], Black},
2 -> {Opacity[0.2], Orange}}, Epilog -> {Black, Point@pts}];
Show[vor, vor0b]


vcells = Catenate[NearestMeshCells[{vor, 2}, #] & /@ pts];
pvor = MeshRegion[MeshCoordinates[vor], MeshCells[vor, vcells],
MeshCellStyle -> {1 -> Black, 2 -> Pink},
Epilog -> {Black, Point@pts}]


 Show[vor, pvor]


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


 Show[g5, PlotRange -> {{0, 1}, {0, 1}}]


• We set pts be the pertabation of the points of regular triangle grid points.
• If we can find a way to select the original,scale, r and λ, we can get a better result,maybe use some fitting function or manipulate.
Clear["Global*"];
e = {e1, e2, e3, e4, e5, e6} = CirclePoints[{1, 0}, 6];
L = 50;
original = {0, 0};
r = Sqrt[3]/12;
scale = .8;
λ = 0;
(* λ=0.012; *)
pts0 = Flatten[
Table[original + scale*r   {i, j} . {e1, e2} +
RandomReal[{0, λ}, 2], {i, -L, L}, {j, -L, L}], 1];
pts = Select[pts0, RegionMember[Rectangle[], #] &];
Graphics[{LightGray, Rectangle[], Red, Point@pts}]


ptss = TranslationTransform[#][pts] & /@ Tuples[{-1, 0, 1}, 2];
pts2 = Flatten[ptss, 1];
vor = VoronoiMesh[pts2, {{-1, 2}, {-1, 2}}, Frame -> True,
Epilog -> Point@pts];
(* HighlightMesh[vor,Catenate@NearestMeshCells[{vor,2},#]&/@pts] *)
vcells = Catenate[NearestMeshCells[{vor, 2}, #] & /@ pts];
pvor = MeshRegion[MeshCoordinates[vor], MeshCells[vor, vcells],
MeshCellStyle -> {1 -> Black, 2 -> Pink},
Epilog -> {Black, Point@pts}];
g5 = Show[
Table[MeshRegion[
TransformedRegion[pvor, TranslationTransform[{i, j}]],
MeshCellStyle -> {1 -> Black,
2 -> ColorData[112, 7  i + j + 25]}], {i, -1, 1}, {j, -1,
1}]];
Show[g5, Graphics[{FaceForm[], EdgeForm[White], Rectangle[]}]]
`

• Many thanks @cvgmt. I really appreciate your efforts and nice suggestions. Now I need to consistently control the size and density of cell.
– jmt
Commented May 11 at 16:18