Working with text in 3D graphics
You could always just Texture
your Text
in:
o = Graphics3D[{{EdgeForm[{Thickness[.000001], GrayLevel@0}], Blue,
Cuboid[{-4, 0, 0}, {4, 2.4, 1}]}, {EdgeForm[{Thickness[.000001],
GrayLevel@0}], Blue,
Cuboid[{-4, 3.4, 0}, {4, 3.6,
1}]}, {EdgeForm[{Thickness[.000001], GrayLevel@0}], Blue,
Cuboid[{-4, 4.6, 0}, {4, 7, 1}]}, {EdgeForm[{Thickness[.000001],
GrayLevel@0}], Blue, Cuboid[{-4, 0, 0}, {4, 7, -1}]}, {Cyan,
Opacity[.95], Cuboid[{-4, 2.4, 0}, {4, 3.4, 1}]}, {Yellow,
Opacity[.95], Cuboid[{-4, 3.6, 0}, {4, 4.6, 1}]}}, Boxed -> False,
ImageSize -> 800];
text = First[
First[ImportString[
ExportString[
Style["testing one two three", Italic, FontSize -> 24,
FontFamily -> "Times"], "PDF"], "PDF",
"TextMode" -> "Outlines"]]];
r = ImagePad[
Rasterize[Graphics[{EdgeForm[None], Darker@Blue, text}],
Background -> None,
ImageResolution -> 1000], {{200, 200}, {0, 30}}];
face = {{-4, 2.4`, 1.01`}, {4, 2.4`, 1.01`}, {4, 3.4`, 1.01`}, {-4,
3.4`, 1.01`}};
Show[o, Graphics3D[{Texture[r],
Polygon[RotateRight[face, 4],
VertexTextureCoordinates -> {{0, 0}, {1, 0}, {1, 1}, {0, 1}}]}],
Lighting -> "Neutral"]
Like M.R. I recommend using texture mapping to put a label on a surface. However, I would write somewhat simpler code to do it.
First rasterize the text.
text =
Rasterize[Style["Text as a texture", "SR"],
RasterSize -> 500, ImageSize -> 200, Background -> None];
Next make a 3D-polygon having the rasterized text mapped onto it. The polygon is is designed to float just above the cuboid surface it labels.
label =
With[
{rectangle =
With[{dz = .001},
{{-4, 3.6, 1 + dz}, {4, 3.6, 1 + dz}, {4, 4.6, 1 + dz}, {-4, 4.6, 1 + dz}}],
textCorners = {{0, 0}, {1, 0}, {1, 1}, {0, 1}}},
{Texture[text], Polygon[rectangle, VertexTextureCoordinates -> textCorners]}];
Finally, add the label to your graphics.
Graphics3D[
{{Blue, EdgeForm[],
{Cuboid[{-4, 0, 0}, {4, 2.4, 1}],
Cuboid[{-4, 3.4, 0}, {4, 3.6, 1}],
Cuboid[{-4, 4.6, 0}, {4, 7, 1}],
Cuboid[{-4, 0, 0}, {4, 7, -1}]}},
{Cyan, Cuboid[{-4, 2.4, 0}, {4, 3.4, 1}]},
{Yellow, Cuboid[{-4, 3.6, 0}, {4, 4.6, 1}]},
label},
Boxed -> False, ImageSize -> 500]
An approach without using Texture
:
- Use M.R.'s
ImportString[ExportString[..., "PDF"], "PDF", "TextMode" -> "Outlines"]
trick to make your text into a list ofFilledCurves
. - Use the function
filledCurveToPolygons3D
this answer by Simon Woods to convertFilledCurves
to polygons in 3D - Use
NDSolve`FEM`GraphicsPrimitiveToGraphicsComplex
to convert graphics primitives toGraphicsComplex
- Use the function
rescale
below toRescale
the coordinates of the primitives from the previous step to place them in the appropriate positions in the inputGraphics3D
.
Using text
and o
from @M.R.'s answer:
gc3d = NDSolve`FEM`GraphicsPrimitiveToGraphicsComplex[Cases[text /.
f_FilledCurve :> filledCurveToPolygons3D[f], _Polygon, Infinity]];
rescale[ranges_, style___ : FaceForm[Red]] := # /.
GraphicsComplex[c_, prims___] :> GraphicsComplex[
Transpose[Table[Rescale[Transpose[c][[i]],
Through[{Min, Max}@Transpose[c][[i]]], ranges[[i]]], {i, 1, 3}]],
{style, prims}] &;
ranges1 = {{-3.6, 3.6}, {2.5, 3.3}, {1.001, 1.001}};
ranges2 = {{-3.6, 3.6}, {3.5, 4.5}, {1.001, 1.001}}
ranges3 = {{3.6, -3.6}, {6.5, 5}, {1.001, 1.001}};
Show[Graphics3D[rescale[ranges1] @ gc3d],
Graphics3D[rescale[ranges2, EdgeForm[], FaceForm[Blue]] @ gc3d],
Graphics3D[rescale[ranges3, EdgeForm[], FaceForm[Yellow]] @ gc3d], o]