2
$\begingroup$

I have seen the documentation for Translate (https://reference.wolfram.com/language/ref/Translate.html), which allows one to translate a graphics primitive (like Circle, Cone, etc.) and then apply Graphics[] or Graphics3D[] to it. E.g.-

Graphics[Translate[..., {1, 0}]]

Q: But what I want to know is whether one can translate (or rotate) an existing Graphics object, something like:

Translate[Graphics[...], {1, 0}]

In particular, I have the Graphics3D output of a ParametricPlot3D[] call that I want to translate in space. I don't want to go into the definition of the ParametricPlot3D[] and translate the individual quantities inside. That is cumbersome, and might even lead to errors.

I hope someone can help.

$\endgroup$
1
  • 2
    $\begingroup$ try MapAt[Translate[#, {1, 0}] &, {1}]@Graphics[...]? $\endgroup$
    – kglr
    Commented Feb 12, 2021 at 5:20

2 Answers 2

6
$\begingroup$

One way like this.

g = ParametricPlot3D[{x*y, x, y + x}, {x, -1, 1}, {y, -1, 1}];
Show[g, Graphics3D[
  GeometricTransformation[g[[1]], 
   RotationTransform[Pi/3, {1, 0, 0}]]]]
$\endgroup$
2
  • 1
    $\begingroup$ Thank you very much. Could you please tell me why exactly you use g[[1]] instead of using g itself? I didn't even know that a Graphics object like g was indexed. $\endgroup$
    – ap21
    Commented Feb 12, 2021 at 23:28
  • $\begingroup$ @ap21 we can use g[[1]]//FullForm and g[[2]]//FullForm to see the structure of g, especially the structure of GraphicsComplex. $\endgroup$
    – cvgmt
    Commented Feb 13, 2021 at 1:03
1
$\begingroup$

Here's another approach, which I prefer when I chain multiple transforms to a Graphics object.

It's along the lines of @kglr's comment, but use a convenience functor that operates on the 1st part of a Graphics-headed expression (or, more generally, an expression with any head as long as it contains part $1$, i.e. not of the form f[]):

m = OperatorApplied[MapAt, {2, 3, 1}][1]; (* MMA 12.1+, or *)
m = Curry[MapAt, {2, 3, 1}][1];           (* MMA 11+ *)

g =OperatorApplied[MapAt, {2, 3, 1}] is an applicative that permutes arguments of MapAf[f, expr, n] into g[n, f, expr]. The argument order permutation {2,3,1} isn't very intuitive to read. It means that the 2nd argument of g will be passed to MapAt as its 1st argument, because $2$ is at the position $1$ in the list; g's 3rd argument will be the 2nd to MapAt; and, finally, g's 1st argument will be the MapAt's 3rd, the last. This 1st argument of g is then curried to literal $1$ by the partial application syntax g[1], completing the definition of m. Either m[f, expr] or m[f][expr] is then rewritten by MMA into MapAf[f, expr, 1]. This captures the essential idea of this wrapper:

In[...]=  m[transform][graphics["directives", "options", "..."]]
Out[...]= graphics[transform["directives"], "options", "..."]

Then I use the m in a chain of postfix transforms like this:

Graphics[GraphicsComplex[{{-1, 0}, {0, 2}, {1, 0}},
                         {Thick, Blue, Line[{1, 2}], 
                                 Orange, Line[{2, 3}],
                                 Magenta, Line[{3, 1}]}],
     ImageSize -> Small, Axes -> True
  ] (* // Normal *)(* -- if you want to dismantle the GraphicsComplex. *)
% // m[Scale[#, {1, -2}] &] //
     m[Rotate[#, Pi/6] &] // 
     m[{#, Translate[#, {1, 0}]} &]
% // Options (* The options are preserved: m[] is applied to directives only. *)
m = .
$\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.