Space-Filling Tetrahedron

Author

Eric W. Weisstein
August 18, 2026

This notebook downloaded from https://mathworld.wolfram.com/notebooks/Polyhedra/Space-FillingTetrahedron.nb.

For more information, see Eric's MathWorld entry https://mathworld.wolfram.com/Space-FillingTetrahedron.html.

©2026 Wolfram Research, Inc. except for portions noted otherwise

Additional Authors

Coordinate data and construction code from
Ed Pegg, Jr.
July 27, 2026

Definitions

pointTransform[points_, matrix_, shift_] := (matrix . # + shift) & /@ points;
makeCell[seed_, transforms_] := pointTransform[seed, #[[1]], #[[2]]] & /@ transforms;
tetrahedronVolume[points_] := Abs[Det[(# - First[points]) & /@ Rest[points]]]/6;
squaredDistanceKey[points_] := Sort[SquaredEuclideanDistance @@@ Subsets[points, {2}]];
isometryMatrixQ[matrix_] := Simplify[Transpose[matrix] . matrix == IdentityMatrix[3]] && MemberQ[{-1, 1}, Det[matrix]];
cellCheck[entry_] := Module[{pieces, unionVolume, totalVolume, hullVolume},
	pieces = entry["DisplayPieces"];
	unionVolume = Quiet[RegionMeasure[RegionUnion @@ (ConvexHullMesh /@ pieces)], BoundaryMeshRegion::bsuncl];
	totalVolume = Total[tetrahedronVolume /@ pieces];
	hullVolume = RegionMeasure[ConvexHullMesh[DeleteDuplicates[Flatten[pieces, 1]]]];
	<|
		"Pieces" -> Length[pieces],
		"SquaredEdgeLengths" -> squaredDistanceKey[entry["Seed"]],
		"Isometries" -> And @@ (isometryMatrixQ[First[#]] & /@ entry["Transforms"]),
		"Congruent" -> SameQ @@ (squaredDistanceKey /@ entry["Pieces"]),
		"DisjointAndComplete" -> Simplify[unionVolume == totalVolume == hullVolume]
		|>
	];
pieceGraphic[points_] := Graphics3D[
	{Directive[StandardOrange, Opacity[0.72], EdgeForm[Directive[LightDarkSwitched@Black, Thin]]], MeshPrimitives[ConvexHullMesh[points], 2]},
	Boxed -> False, Lighting -> "ThreePoint", PlotRange -> All,
	ViewPoint -> {1.7, -2.1, 1.35}
	];
cellGraphic[pieces_] := Module[{allPoints},
	allPoints = DeleteDuplicates[Flatten[pieces, 1]];
	Graphics3D[
		{
			MapIndexed[
				{ColorData[97][1 + Mod[First[#2] - 1, 12]], Opacity[0.52], EdgeForm[Directive[LightDarkSwitched@Black, Thin]], MeshPrimitives[ConvexHullMesh[#1], 2]} &,
				pieces
				],
			Directive[LightDarkSwitched @ Black, Opacity[1], AbsoluteThickness[1.15]], MeshPrimitives[ConvexHullMesh[allPoints], 1]
			},
		Boxed -> False, Lighting -> "ThreePoint", PlotRange -> All,
		SphericalRegion -> True,
		ViewPoint -> {1.7, -2.1, 1.35}
		]
	];
entryCard[entry_] := Labeled[
	Row[{pieceGraphic[entry["Seed"]], cellGraphic[entry["DisplayPieces"]]}],
	Style[First[entry["Names"]], Italic, 14, FontFamily -> "Times", LightDarkSwitched@Black], Top
	];

Data

The five entries are fixed representatives of the classical space-filling tetrahedra described by Sommerville, Baumgartner, Hill, and Goldberg. The coordinate data below are exact.

names = {
	{"Sommerville No. 1", "Baumgartner T", "Hill 1-60"},
	{"Sommerville No. 2", "Baumgartner T1", "Hill special"},
	{"Sommerville No. 3", "Hill 2-45"},
	{"Sommerville No. 4", "Baumgartner T4"},
	{"Baumgartner T3", "Hill 2-60"}
	};
cellNames = {"triangular prism", "parallelepiped", "cube", "oblique triangular prism", "oblique triangular prism"};
tetrahedra = {
	{{1, 1, 1}, {2, 2, 0}, {2, 2, 2}, {3, 1, 1}},
	{{1, 1, 1}, {2, 2, 0}, {2, 2, 2}, {2, 1, 1}},
	{{1, 1, 1}, {2, 2, 0}, {2, 2, 2}, {2, 0, 0}},
	{{1, 1, 1}, {2, 2, 0}, {2, 2, 2}, {2, 3/2, 1}},
	{{0, 3, 3}, {1, 4, 2}, {3, 2, 4}, {1, 0, 2}}
	};
cellTransforms = {
	{
		{IdentityMatrix[3], {0, 0, 0}},
		{{{0, 1, 0}, {-1, 0, 0}, {0, 0, -1}}, {0, 4, 2}},
		{{{-1, 0, 0}, {0, 0, -1}, {0, 1, 0}}, {3, 3, -1}}
		},
	{
		{IdentityMatrix[3], {0, 0, 0}},
		{{{0, -1, 0}, {0, 0, -1}, {-1, 0, 0}}, {3, 3, 3}},
		{{{-1, 0, 0}, {0, 0, -1}, {0, -1, 0}}, {3, 3, 3}},
		{{{0, -1, 0}, {0, 0, -1}, {1, 0, 0}}, {3, 3, -1}},
		{{{-1, 0, 0}, {0, 0, -1}, {0, 1, 0}}, {3, 3, -1}},
		{{{1, 0, 0}, {0, -1, 0}, {0, 0, -1}}, {0, 4, 2}}
		},
	{
		{IdentityMatrix[3], {0, 0, 0}},
		{{{0, 1, 0}, {1, 0, 0}, {0, 0, -1}}, {0, 0, 2}},
		{{{1, 0, 0}, {0, -1, 0}, {0, 0, -1}}, {0, 2, 2}},
		{{{0, 1, 0}, {0, 0, 1}, {1, 0, 0}}, {0, 0, 0}},
		{{{0, -1, 0}, {0, 0, -1}, {1, 0, 0}}, {2, 2, 0}},
		{{{0, 1, 0}, {0, 0, 1}, {-1, 0, 0}}, {0, 0, 2}},
		{{{0, -1, 0}, {1, 0, 0}, {0, 0, 1}}, {2, 0, 0}},
		{{{0, -1, 0}, {0, 0, -1}, {-1, 0, 0}}, {2, 2, 2}},
		{{{0, 1, 0}, {-1, 0, 0}, {0, 0, -1}}, {0, 2, 2}},
		{{{0, -1, 0}, {-1, 0, 0}, {0, 0, 1}}, {2, 2, 0}},
		{{{-1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, {2, 0, 0}},
		{{{-1, 0, 0}, {0, -1, 0}, {0, 0, -1}}, {2, 2, 2}}
		},
	{
		{IdentityMatrix[3], {0, 0, 0}},
		{{{-1, 0, 0}, {0, 1, 0}, {0, 0, -1}}, {4, 0, 2}},
		{{{0, 0, -1}, {0, -1, 0}, {-1, 0, 0}}, {3, 3, 3}},
		{{{0, 0, -1}, {0, -1, 0}, {1, 0, 0}}, {3, 3, -1}},
		{{{0, 0, -1}, {-1, 0, 0}, {0, 1, 0}}, {3, 3, -1}},
		{{{1, 0, 0}, {0, 0, -1}, {0, -1, 0}}, {0, 2, 2}},
		{{{-1, 0, 0}, {0, 0, -1}, {0, -1, 0}}, {4, 2, 2}},
		{{{0, 1, 0}, {-1, 0, 0}, {0, 0, -1}}, {1, 3, 1}},
		{{{0, -1, 0}, {0, 0, -1}, {-1, 0, 0}}, {4, 2, 2}},
		{{{0, -1, 0}, {0, 0, -1}, {1, 0, 0}}, {4, 2, -2}},
		{{{0, 0, -1}, {1, 0, 0}, {0, 1, 0}}, {3, -1, -1}},
		{{{0, 1, 0}, {1, 0, 0}, {0, 0, -1}}, {1, -1, 1}}
		},
	{
		{IdentityMatrix[3], {0, 0, 0}},
		{{{0, 0, 1}, {0, -1, 0}, {1, 0, 0}}, {-1, 4, 1}},
		{{{0, 1, 0}, {0, 0, -1}, {-1, 0, 0}}, {1, 6, 3}},
		{{{0, -1, 0}, {-1, 0, 0}, {0, 0, -1}}, {5, 5, 4}},
		{{{-1, 0, 0}, {0, 0, 1}, {0, 1, 0}}, {4, 0, 0}},
		{{{0, 0, -1}, {1, 0, 0}, {0, -1, 0}}, {5, 1, 4}}
		}
	};
cells = MapThread[makeCell, {tetrahedra, cellTransforms}];
entries = MapThread[
	<|"Names" -> #1, "Cell" -> #2, "Seed" -> #3, "Transforms" -> #4, "Pieces" -> #5, "DisplayPieces" -> #6|> &,
	{names, cellNames, tetrahedra, cellTransforms, cells, cells}
	];

Figures

In each panel, the orange tetrahedron is the seed and the multicolored solid is an assembled space-filling cell.

GraphicsGrid[
Partition[entryCard/@entries,UpTo[3]],
Dividers->All,
Alignment->Top
]

Rep-8 Subdivisions

The first three Sommerville tetrahedra are rep-8-tiles. Each parent tetrahedron below is subdivided through its six edge midpoints into eight congruent copies at linear scale 1/2. Applying the same affine subdivision to those pieces gives 64 copies at scale 1/4.

repParents = {
	{{0, 0, 2}, {0, 4, 2}, {2, 2, 0}, {2, 2, 4}},
	{{0, 2, 0}, {0, 2, 4}, {2, 0, 2}, {2, 2, 2}},
	{{0, 0, 0}, {2, 2, 2}, {4, 0, 0}, {4, 4, 0}}
	};
repPieces = {
	{
		{{0, 0, 2}, {0, 2, 2}, {1, 1, 1}, {1, 1, 3}},
		{{0, 2, 2}, {0, 4, 2}, {1, 3, 1}, {1, 3, 3}},
		{{0, 2, 2}, {2, 2, 2}, {1, 1, 1}, {1, 1, 3}},
		{{0, 2, 2}, {2, 2, 2}, {1, 1, 1}, {1, 3, 1}},
		{{0, 2, 2}, {2, 2, 2}, {1, 1, 3}, {1, 3, 3}},
		{{0, 2, 2}, {2, 2, 2}, {1, 3, 1}, {1, 3, 3}},
		{{1, 1, 1}, {1, 3, 1}, {2, 2, 0}, {2, 2, 2}},
		{{1, 1, 3}, {1, 3, 3}, {2, 2, 2}, {2, 2, 4}}
		},
	{
		{{0, 2, 0}, {1, 1, 1}, {1, 2, 1}, {0, 2, 2}},
		{{0, 2, 2}, {1, 1, 1}, {1, 1, 2}, {2, 2, 2}},
		{{0, 2, 2}, {1, 1, 1}, {1, 2, 1}, {2, 2, 2}},
		{{0, 2, 2}, {1, 1, 3}, {1, 1, 2}, {2, 2, 2}},
		{{0, 2, 2}, {1, 1, 3}, {1, 2, 3}, {0, 2, 4}},
		{{0, 2, 2}, {1, 1, 3}, {1, 2, 3}, {2, 2, 2}},
		{{1, 1, 1}, {2, 0, 2}, {2, 1, 2}, {1, 1, 3}},
		{{1, 1, 1}, {2, 2, 2}, {2, 1, 2}, {1, 1, 3}}
		},
	{
		{{0, 0, 0}, {1, 1, 1}, {2, 0, 0}, {2, 2, 0}},
		{{1, 1, 1}, {2, 0, 0}, {2, 2, 0}, {2, 2, 2}},
		{{2, 0, 0}, {2, 2, 0}, {2, 2, 2}, {3, 1, 1}},
		{{2, 0, 0}, {2, 2, 0}, {3, 1, 1}, {4, 0, 0}},
		{{2, 2, 0}, {2, 2, 2}, {3, 1, 1}, {4, 2, 0}},
		{{2, 2, 0}, {2, 2, 2}, {3, 3, 1}, {4, 2, 0}},
		{{2, 2, 0}, {3, 1, 1}, {4, 0, 0}, {4, 2, 0}},
		{{2, 2, 0}, {3, 3, 1}, {4, 2, 0}, {4, 4, 0}}
		}
	};

distanceMatrix[points_] := Outer[SquaredEuclideanDistance, points, points, 1];
barycentricCoordinates[tet_, point_] := LinearSolve[
	Transpose[Append[#, 1] & /@ tet],
	Append[point, 1]
	];
affinePoint[tet_, coordinates_] := coordinates . tet;
similarVertexOrder[parent_, piece_] := Module[{scaleSquared},
	scaleSquared = (tetrahedronVolume[piece]/tetrahedronVolume[parent])^(2/3);
	SelectFirst[
		Permutations[piece],
		distanceMatrix[#] === scaleSquared * distanceMatrix[parent] &
		]
	];
refineRep8[parent_, pattern_][pieces_] := Module[{barycentricPattern},
	barycentricPattern = Map[barycentricCoordinates[parent, #] &, pattern, {2}];
	Flatten[
		Function[piece,
			Map[
				affinePoint[similarVertexOrder[parent, piece], #] &,
				barycentricPattern,
				{2}
				]
			] /@ pieces,
		1
		]
	];
repLevels = MapThread[
	NestList[refineRep8[#1, #2], {#1}, 2] &,
	{repParents, repPieces}
	];

repLevelLabels = {"8 pieces", "64 pieces"};
GraphicsGrid[
	Table[
		Labeled[
			cellGraphic[repLevels[[column, level]]],
			Style[
				names[[column, 1]] <> " (" <> repLevelLabels[[level - 1]] <> ")",
				Italic,
				14,
				FontFamily -> "Times",
				LightDarkSwitched @ Black
				],
			Top
			],
		{level, 2, 3},
		{column, 3}
		],
	Alignment -> Top,Dividers->All
	]

Verification

The first check verifies exact similarity, containment, volume, and pairwise disjoint interiors for each eight-piece subdivision. Since the 64-piece level is obtained by transporting this verified partition affinely into every first-level tetrahedron, its disjointness and completeness follow from the construction; the second check verifies its exact count, similarity, containment, and volume.

interiorsOverlapQ[{first_, second_}] := Module[{a, b, t, maximum},
	a = Table[Unique["a"], {4}];
	b = Table[Unique["b"], {4}];
	maximum = MaxValue[
		{
			t,
			And @@ Join[
				Thread[a >= t],
				Thread[b >= t],
				{Total[a] == 1, Total[b] == 1},
				Thread[a . first == b . second]
				]
			},
		Join[a, b, {t}]
		];
	maximum > 0
	];
repLevelCheck[parent_, pieces_, checkDisjointness_] := Module[{scaleSquared},
	scaleSquared = (tetrahedronVolume[First[pieces]]/tetrahedronVolume[parent])^(2/3);
	<|
		"PieceCount" -> Length[pieces],
		"ScaleFactor" -> Sqrt[scaleSquared],
		"AllSimilar" -> AllTrue[
			pieces,
			Sort[SquaredEuclideanDistance @@@ Subsets[#, {2}]] ===
				Sort[scaleSquared * (SquaredEuclideanDistance @@@ Subsets[parent, {2}])] &
			],
		"Contained" -> And @@ Flatten[
			Map[
				And @@ Thread[barycentricCoordinates[parent, #] >= 0] &,
				pieces,
				{2}
				]
			],
		"VolumeComplete" -> Total[tetrahedronVolume /@ pieces] === tetrahedronVolume[parent],
		"PairwiseInteriorDisjoint" -> If[
			checkDisjointness,
			NoneTrue[Subsets[pieces, {2}], interiorsOverlapQ],
			"Follows from affine refinement"
			]
		|>
	];

{
	MapThread[repLevelCheck[#1, #2, True] &, {repParents, repLevels[[All, 2]]}],
	MapThread[repLevelCheck[#1, #2, False] &, {repParents, repLevels[[All, 3]]}]
	}

References

M. Goldberg, "Three Infinite Families of Tetrahedral Space-Fillers," Journal of Combinatorial Theory, Series A 16 (1974), 348-354. https://doi.org/10.1016/0097-3165(74)90058-2

J. Kyncl and Z. Patakova, "On the Nonexistence of k-Reptile Simplices in R^3 and R^4," Electronic Journal of Combinatorics 24 (2017), Paper 3.1, 44 pp. https://doi.org/10.37236/6113

D. J. T. Liu and Q. Du, "Optimization of Subdivision Invariant Tetrahedra," International Journal of Computational Geometry and Applications 25 (2015), 37-56. https://doi.org/10.1142/S0218195915500041

M. Senechal, "Which Tetrahedra Fill Space?" Mathematics Magazine 54 (1981), 227-243. https://doi.org/10.1080/0025570X.1981.11976933

D. M. Y. Sommerville, "Space-Filling Tetrahedra in Euclidean Space," Proceedings of the Edinburgh Mathematical Society 41 (1922), 49-57. https://doi.org/10.1017/S001309150007783X