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.

| improve this answer | |
  • 1
    $\begingroup$ Ugh I feel like I always get hit by the undocumented things. Thanks for the simple fix $\endgroup$ – BioPhysicist Mar 20 at 21:49
  • $\begingroup$ You're welcome. $\endgroup$ – Henrik Schumacher Mar 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

| improve this answer | |
  • $\begingroup$ What if I have 12.0? :) $\endgroup$ – BioPhysicist Mar 20 at 21:40
  • 1
    $\begingroup$ @AaronStevens it’s worth the upgrade! Especially for when undocumented functions go documented like in this example! $\endgroup$ – CA Trevillian Mar 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$ – CA Trevillian Mar 21 at 3:07
  • $\begingroup$ Thank you @CATrevillian. I fixed it. $\endgroup$ – kglr Mar 21 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$ – Henrik Schumacher Mar 21 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.