As a simple example of what I want to do, let's say I have a Voronoi mesh in a $10\times10$ area with $10$ random "seed points":

randMesh=VoronoiMesh[RandomReal[{1, 10}, {10, 2}], {{1, 10}, {1, 10}}]

enter image description here

And I am interested in all integer points within this area. i.e. the $100$ points determined by

points = Flatten[Table[{x, y}, {x, 10}, {y, 10}], 1]

What is an efficient way to group the points by the mesh section they reside in?

One way I have thought of doing this is is just going point-by-point and checking each region, such as something like

{5, 5} \[Element] # & /@ MeshPrimitives[randMesh, 2]

{False, False, True, False, False, False, False, False, False, False}

but applied to each point, and then grouping the points based on which mesh primitive they belong in. But this is not very efficient, as in what I am actually doing I have a $512\times512$ area with about $1000$ seed points for the mesh. Is there a better way to approach this?


This is possible already in version 12, but just undocumented.

grouped =  GatherBy[points, Region`Mesh`MeshNearestCellIndex[randMesh]];

Apparently, this can find only top-dimensional cells. This is a good example where the syntax of undocumented code was changed in the final version.

  • 1
    $\begingroup$ Ugh I feel like I always get hit by the undocumented things. Thanks for the simple fix $\endgroup$ Mar 20 '20 at 21:49
  • $\begingroup$ You're welcome. $\endgroup$ Mar 20 '20 at 21:50

In version 12.1 you can use NearestMeshCells with GatherBy as follows:

grouped = GatherBy[points, NearestMeshCells[{randMesh, 2}, #] &];

 ListPlot[grouped, BaseStyle -> PointSize[Large], 
  PlotLegends -> ("group-" <> ToString[#] & /@ Range[Length @ grouped])]]

enter image description here

  • $\begingroup$ What if I have 12.0? :) $\endgroup$ Mar 20 '20 at 21:40
  • 1
    $\begingroup$ @AaronStevens it’s worth the upgrade! Especially for when undocumented functions go documented like in this example! $\endgroup$ Mar 20 '20 at 22:39
  • $\begingroup$ kglr, the link and linked term are missing a necessary s, I could not edit as it is less than 6 characters $\endgroup$ Mar 21 '20 at 3:07
  • $\begingroup$ Thank you @CATrevillian. I fixed it. $\endgroup$
    – kglr
    Mar 21 '20 at 3:13
  • $\begingroup$ Is it possible to generate a more efficient version of the function NearestMeshCells[{randMesh, 2}, #] & with NearestMeshCells[{randMesh, 2}]? Typically, this is possible with Nearest-related constructs. $\endgroup$ Mar 21 '20 at 8:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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