I want the edges of a VoronoiMesh
to be smooth and round. I have found the following code from this answer
arcgen[{p1_, p2_, p3_}, r_, n_] :=
Module[{dc = Normalize[p1 - p2] + Normalize[p3 - p2], cc, th},
cc = p2 + r dc/EuclideanDistance[dc, Projection[dc, p1 - p2]];
th = Sign[
Det[PadRight[{p1, p2, p3}, {3, 3}, 1]]] (π -
VectorAngle[p3 - p2, p1 - p2])/(n - 1);
NestList[RotationTransform[th, cc],
p2 + Projection[cc - p2, p1 - p2], n - 1]]
roundedPolygon[Polygon[pts_?MatrixQ], r_?NumericQ,
n : (_Integer?Positive) : 12] :=
Polygon[Flatten[
arcgen[#, r, n] & /@
Partition[If[TrueQ[First[pts] == Last[pts]], Most, Identity][pts],
3, 1, {2, -2}], 1]]
Consider for example, the 3x3 hexagonal mesh (see this question for more details)
L1 = 3; L2 = 3;
pts = Flatten[
Table[{3/2 i, Sqrt[3] j + Mod[i, 2] Sqrt[3]/2}, {i, L2 + 4}, {j,
L1 + 4}], 1];
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"}]]
Using roundedPolygon
defined above, I can get what I want with
Graphics[{Directive[LightBlue, EdgeForm[Gray], EdgeThickness -> .001],
roundedPolygon[#, 0.3]} & /@ MeshPrimitives[mesh, 2]]
This looks good already, but I have the following questions:
- Is it possible to fill the gaps between cells automatically? I first thought about setting a
Background
colour on inGraphics
that would match the edge colour. This, however, yields a box look that I want to avoid. I could also change the edge thickness, but this doesn't seem to scale with the lattice size. Any idea how to solve this? The following picture illustrates these cases.
Is it possible to scale the
EdgeThickness
with the mesh size?When I consider a square mesh, given, for example, by
pts = Flatten[Table[{i, j}, {i, L2 + 2}, {j, L1 + 2}], 1]
andmesh = MeshRegion[MeshCoordinates[mesh0], MeshCells[mesh0, {2, "Interior"}]]
roundedPolygon
seems to fail, returning, among others, the error
Any idea how to solve this?
- Finally, I wonder if it's possible to display the mesh as a mesh-type object and avoid using
Graphics
.
I don't expect to get an answer to everything, but any ideas or suggestions are welcome.
Edit: The answer to the main problem was already given. However, going a step further, I'm having some troubles using Chip Hurst's code below when considering a random VoronoiMesh
. First, it seems that the way diff
and joints
are defined becomes problematic when considering such type of mesh, different types of errors appear. Furthermore, simply computing the rounded mesh (without filling the spaces), and setting
pts = {RandomReal[L2, L1 L2], RandomReal[L1, L1 L2]} // Transpose;
mesh = VoronoiMesh[pts]
doesn't always yield what I expect from the roundedPolygon
option. Occasionaly I get the right rounded mesh
But most times I get wrongly placed polygons
This seems to be an ordering problem, possibly from using Nearest
, though I'm not sure. Using Graphics
seems to work well with random meshes, but I'd like to be able to work with meshes. Filling the gaps in the random case might get really tricky, but everything works well with either regular square and hexagonal lattices, just wondering if we could go a step further. Any ideas?
EdgeForm[Thickness[whateveryouwant]
below. $\endgroup$