13
$\begingroup$

How to create an image of a 3D die from the 2D images?

enter image description hereenter image description hereenter image description here

enter image description hereenter image description here enter image description here

There is an example in the Documentation Center

enter image description here

I tried enter image description here

but it doesn't work.

$\endgroup$
20
$\begingroup$

By using a cube with rounded corners, from this answer, and by applying the images as "stickers" onto the sides of this cube, the dice can be made to look a little bit more realistic. The black border does not translate well to a 3D visualization, so I hid it by fiddling with the vertex coordinates.

faces = Import /@ {
    "http://i.stack.imgur.com/FdfMj.png",
    "http://i.stack.imgur.com/Qv7w6.png",
    "http://i.stack.imgur.com/WayOQ.png",
    "http://i.stack.imgur.com/mgjkA.png",
    "http://i.stack.imgur.com/qa5bK.png",
    "http://i.stack.imgur.com/T8szh.png"
    };

polygons = With[{eps = 0.01, k = 0.05}, {
    {{k, k, 0 - eps}, {k, 1 - k, 0 - eps}, {1 - k, 1 - k, 0 - eps}, {1 - k, k, 0 - eps}},
    {{k, 0 - eps, k}, {1 - k, 0 - eps, k}, {1 - k, 0 - eps, 1 - k}, {k, 0 - eps, 1 - k}},
    {{1 + eps, k, k}, {1 + eps, 1 - k, k}, {1 + eps, 1 - k, 1 - k}, {1 + eps, k, 1 - k}},
    {{1 - k, 1 + eps, k}, {k, 1 + eps, k}, {k, 1 + eps, 1}, {1 - k, 1 + eps, 1 - k}},
    {{0 - eps, 1 - k, k}, {0 - eps, k, k}, {0 - eps, k, 1 - k}, {0 - eps, 1 - k, 1 - k}},
    {{1 - k, k, 1 + eps}, {1 - k, 1 - k, 1 + eps}, {k, 1 - k, 1 + eps}, {k, k, 1 + eps}}
    }];

(* roundedCuboid: https://mathematica.stackexchange.com/questions/49313/drawing-a-cuboid-with-rounded-corners *)
roundedCuboid[p0 : {x0_, y0_, z0_}, p1 : {x1_, y1_, z1_}, r_] := {
   EdgeForm[None],
   Cuboid[p0 + {0, r, r}, p1 - {0, r, r}],
   Cuboid[p0 + {r, 0, r}, p1 - {r, 0, r}],
   Cuboid[p0 + {r, r, 0}, p1 - {r, r, 0}],
   Table[Cylinder[{{x0 + r, y, z}, {x1 - r, y, z}}, r], {y, {y0 + r, y1 - r}}, {z, {z0 + r, z1 - r}}], 
   Table[Cylinder[{{x, y0 + r, z}, {x, y1 - r, z}}, r], {x, {x0 + r, x1 - r}}, {z, {z0 + r, z1 - r}}], 
   Table[Cylinder[{{x, y, z0 + r}, {x, y, z1 - r}}, r], {x, {x0 + r, x1 - r}}, {y, {y0 + r, y1 - r}}], 
   Table[Sphere[{x, y, z}, r], {x, {x0 + r, x1 - r}}, {y, {y0 + r, y1 - r}}, {z, {z0 + r, z1 - r}}]
   };

sticker[img_, coords_] := With[{eps = 0.92}, {
   EdgeForm[None],
   Texture[img],
   Polygon[coords, 
    VertexTextureCoordinates -> {{eps, eps}, {1 - eps, eps}, {1 - eps, 1 - eps}, {eps, 1 - eps}}]
   }]

Graphics3D[{
  White, roundedCuboid[{0, 0, 0}, {1, 1, 1}, 1/20],
  MapThread[sticker, {faces, polygons}]
  },
 Boxed -> False, Lighting -> "Neutral"
 ]

Mathematica graphics

$\endgroup$
  • $\begingroup$ I wonder if it might be neater (and less error prone) to extract the geometry from PolyhedronData["Cube", ...] and modify it for the rounded edges. (e.g. turn the Lines in "Edges" into Tubes, and then offset all the faces along their normal). $\endgroup$ – Martin Ender Mar 18 '16 at 9:20
  • $\begingroup$ @Martin, more or less what I did in my answer to that other thread, but I went further and used NURBS for rounding out the edges and corners. $\endgroup$ – J. M. will be back soon Mar 18 '16 at 10:17
  • $\begingroup$ @MartinBüttner Maybe. Does not really matter since I am using a pre-made working solution for that part but then why did I prefer that answer over the others? I actually like being able to see exactly what's going on by just looking at the code. Hiding the construction of the box in a higher level built-in function prevents that. $\endgroup$ – C. E. Mar 18 '16 at 11:04
22
$\begingroup$

Image3D isn't what you're looking for. That actually generates a "3-dimensional image" with voxels instead of pixels (by using the given images as layers in the voxel grid). That's what you're seeing in the example you included.

What you want is render a bunch of (square) polygons and use your images as textures. To do so you'll need Texture and the VertexTextureCoordinates option of Polygons. You can get the faces of a cube from PolyhedronData, which you can destructure and then reassemble with the correct textures. (I wonder if there's a way to apply multiple textures to the single GraphicsComplex object returned by PolyhedronData instead.)

Here is some code:

faces = Import /@ {
    "http://i.stack.imgur.com/FdfMj.png",
    "http://i.stack.imgur.com/Qv7w6.png",
    "http://i.stack.imgur.com/WayOQ.png",
    "http://i.stack.imgur.com/mgjkA.png",
    "http://i.stack.imgur.com/qa5bK.png",
    "http://i.stack.imgur.com/T8szh.png"
};

(* standard texture coordinates for mapping a texture completely onto a quad *)
fullQuad = {{0, 0}, {1, 0}, {1, 1}, {0, 1}};

(* get the cube's face polygons *)
cube = PolyhedronData["Cube", "Faces"];

(* pick out the individual faces and pair them with the corresponding texture *)
Graphics3D[
 MapThread[
  {
    Texture[#],
    Polygon[cube[[1, #2]], VertexTextureCoordinates -> fullQuad]
    } &,
  {
   faces,
   cube[[2, 1]]
   }
  ],
 Lighting -> "Neutral",
 Boxed -> False
]

enter image description here

As you can see, this isn't quite perfect, because it doesn't follow the rounded edges of your textures, but extracting the shape of those and using it to generate a model on the fly will be a lot trickier.

$\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.