Combining @garagecoder and my previous into one may be closer to your original ask: you want to twist and toss a cat. Donāt do this with a real cat; skin integrity may suffer. The game is to fill a warping image with new coordinates. A pixel in the warping image at location x,y contains the coordinates of where the pixel in the cat image at location x,y is to go in the final output image. Here, we fill the warping image with coordinates calculated from an affine transformation matrix, the transformation matrix taking the x,y pixel location as the initial position vector and producing the transformed position ā typical affine transformation matrix work. To make this example a little more interesting, the final affine transformation matrix, `fin`

is a composition of (1) a translation matrix, to bring the center of the cat image to the origin, (2) a rotation matrix, twirling the cat around the origin, and (3) a second translation matrix to throw the cat more-or-less back around the center of the image, but not quite in the same place. `expand_xy`

is handy for furnishing some working room.

`xfrmfun.gmic`

:

```
xfrmfun:
+f. "begin(
xlt0=eye(3);
xlt0[2]=w/2;
xlt0[5]=h/2;
fin=mul(rot([0,0,1],73.25Ā°),xlt0,3);
xlt1=eye(3);
xlt1[2]=-1.5*w/2;
xlt1[5]=-0.75*h/2;
fin=mul(fin,xlt1,3)
);
p=fin*[x,y,1];
[p[0,2,1],0]"
warp.. .,0,2,2
rm.
```

Thereās a bit of trickery toward the end of the math expression. In most of the transformation pipeline, we are manipulating homogeneous position vectors `[x,y,1]`

. When it comes to dropping a pixel into the warp image, we extract the `x,y`

part, leaving behind the one, then compose a new vector, a pixel with channel 2 set to zero always; that, then, drops into the warp image.

Usage:

```
gmic xfrmfun.gmic sp cat,256 expand_xy. 200,0 xfrmfun. o. 'throwncat.png'
```

Have fun!