9
$\begingroup$

enter image description here

Given a 3×3×3 cube made of 27 unit blocks. If the cube is painted, then each of the blocks has 3 of its faces painted, a given block may have 0, 1, 2 , or 3 of its faces painted. I want to mark different colors for them. I came up with the following way, it only works for n=3 and n=4, and coloring only the boundary is better than coloring the whole cube. Do you have a better way? Maybe the mesh based method will be useful.

n = 3;
pts = Tuples[Range[0, n - 1], 3];
pts1 = Tuples[{0, n - 1}, 3];
pts2 = Position[CrossMatrix[All, n {1, 1, 1}], 1] - 1;
pts3 = Complement[pts, pts1, pts2];
Graphics3D[{
  Red, Translate[Cuboid[], pts1],
  Blue, Translate[Cuboid[], pts2],
  Green, Translate[Cuboid[], pts3]
  }]
$\endgroup$

3 Answers 3

5
$\begingroup$

Updated

  • We use GridGraph to get the relations of the connect.
  • By using such connect relation, we can collect which surfaces of the cuboids should be colorize.
Clear["Global`*"];
n = 5;
g = Graph3D[GridGraph[{n, n, n}], 
   VertexCoordinates -> Tuples[Range[n], 3]];
coords = AssociationThread[VertexList[g] -> GraphEmbedding[g]];
colors = {1 -> Blue, 2 -> Green, 3 -> Red, 0 -> Opacity[.5]};
index2normal = {1 -> {0, 0, -1}, 2 -> {0, -1, 0}, 3 -> {1, 0, 0}, 
   4 -> {0, 1, 0}, 5 -> {-1, 0, 0}, 6 -> {0, 0, 1}};
normal2index = Reverse[index2normal, {2}];
normal[i_] := # - (i /. coords) & /@ (AdjacencyList[g, i] /. coords);
draw[i_] := 
  Module[{indexs, coidexs, faces}, 
   indexs = normal[i] /. normal2index;
   coindexs = Complement[Range[6], indexs];
   faces = MeshPrimitives[Cuboid[(i /. coords)/.75], 2];
   {Length@coindexs /. colors, faces[[coindexs]], Opacity[.5], White, 
    faces[[indexs]]}];
Graphics3D[Table[draw[i], {i, VertexList[g]}], Boxed -> False]

enter image description here

A starting point.

Clear["Global`*"];
n = 8;
g = Graph3D[GridGraph[{n, n, n}], EdgeStyle -> Transparent];
vd = VertexDegree[g];
rules = {1 -> Magenta, 2 -> Green, 3 -> Red, 4 -> Green, 5 -> Blue, 
   6 -> Opacity[.5]};
vf2[pt_, name_, bd_] := {EdgeForm[Black], Cuboid[pt - bd, pt + bd]}
size = .5;
HighlightGraph[g, 
 Table[Style[VertexList[g][[i]], vd[[i]] /. rules], {i, 
   VertexCount[g]}], EdgeShapeFunction -> "Line", 
 VertexShapeFunction -> vf2, VertexSize -> size, 
 VertexCoordinates -> Tuples[Range[n], 3]]

enter image description here

$\endgroup$
8
$\begingroup$
ClearAll[coloredCuboids];

coloredCuboids[m_] :=
 Map[{Switch[Count[#, 1 | m], 3, Red, 2, Green, _, Blue], Cuboid @ #} & ] @ 
 Tuples[Range @ m, 3]

Multicolumn[Graphics3D[coloredCuboids[#], 
    Boxed -> False, ImageSize -> 150, PlotLabel -> #] & /@ Range[12],
  4, Appearance -> "Horizontal"]

enter image description here

$\endgroup$
1
  • 1
    $\begingroup$ Nice work!(+1) How do we color only the outside faces, just like the second row of the picture in the question? $\endgroup$
    – matrix42
    Commented Dec 22, 2023 at 13:01
3
$\begingroup$

Using Array* functions:

Clear["Global`*"];
cubesArray[n_Integer /; n <= 2] := Module[{res},
  If[n < 1, res = "\[Wolf]"];
  If[n == 1, res = {{{2}}}];
  If[n == 2 , res = {{{2, 2}, {2, 2}}, {{2, 2}, {2, 2}}}];
  res
  ]

cubesArray[n_Integer /; n > 2] := Module[{tmid, tupdn, res},
  tmid = ConstantArray[ConstantArray[3, {n, n}] //
     ReplacePart[#, {{1, 1} -> 1, {1, n} -> 1, {n, 1} -> 1, {n, n} -> 
         1}] &, n - 2];
  tupdn = 
   ArrayPad[ConstantArray[3, {n - 2, n - 2}], 1, 1] // 
    ReplacePart[#, {{1, 1} -> 2, {1, n} -> 2, {n, 1} -> 2, {n, n} -> 
        2}] &;
  res = Join[{tupdn}, tmid, {tupdn}] 
  ]

Usage:

ArrayPlot3D[cubesArray[#]
     , ColorRules -> {1 -> Green, 2 -> Red, 3 -> Blue}
     , Boxed -> False
     , PlotLabel -> #
     ] & /@ Range[1, 11] //
  Partition[#, UpTo[4]] & // GraphicsGrid[#, ImageSize -> 600] &

enter image description here


Explanations:

Essentially it is a stack up of 2D matrices in 3D. For example,

cubesArray[4] // Map[MatrixForm]

enter image description here

Since the cubesArray is being built up from the inside out, the first two cases are conveniently added using custom definitions above.

For n>2, there is an array tmid of n-2 slices (matrices) which are Blue colored initially. Green corners are added to each using ReplacePart.

The top and bottom (or more correctly called front and back) slices called tupdn start out with a blue core which is n-2 x n-2. This is ArrayPaded with Green sides, and then the Red corners are added using ReplacePart.

Subsequently, the 3D matrix is put together using the Join command.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.