# How to modify the elements of a list in a loop?

I have a list with points coordinates. And I'm trying to traverse it and perform some matrix operations on each point. But I have a problem with storing modified points in the initial list instead of the original points.

Here is the complete entry point example:

(* the matrix of the linear operator of rotation around OX axis *)
rx = {
{1, 0, 0, 0},
{0, Cos[ax], -Sin[ax], 0},
{0, Sin[ax], Cos[ax], 0},
{0, 0, 0, 1}
};

(* translation matrices *)
t1 = {
{1, 0, 0, -j},
{0, 1, 0, -k},
{0, 0, 1, -l},
{0, 0, 0, 1}
};
t2 = {
{1, 0, 0, j},
{0, 1, 0, k},
{0, 0, 1, l},
{0, 0, 0, 1}
};

(* projection onto OXY plane *)
f = {
{1, 0, 0, 0},
{0, 1, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 1}
};

points = {
{{100},{0},{0},{1}},
{{155},{0},{0},{1}}
};

ax = Pi/4;
j = 100;
k = 100;
l = 0;


And this is my solution to it, which I try to improve

For[i1 = 1, i1 < 3, i1++, {
item = t1 . Part[points, i1];
item = rx . item;
item = t2 .item;
item = f . item;
xP = N[Part[item, 1]];
yP = N[Part[item, 2]];
zP = N[Part[item, 3]];
homogP = N[Part[item, 4]];
Print[{xP, yP, zP, homogP}];
}];


the output is:

{{100.},{29.2893},{0.},{1.}}

{{155.},{29.2893},{0.},{1.}}


And this seems to be correct.

But if I change the For loop with the solution inspired by Alexei Boulbich

Map[{t1.#, rx.#, t2.#, f.#, N[#]} &, points];
Print[points];


I get this:

{{{100},{0},{0},{1}},{{155},{0},{0},{1}}}


That is the original list without any operations applied.

-
Please give an example of the input and output that you expect. –  Mr.Wizard Aug 16 at 21:13
@Mr.Wizard I reworded the question –  user5693 Aug 18 at 16:02
Alexei Boulbich's code is just Map[{t1.#, rx.#, t2.#, f.#, N[#]} &, points] -- no semicolon, no Print. –  Michael E2 Aug 18 at 16:11
@MichaelE2 if I remove f#, N[#], semicolon and print in order to use the exact version of Alexei's answer, it still does not give the correct result. –  user5693 Aug 18 at 16:27
@user5693 Why doesn't your update state that, then? Print[points]; will print the original list because the list points is not modified (by either Alexei's code or yours). (Yeah, I forgot to remove the f.# etc. Oops.) –  Michael E2 Aug 18 at 16:59

From your updated example this does what you desire:

N[f.t2.rx.t1.#] & /@ points

{
{{100.}, {29.2893}, {0.}, {1.}},
{{155.}, {29.2893}, {0.}, {1.}}
}


You can eliminate some redundancy by precomputing the fixed part of that operation:

m = f.t2.rx.t1;

N[m.#] & /@ points

{
{{100.}, {29.2893}, {0.}, {1.}},
{{155.}, {29.2893}, {0.}, {1.}}
}

-

Try this:

Map[{t1.#, rx.#, t2.#} &, points]


or like this:

Map[{t1, rx, t2}.# &, points]


which is the same.

For example, if

points = {{a1, a2, a3}, {b1, b2, b3}};


and

 t1 = {x, 0, 0};
rx = {0, y, 0};
t2 = {0, 0, z};


the operation yields:

    Map[{t1.#, rx.#, t2.#} &, points]
(*   {{a1 x, a2 y, a3 z}, {b1 x, b2 y, b3 z}}    *)


as one should expect.

-
it yields some strange result. The result consists of a list with inner list which contains 36 lists, which I can assume are the results of each matrix apply, that is 12 points of the first matrix product,12 of the second one and 12 of the last. Am I correct? –  user5693 Aug 16 at 19:32
I think the OP wants to apply each transformation in turn to each point, i.e. points.Transpose[t2.rx.t1]. It's hard to tell though, when the only thing we have to go on is some code which does something else entirely. –  Simon Woods Aug 17 at 15:02
@user5693 Well, what I did is essentially the same you have written in your example, but yielding the output. The possible source of misunderstanding is (as it has been mentioned by Mr. Wizard) that you gave no examples of your data, parameters and expected output. In particular, I assumed rx, t1 and t2 to be vectors. Are they not? Then your result will, of course, differ from expected one. –  Alexei Boulbitch Aug 18 at 7:50
@AlexeiBoulbitch, I've just expanded the question –  user5693 Aug 18 at 15:48