Creating MeshRegions of various 2D lattices
I modify hexTile
slightly for convenience by skipping the wrapup with Polygon
and by Flatten
ing a level.
hexTile1[n_, m_] :=
With[{hex =
Table[{Cos[2. Pi k/6] + #, Sin[2. Pi k/6] + #2}, {k, 6}] &},
Flatten[Table[hex[3 i + 3 ((-1)^j + 1)/4, Sqrt[3]/2 j], {i, n}, {j, m}], 1]];
Let's assume that we have a ragged array polygonpts
whose entries are lists containing the vertex positions of each polygon.
First, we compute a clustering tolerance ϵ
lower than any edge length in the tesselation. Second, we cluster duplicates with the help of Nearest
in order to produce a reduced point set newpts
. Afterwards, we use the NearestFunction
of newpts
as a lookup function for the vertex indices.
polygonpts = hexTile1[3, 5];
ϵ = 0.5 Min[Sqrt[Total[(# - RotateLeft[#])^2, {2}]] & /@ polygonpts];
pts = Flatten[polygonpts, 1];
plist = Sort[DeleteDuplicates[
Compile[{{idx, _Integer, 1}},
Min[idx],
RuntimeAttributes -> {Listable},
Parallelization -> True
][Nearest[pts -> Automatic, pts, {∞, ϵ}]]
]];
newpts = pts[[plist]];
nf = Nearest[newpts -> Automatic];
polygons = Internal`PartitionRagged[Flatten[nf[pts]], Length /@ polygonpts];
MeshRegion[newpts, Polygon[polygons], MeshCellLabel -> {0 -> "Index"}]
It appears that this is the same mesh as the one returned by DiscretizeGraphics
.
Sorting the reduced point set first leads to somewhat nicer enumeration of points:
newpts = Sort[pts[[plist]]];
nf = Nearest[newpts -> Automatic];
polygons = Internal`PartitionRagged[Flatten[nf[pts]], Length /@ polygonpts];
MeshRegion[newpts, Polygon[polygons], MeshCellLabel -> {0 -> "Index"}]