2
$\begingroup$

I am new to Mathematica & I am facing a problem as follows: I have created a Voronoi diagram and now I want to assign to each region, a value, i.e., I want to extend this Voronoi diagram to form a 2 variable function in Mathematica. For example, let one of the cells be named $R_1$, I want that my 2 variable function takes a constant value (e.g., $f(x,y)=4$) to all the points in $R_1$. Similarly for the other cells.

I am also including the information about how Voronoi diagram is being stored herein. What I am using is VoronoiDiagram[refpoints] function that returns the vertices of polygons and cells with corresponding vertices of which they are made up of. Also, since the edges partitioning in Voronoi diagrams are straight lines, it is possible to trace out the cells.

$\endgroup$
1
$\begingroup$

Nearest

We can construct such a function $f$ using the definition of Voronoi diagram. Given a set of generating points $p_1, p_2, \ldots, p_n$ the Voronoi cell $R_i$ consists of all points in the plane that are closer to $p_i$ than to any of the other generators. In other words, any point belongs to the Voronoi cell of the nearest $p_i$.

Therefore, as indicated by Rahul in the comments, we can use Nearest:

Generate some random points

SeedRandom[10]
pts = RandomReal[10, {10, 2}];

and suppose vals is our list of constant values, for example

vals = {v1, v2, v3, v4, v5, v6, v7, v8, v9, v10};

Make a table of rules to tell Nearest which value we want returned for each nearest point

rules = MapThread[Rule, {pts, vals}]
(* {{6.67917, 8.33874} -> v1, <<...>>,  {7.15778, 6.34697} -> v10} *)

Compute the corresponding NearestFunction and define f

nf = Nearest[rules];
f[x_, y_] := First[nf[{x, y}]]

Try it with a point

f[2.1, 6.8]
(* v4 *)

Since we got v4, the point must have been in $R_4$, indeed

Needs["ComputationalGeometry`"]
Show[DiagramPlot[pts, PlotRange -> {{-2, 12}, {-2, 12}}], 
        Graphics[{Blue, PointSize[Large], Point[{2.1, 6.8}]}]]

enter image description here

Addendum (for version 10.1 or later)

There is an undocumented function that can be used instead of Marco's positioninmesh. For a mesh-based region mr, Region`Mesh`MeshMemberCellIndex[mr, pt] returns the index of the mesh cell containing the point pt.

The example below assigns a constant value (which happens to be a color) to each Voronoi cell and displays it as the point p moves across the mesh

SeedRandom[10];
pts = RandomReal[10, {10, 2}];
vm = VoronoiMesh[pts];
cind = Region`Mesh`MeshMemberCellIndex[vm];
Manipulate[
  HighlightMesh[vm, Style[#, ColorData[88, Last[#]]]]& @ cind[p], {{p, {5, 5}}, Locator}]

enter image description here

$\endgroup$
  • $\begingroup$ further I want to find out the fourier series of this function. So, can I simply use the built-in function FourierSeries[f,{x,y},{5,5}] to accomplish my task? $\endgroup$ – Madhusudana Jun 10 '15 at 8:08
  • $\begingroup$ @Madhusudana Probably not without an explicit formula, functions like FourierSeries and Integrate work with symbolic input. $\endgroup$ – ilian Jun 10 '15 at 16:58
1
$\begingroup$

Let's generate some random points and their corresponding Voronoi mesh diagram:

SeedRandom[10]
points = RandomReal[10, {10, 2}];

Here are the points and the mesh:

Show[
 VoronoiMesh[points],
 ListPlot[points, PlotStyle -> {Red, PointSize[0.02]}],
 Axes -> False, Frame -> True
]

mesh and points

As you mentioned in your question, the Mesh object generated by VoronoiMesh contains information about the mesh cells in its "FaceCoordinates" property:

MapIndexed[{First@#2, Sequence @@ #1} &, VoronoiMesh[points]["FaceCoordinates"]];
Grid[Prepend[%, {"Face", "Coordinates", SpanFromLeft}], Frame -> All, Alignment -> Left]

face coordinates

We can use this information to generate a list of polygon regions that represent each face. We can then generate RegionMemberFunctions, one per polygonal face, that will indicate whether a given point is a member of one of the faces.

mymesh = VoronoiMesh[points];
polygonmemberfunctions = RegionMember[Polygon[#]]& /@ mymesh["FaceCoordinates"];

These functions can be passed to a function that uses them to assign values to a point depending on whether it is found within a certain face. I don't know how you would like to assign those values, so I will have to leave that part to you. For now, the function below returns the face number as that value.

positioninmesh[mesh_, polygonmemberfunctions_, point_] := Module[
  {},
  Position[Through[polygonmemberfunctions[point]], True][[1, 1]]
]

You will probably want to do something with the value of position to assign your desired values instead. You could use a Piecewise definition, or a Switch statement, or other similar constructs.

In the present simple case, we can already use this simple function to assign $z$ values to $(x,y)$ points depending on the face they fall within, as shown by the following density plot (which takes a while to calculate):

DensityPlot[positioninmesh[mymesh, {x, y}], 
   {x, 0, 10}, {y, 0, 10}, 
   MaxRecursion -> 3, PlotPoints -> 20
]

density plot

$\endgroup$
  • $\begingroup$ Thanx MarcoB for your reply. But I am currently using Mathematica 9.0 & VoronoiMesh function is not there in the version 9.0 - since I am altogether new to Mathematica can you please give some hint about if I can proceed simply with VoronoiDiagram command. $\endgroup$ – Madhusudana Jun 5 '15 at 14:31
  • $\begingroup$ @Madhusudana Revised my answer for V9. $\endgroup$ – ilian Jun 7 '15 at 17:40
  • $\begingroup$ @ilian thanx a lot!! $\endgroup$ – Madhusudana Jun 8 '15 at 3:15
1
$\begingroup$

Using:

SeedRandom[10];
pts = RandomReal[10, {10, 2}];
v = VoronoiMesh[pts];

then

f[{x_, y_}] := 
  First@Nearest[pts, {x, y}] /. 
   Thread[pts -> {6, 10, 5, 4, 1, 2, 8, 7, 9, 3}];
re[{x_, y_}] := 
  With[{mp = MeshPrimitives[v, 2]}, 
   Pick[mp, RegionMember[#, {x, y}] & /@ mp]];
Manipulate[
 Column[{Show[v, 
    Graphics[{Point[p], Red, Point[pts], , Hue[f[p]/10], re[p]}]], 
   f[p]}], {{p, {0.5, 0.5}}, Locator}]

Of course f can be defined any way you want.

enter image description here

$\endgroup$

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.