6
$\begingroup$

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):

enter image description here

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

enter image description here

   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]

enter image description here

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

enter image description here

 Show[vor, pvor]

enter image description here

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

enter image description here

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

enter image description here

$\endgroup$

1 Answer 1

4
$\begingroup$
  • 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}]

enter image description here

  • Then almost follow your code.
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[]}]]

enter image description here

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

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.