8

Question

Given a set of points in the plane, how can you create a planar graph in the standard graph representation of Mathematica (version 9 or higher), from these points?

Background

A planar graph is a graph embedded in the plane in such a way that the edges intersect at vertices only. This is an example of a planar graph:

g = GridGraph[{3, 3}]

GridGraph

It is stored in the standard Mathematica representation for graphs.

You can also draw a planar graph from a set of points in the plane with ComputationalGeometry`PlanarGraphPlot:

Needs["ComputationalGeometry`"]    
pts = RandomReal[{0, 10}, {10, 2}]
PlanarGraphPlot[pts]

Delaunay triangulation of points

However, the output is not in the standard representation for graphs.

sjdh
  • 7,757
  • 5
  • 37
  • 47

4 Answers4

11

In Version 10, we can do this nicely even for 3D point sets:

pointsToGraph[pts_, graph : (Graph | Graph3D)] := 
 Module[{del = DelaunayMesh[pts], edges},
  edges = UndirectedEdge @@@ MeshCells[del, 1][[All, 1]];
  graph[Range@Length@pts, edges, VertexLabels -> "Name", VertexCoordinates -> pts]
  ]

SeedRandom[2];
pts2d = RandomReal[10, {10, 2}];
pointsToGraph[pts2d, Graph]

Mathematica graphics

SeedRandom[2];
pts3d = RandomReal[10, {30, 3}];
pointsToGraph[pts3d, Graph3D]

Mathematica graphics

RunnyKine
  • 33,088
  • 3
  • 109
  • 176
8

Using Mark McClure's answer, one can easily build a graph by collecting all the edges of a Delaunay triangulation and then removing duplicates. For non-crossing layout, use GraphLayout -> "PlanarEmbedding" (since v9) and add the original points as vertex coordinates.

Needs["ComputationalGeometry`"];
pts = RandomReal[{0, 10}, {10, 2}];
dt = DelaunayTriangulation[pts];
toPairs[{m_, ns_List}] := Map[{m, #} &, ns];
edges = Union[Sort /@ Flatten[toPairs /@ dt, 1]];
Graph[edges, VertexLabels -> "Name", ImagePadding -> 20,
    GraphLayout -> "PlanarEmbedding", VertexCoordinates -> pts]

enter image description here

István Zachar
  • 47,032
  • 20
  • 143
  • 291
  • In your example, some edges cross each other. I would like a result in which non of the edges cross. I'll add this to my question. – sjdh Apr 06 '13 at 12:17
6

Here's one possibility, using an undocumented function for the Delaunay triangulation:

BlockRandom[SeedRandom[131, Method -> "MKL"]; (* for reproducibility *)
            pts = RandomReal[{0, 10}, {10, 2}]];

Graphics`Mesh`MeshInit[];
dt = Delaunay[pts];

Graph[Range[Length[pts]], UndirectedEdge @@@ dt["Edges"], VertexCoordinates -> pts]

Delaunay graph from randomly chosen points

Compare:

GraphicsComplex[dt["Coordinates"],
                {FaceForm[None], EdgeForm[Black], Polygon[dt["Faces"]]}] // Graphics

Delaunay triangles

J. M.'s missing motivation
  • 124,525
  • 11
  • 401
  • 574
2

With IGraph/M,

pts = RandomPoint[Disk[], 10];

IGMeshGraph@DelaunayMesh[pts]

enter image description here

Szabolcs
  • 234,956
  • 30
  • 623
  • 1,263