The easiest way to get centroids of triangles tiling sphere

I need to tile a unit sphere with N equal equilateral spherical triangles and get an array of the coordinates {Phi, Theta} of the centroids of those triangles. What is the most straightforward way to do this in Mathematica? Are there any built-in functions that might help?

• It is mathematically impossible to tile a sphere with an arbitrary $N$ equilateral spherical triangles. – David G. Stork Dec 17 '18 at 17:02
• Ok, that is not the most crucial part. What about tiling with just N triangles? – user15933 Dec 17 '18 at 17:12
• What version of Mathematica are you using? – halirutan Dec 17 '18 at 17:19
• Mathematica 11.3 – user15933 Dec 17 '18 at 17:22
• @DavidG.Stork This is why I have written: "subdivide". I wasn't sure if the OP wants a tiling of the sphere's surface, a subdivision of the 3D sphere for e.g. FEM, or a mesh using triangles that approximates the surface of the sphere. – halirutan Dec 18 '18 at 0:00

2 Answers

I'm still not sure I understood what you are seeking, but let's give it a try. Let us look at a simple function that subdivides a triangle in the following way:

div[expr_] := expr /. Triangle[pts : {a_, b_, c_}] :>
With[{ab = Mean[{a, b}], ac = Mean[{a, c}], bc = Mean[{b, c}]},
Triangle /@ {{a, ab, ac}, {ab, b, bc}, {ab, bc, ac}, {ac, bc, c}}
]

tri = Triangle@Table[{Cos[phi], Sin[phi]}, {phi, {0, 2 Pi/3, 4 Pi/3}}];
GraphicsRow[
Graphics[{FaceForm[None], EdgeForm[Gray], #}] & /@ {tri, div[tri]}]


Now, let us take a look at an Icosahedron

We can access the triangles of this polyhedron using PolyhedronData as well. There might be an easier way to do this, but I'm not digging right now:

pts = Triangle[N@PolyhedronData["Icosahedron", "Vertices"][[#]]] & /@
PolyhedronData["Icosahedron", "Faces"];


Now, we can use the div function to subdivide each of the triangles as often as we want

subpts = Nest[div, pts, 2];
Graphics3D[subpts]


The last step is the most important one: Now we take each vertex and normalize is. This means in 3D it will be projected onto the surface of the unit sphere

Graphics3D[subpts /. Triangle[pts_] :> Triangle[Normalize /@ pts]]


If you want a finer mesh, just use 3, 4 or 5 subdivisions.

Discretize the unit sphere into triangles with DiscretizeRegion[Sphere[]], using the MaxCellMeasure or MeshQualityGoal options to choose the grid quality, and then calculate the centers of the resulting triangles (mesh primitives are all triangles in this case):

MeshPrimitives[DiscretizeRegion[Sphere[]], 2] /. Polygon[L_] :> Normalize[Mean[L]]


{{0.222616, -0.858449, 0.462068}, {0.166477, -0.863634, 0.475837}, ..., {0.425092, 0.502648, 0.752757}, {0.451631, 0.406594, 0.794173}}

This is what the sphere discretization looks like with default parameters:

DiscretizeRegion[Sphere[]]