34
$\begingroup$

Some idea of how to do something similar to the image, but with any 3d object

Any body in 3d

$\endgroup$
1

2 Answers 2

34
$\begingroup$

Update 2: The function projectToWalls does not work in version 12.0 because the function PlotRange no longer works. To fix the issue, replace PlotRange with plotRange where

 plotRange = PlotRange/.AbsoluteOptions[#, PlotRange] &;

in the definition of projectToWalls.

Original answer:

You can post-process a Graphics3D object to project the lines to the left, back and bottom planes using a function like:

ClearAll[projectToWalls]
projectToWalls =  Module[{pr = PlotRange[#]}, 
    Normal[#] /. Line[x_, ___] :> 
       {Line[x], Line /@ (x /. 
         {{{a_, b_, c_} :> {pr[[1, 1]], b, c}}, 
          {{a_, b_, c_} :> {a, pr[[2, 2]], c}}, 
          {{a_, b_, c_} :> {a, b, pr[[3, 1]]}}})}] &;

Examples:

pp1 = ParametricPlot3D[{{4 + (3 + Cos[v]) Sin[u], 
        4 + (3 + Cos[v]) Cos[u], 4 + Sin[v]}, {8 + (3 + Cos[v]) Cos[u], 
        3 + Sin[v], 4 + (3 + Cos[v]) Sin[u]}}, {u, 0, 2 Pi}, {v, 0, 2 Pi},
    PlotStyle -> {Red, Green}];

projectToWalls @ pp1

enter image description here

projectToWalls @
 Graphics3D[{White, MeshPrimitives[Tetrahedron[], 1], 
   MeshPrimitives[Cuboid[{0, 1/2, 0}], 1]}, 
  PlotRange -> {{-1, 2}, {-1, 2}, {-1, 2}}, Background -> Black]

enter image description here

Update: Taking Roman's idea a step further using Textured polygons:

SeedRandom[1234];
P = Graphics3D[{Hue@RandomReal[], #} & /@ Cuboid @@@ RandomReal[{0, 1}, {10, 2, 3}]];
pr = PlotRange[P];
rect = {#, {#2[[1]], #[[-1]]}, #2, {#[[1]], #2[[-1]]}} & @@ Transpose[pr[[{##}]]] &;
texturedPoly = {Texture[Rasterize[#, Background -> None]], 
    Polygon[#2, VertexTextureCoordinates -> {{0, 0}, {1, 0}, {1, 1}, {0, 1}}]} &;
{left, back, bottom} = Show[P, ViewPoint -> #, Boxed -> False, Axes -> False, 
    Lighting -> "Neutral"] & /@ {Right, Front, Top}; 
leftWall = Prepend[#, pr[[1, 1]] - 1] & /@ rect[2, 3];
backWall = Insert[#, pr[[2, 1]] + 2, 2] & /@ rect[1, 3];
bottomWall = Append[#, pr[[3, 1]] - 1] & /@ rect[1, 2];

Graphics3D[{Opacity[.2], P[[1]], EdgeForm[None], Opacity[1], 
  MapThread[texturedPoly, {{left, back, bottom}, {leftWall, backWall, bottomWall}}]}, 
  BoxRatios -> 1, PlotRange -> {{-1, 1.5}, {-.5, 2.1}, {-1, 1.5}}]

enter image description here

$\endgroup$
3
  • $\begingroup$ projectToWalls no longer seems to work on Version 12. Suggestions? Thanks. $\endgroup$
    – bbgodfrey
    Dec 6, 2019 at 13:21
  • 1
    $\begingroup$ @bbgodfrey, thank you for bringing this issue to my attention. I updated the post with a fix that works in v12.0 (Wolfram Cloud). $\endgroup$
    – kglr
    Dec 6, 2019 at 13:42
  • $\begingroup$ It certainly does. Many thanks. $\endgroup$
    – bbgodfrey
    Dec 6, 2019 at 14:49
15
$\begingroup$

If you only need the 2D projection images, you can just project the 3D image from the six cardinal directions:

SeedRandom[1234];
P = Graphics3D[{RandomColor[], #} & /@ Cuboid @@@ RandomReal[{0, 1}, {10, 2, 3}]]

enter image description here

Show[P, ViewPoint -> #] & /@ {{∞,0,0}, {-∞,0,0}, {0,∞,0}, {0,-∞,0}, {0,0,∞}, {0,0,-∞}}

enter image description here

Working with the ViewVertical option might also help.

$\endgroup$

Your Answer

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

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