One way to do this is to covert the 2D graphics primitives to an equivalent 3D primitive using a set of rules.
It's not so simple as tacking on the z-coordinate to every list of two numbers. Sometimes your list of two numbers might not be a 2D point. So these rules must specifically target the bits which we know are coordinates. As a start we can transform Line
and Text
:
linerule[z_] := Line[points_, stuff___] :> Line[#~Append~z & /@ points, stuff];
textrule[z_] := {
Text[t_, {x_, y_}, stuff___] :> Text[t, {x, y, z}, stuff],
Text[t_, stuff___] :> Text[t, {0, 0, z}, stuff] (* default coords *)
};
Some primitives like Circle
don't have a direct 3D analogue, so we have to do a bit more work:
circle3d[{x_, y_}, r_, z_] := BSplineCurve[
{{r, 0, z}, {r, r, z}, {-r, r, z}, {-r, 0, z}, {-r, -r, z}, {r, -r,
z}, {r, 0, z}},
SplineKnots -> {0, 0, 0, 1/4, 1/2, 1/2, 3/4, 1, 1, 1},
SplineWeights -> {1, 1/2, 1/2, 1, 1/2, 1/2, 1},
SplineDegree -> 2];
circlerule[z_] := {
Circle[{x_, y_}, r_?NumberQ, stuff___] :> circle3d[{x, y}, r, z],
Circle[{x_, y_}, stuff___] :> circle3d[{x, y}, 1, z], (* default radius *)
Circle[stuff___] :> circle3d[{0, 0}, 1, z] (* default coords and radius *)
}
This spline construction is just from the help on BSplineCurve
. It only works for a full circle, not arcs. For a full treatment of circles in space see (10957).
Further rules for Point
, GraphicsComplex
, Polygon
, etc., are left as an exercise to the reader.
Now we can put it together to make our 3D graphic. FullGraphics
is used to get Mathematica to provide the 2D primitives.
allrules[z_] := Flatten@Through[{linerule, textrule, circlerule}[z]];
Graphics3D[Table[First@FullGraphics@g@z /. allrules[z], {z, 2, 5}], BoxRatios -> {1,1,2}]
(This Q&A brought to you by the moderators' tireless efforts in cleaning up old and dead questions).