I have a requirement to perform a series of GeometricTransformation[]s using the AfineTransform[] function. I use these to set up something similar to a kinematic chain in something similar to a mechanism.

Four geometric objects are stored in a list, say

fList={f1, f2, f3, f4}

and four affine transforms are stored in their own list, say

tList={t1, t2, t3, t4}

Right now I am performing the geometric transformations as follows

f1New=Fold[GeometricTransformation[#1,#2]&, fList[[1]], tList[[1;;1;;-1]]];
f2New=Fold[GeometricTransformation[#1,#2]&, fList[[2]], tList[[2;;1;;-1]]];
f3New=Fold[GeometricTransformation[#1,#2]&, fList[[3]], tList[[3;;1;;-1]]];
f4New=Fold[GeometricTransformation[#1,#2]&, fList[[4]], tList[[4;;1;;-1]]];

However, I would like to combine the four lines into a single line that generates a list of four new transforms and write a function to apply the transforms for lists of N graphics objects and N affine transforms.

So far I have tried to use Nest[] but that has not worked. I'm sure there is a subtle way to handle this but it eludes me. I would appreciate a hint.

Also, I am trying to stay away from using For[] or Do[] constructs because I am fascinated by Mathematica outstanding proficiency at handling lists.

Thank you and all the best!



If elements of tList are TransformationFunctions, you can use a combination of Composition and MapThread:

cList = Composition @@ Take[tList, #] & /@ Range[4];

fListNew = MapThread[GeometricTransformation] @ {fList, cList};

to get the same result.


fList = {f1, f2, f3, f4} = {Point[{2, 4}], Rectangle[{4, 3}, {5, 5}], 
   Circle[{4, 1}], Polygon[{{1, 2}, {3, 3}, {2, 1}}]};

tList = {t1, t2, t3, t4} = {ReflectionTransform[{-1, 1}], 
   ShearingTransform[Pi/4, {1, 0}, {0, 1}], 
   TranslationTransform[{2, 3}], 
   ScalingTransform[{.5, 2.}]};

 f1234New = Fold[GeometricTransformation[#1, #2] &, fList[[#]], 
     tList[[# ;; 1 ;; -1]]] & /@ Range[4];

 fListNew = MapThread[GeometricTransformation] @ 
    {fList, Composition @@ Take[tList, #] & /@ Range[4]};

Row[Framed[Graphics[{PointSize@Large, FaceForm[Opacity[.5, Red]], 
      EdgeForm[Gray], Thick, #}, ImageSize -> 200]] & /@ 
  {fList, f1234New, fListNew}, Spacer[50]]

enter image description here

  • $\begingroup$ Thank you @kglr The MapThread[] and Composition[] combo works well and it's very elegant, if I may say so myself. I assume that in your example you have meant fList={f1, f2, f3, f4} = ... and tList={t1, t2, t3, t4} = ... $\endgroup$ – user74549 Oct 12 '20 at 5:15
  • 1
    $\begingroup$ Thank you @user74549; fixed the definitions. $\endgroup$ – kglr Oct 12 '20 at 5:23

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.