I have a number of rotations computed by rot = RotationTransform[theta, point], and I would like to compose them to produce one function that is the composition of all the rotations. I need this function in a form that I can then use in, say, FindMinimum[].

I solved my problem by using TransformationMatrix[rot], multiplying all the matrices, and defining a function based on that. But it would be cleaner to create one function that is the composition of the others, rather than take the detour through matrices. Ideally I would input a list of `theta, point' values, and get back a function that is the composition of all those rotations.

I'd appreciate learning how to do this. Thanks!

  • 2
    $\begingroup$ Why don't you post the code for the functions your have. Then someone can suggest how to compose them. $\endgroup$ – DavidC Mar 12 '12 at 15:49
  • 2
    $\begingroup$ Why would you not want to work with the matrices directly? Seems like a straightforward way to compose the combined rotation. $\endgroup$ – Yves Klett Mar 12 '12 at 15:54
  • 1
    $\begingroup$ @David: I didn't want to bias the answers to my specific situation. The various rotations are computed in separate parts of the code, and only lashed together at the end. I would have to contrive an example to make it independent of my details. $\endgroup$ – Joseph O'Rourke Mar 12 '12 at 17:15
  • $\begingroup$ @Yves: It works perfectly by multiplying matrices. I just thought that was an inelegant solution. $\endgroup$ – Joseph O'Rourke Mar 12 '12 at 17:16
  • $\begingroup$ Ultimately, the matrices will get multiplied together, anyway. The question is whether or not you do it yourself. $\endgroup$ – rcollyer Mar 12 '12 at 17:21

The function your looking for is Composition which does exactly what you would like it to do. For instance,

{rot1, rot2} = MapThread[RotationTransform, {{theta1,theta1},{point1,point2}}]
composed = Composition @@ %
     RotationTransform[theta1, point1], 
     RotationTransform[theta1, point2]

which can then be used like rot1 and rot2 would, e.g. composed[ {x, y, z} ]. From some experiments, it seems that Composition will combine multiple TransformationFunction into a single TransformationFunction, e.g.

Composition[ RotationTransform[ Pi/2 ], RotationTransform[ Pi/2] ] ]

simplifies to

RotationTransform[ Pi ]

Here is a specific example using the following rotations

RotationTransform[Pi/2, {1, 0}]
RotationTransform[Pi/2, {1, 1}]
composed = Composition @@ {%, %%}

which gives the output (it's in picture form as the output is displayed using boxes):

enter image description here

Now, applying them one at a time to a triangle, using the following code

  {EdgeForm[Black], White, #2[#1]} &, 
   Polygon[{{1, 0}, {0, Sqrt[3]}, {-1, 0}}], 
  {# &, 
   GeometricTransformation[#, RotationTransform[Pi/2, {1, 0}]] &, 
   GeometricTransformation[#, RotationTransform[Pi/2, {1, 1}]] &}
][[2 ;;]] //
 Graphics[#, Frame -> True, PlotRange -> {{-3, 3}, {-3, 3}}] & /@ # 


enter image description here

Using the composition directly via

   EdgeForm[Black], White, 
       Polygon[{{1, 0}, {0, Sqrt[3]}, {-1, 0}}], 
  }, Frame -> True, PlotRange -> {{-3, 3}, {-3, 3}}]

gives the identical end result

enter image description here

Two things to note here. First, the functions are entered into Composition in reverse order of application, i.e. the first function to be applied is last, and the last function is first. Second, I made use of GeometricTransformation to apply the rotations to a Graphics primitive.

  • $\begingroup$ If you supply explicit values for the points like point1={u1, u2} the result is properly evaluated as well. $\endgroup$ – Yves Klett Mar 12 '12 at 16:12
  • $\begingroup$ @YvesKlett actually, yes it does. You can combine any of the specializations of TransformFunction and they will be made into a single unit. $\endgroup$ – rcollyer Mar 12 '12 at 16:14
  • $\begingroup$ Would you mind editing in an example with explicit rotation points? Should be quite instructive for future browsing. $\endgroup$ – Yves Klett Mar 12 '12 at 16:41
  • 1
    $\begingroup$ @YvesKlett added an example with graphics for visual oriented people. $\endgroup$ – rcollyer Mar 12 '12 at 17:16
  • $\begingroup$ Wonderful! This is exactly what I sought. Thanks! $\endgroup$ – Joseph O'Rourke Mar 12 '12 at 17:16

It seems you want a built-in function Composition. Having two functions f and g, where g depends on two arguments it works like this :

Composition[f, g] @@ {x, y}
f[g[x, y]]


g[x_, y_] := ArcTan[x^2 y]
f[z_]     := 1/2 Tan[z]
Composition[f, g] @@ {x, y}
(x^2 y)/2

Composition works with many functions as well, e.g. :

Composition[f1, f2, f3, f4] @@ {x, y, z}
f1[f2[f3[f4[x, y, z]]]]           
  • 2
    $\begingroup$ I wasn't aware that Composition will evaluate when transformation functions are passed to it. I think you should give an example using transformation functions to make this explicit. This is a special behaviour of Composition, specific to TransformationFunctions. $\endgroup$ – Szabolcs Mar 12 '12 at 16:06
  • 1
    $\begingroup$ Composition is also mentioned in the help under guide/GeometricTransforms. In this case it is a neat thing, but the GeometricTransformation framework can be a bit opaque IMHO. $\endgroup$ – Yves Klett Mar 12 '12 at 16:22
  • $\begingroup$ Thank you so much, two equivalent answers! $\endgroup$ – Joseph O'Rourke Mar 12 '12 at 17:17
  • $\begingroup$ @JosephO'Rourke You are welcome. $\endgroup$ – Artes Mar 12 '12 at 17:37
  • 2
    $\begingroup$ @Artes My meaning was that I was surprised and delighted to find that Compose[f,g] does indeed auto-simplify if f and g are TransformationFunctions, like rcollyer showed in his answer. I read your answer first and thought that it's less efficient than hand-multiplying the matrices and construction a new TranformationFunction from them. But I checked if Composition would actually evaluate, and surprise---it did! This only happens for TranformationFunction objects, and it is not obvious, so I asked you to include it (but it seems rcollyer did first). $\endgroup$ – Szabolcs Mar 13 '12 at 5:37

One more thing that may be useful when working with Composition: to include a transformation that does nothing, use Identity.

You may ask why you'd ever need that. An example is given in this post for a shadow projection function: How to make a drop-shadow for a Graphics3D objects?

There is a transformation in the Composition that is supposed to be left out under certain conditions. The link also illustrates how much simpler Composition is than the alternative of adding vectors and multiplying matrices.


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.