Summary
There are several things going on here:
- The
a and b in the expression are fixed parameters and don't substitute for your inputs. Try a pure function or a standard function using SetDelayed as shown below.
- What you are trying to create is not an
AffineTransformation.
- It's not immediately obvious how to pass the coordinates back into the transformation function (to this economist, it's not even clear if this works geometrically).
Part of the answer (item 1) lies in the difference between a function and a TransformationFunction. What you want is to substitute a and b for whatever values you pass it. Try this instead:
ttt[{a_, b_}] :=
AffineTransform[{d*IdentityMatrix[2], {a, b}}][{a, b}]
ttt[{x, y}]
(* {x + d x, y + d y} *)
What's going on here? Looking at the output of your original tt function, reveals a TransformationFunction, which defines a function much like a pure function that can then be applied to some data.
tt
(*TransformationFunction[{{d, 0, a}, {0, d, b}, {0, 0, 1}}]*)
TransformationFunction[{{d, 0, a}, {0, d, b}, {0, 0, 1}}][{p,q}]
(* {a + d p, b + d q} *)
But the a and b are fixed parameters, not variables that are substituted by the data passed to the function. That's why you need to do it as per the ttt function above, using SetDelayed (:=).
An alternative way to do what you want would be to define your function as a pure function. Notice the ampersand and the Slot (#) notation.
ttpure = AffineTransform[{d*IdentityMatrix[2], {#1, #2}}][{#1, #2}] &
But watch out, the syntax of the expected input is a bit different now - it expects two arguments, not inside curly braces (List expression):
ttpure[x, y]
(* {x + d x, y + d y} *)
If you have a pair of variables inside a list, then you need to use Apply (@@).
ttpure @@ {x, y}
(* {x + d x, y + d y} *)
Alternatively, you can restore the behaviour of ttt in taking a two-element list as the input by having a single Slot argument and accessing its Parts like this:
ttp2 = AffineTransform[{d*
IdentityMatrix[2], {#[[1]], #[[2]]}}][{#[[1]], #[[2]]}] &
Personally I find the #[[]] notation to be quite ugly, but it works as required as long as you actually pass an argument that is a list with at least two elements:
ttp2[{x, y}]
(* {x + d x, y + d y} *)
ttp2[{x}]
Part::partw: Part 2 of {x} does not exist. >>
Part::partw: Part 2 of {x} does not exist. >>
(* {x + d x, {x}[[2]] + d {x}[[2]]} *)
ttp2[{x, y, z}]
(* {x + d x, y + d y} *)
Edit in response to comment
To actually make this work on a graphic, you need everything to be numeric. Notice I've added a third argument (#3) here.
ttpure = AffineTransform[{#3*IdentityMatrix[2], {#1, #2}}][{#1, #2}] &
Framed@Graphics[GeometricTransformation[Rectangle[],
ttpure[0.3, 0.6, 0.2]], PlotRange -> 1]

However, this isn't quite what you want, since the actual coordinates aren't passed into the TransformationFunction, only the parameters you pass. (This will have to wait for a later update.)