# tikz-3dplot accumulates the transformation every time let operator is used

In follow up to my previous question, I now have the following problem with the tikz-3dplot library. Every time I use the "let" operator, the transformation matrix seems to act again on the coordinate frame, while computing \x1,\y1:

Edited code

\documentclass[convert,border=.3cm]{standalone}
\usepackage{tikz}
\usepackage{tikz-3dplot}
\usetikzlibrary{positioning,calc}

\begin{document}
\tdplotsetmaincoords{0}{10}
\begin{tikzpicture}[tdplot_main_coords]
\foreach\x in {0,1,2}
\draw[gray,thin] (\x,-.3,0) -- ++(0,2.6,0);
\foreach\y in {0,1,2}
\draw[gray,thin] (-.3,\y,0) -- ++(2.6,0,0);

\coordinate (A) at (1,1);
\draw (0,0,0)--(1,1);
\path let \p1=(A) in coordinate (B) at (\x1*1pt/1cm,\y1*1pt/1cm,0);
\draw[red] (0,0,0)--(B);
\path let \p1=(A) in coordinate (C) at (\x1,\y1);
\draw[green] (2,0,0)--(C);

\foreach\x in {0,1,2}
\draw[gray,thin] (\x,-.3,0) -- ++(0,2.6,0);
\foreach\y in {0,1,2}
\draw[gray,thin] (-.3,\y,0) -- ++(2.6,0,0);
\end{tikzpicture}
\end{document} In the example above \tdplotsetmaincoords{0}{10} should (and does) just turn 10 degrees the coordinate frame around the z-axis (originally perpendicular to the screen)

This accumulation does not seem to affect any other element in the tikzpicture, except for the coordinates involved in "let". One can see this because the two "test grids" at the begining and the end are completely aligned.

Notice, that the same effect happens also when I just experiment with the first input of \tdplotsetmaincoords (rotation around x-axis), or with both.

• You are computing the projections of the coordinates, which are not to be confused with the actual coordinates.
– user121799
Feb 10, 2019 at 4:17
• What if you try at (\x1*1pt/1cm,\y1*1pt/1cm) without the third coordinate ,0? Feb 10, 2019 at 4:17
• I edited the code above to answer @Symbol1's question. Feb 10, 2019 at 4:51
• @Symbol1 calc works in what is in tikz-3dplot terminology called screen coordinates and the coordinates to define the point are the main coordinates.
– user121799
Feb 10, 2019 at 6:19
• @marmot I have never found calc necessary and I do not know its logic. But usually when you specify units in a coordinate (for instance (3pt, 4cm)) then it is interpreted as real world lengths. I thought that is the chance. Feb 10, 2019 at 17:03

In your code, you compute the projections of the 3d coordinates on the screen. That is, the calc syntax returns the x and y components 2-dimensional screen coordinates, which are not to be confused with the components of the 3d or main coordinates, i.e. those defined by calling \tdplotsetmaincoords{...}{...}. You take these projections of the 3d coordinates to form new x and y components of new 3d coordinates.

To illustrate this, consider

\documentclass[convert,border=.3cm]{standalone}
\usepackage{tikz}
\usepackage{tikz-3dplot}
\usetikzlibrary{positioning,calc}

\begin{document}
\tdplotsetmaincoords{0}{10}
\begin{tikzpicture}[tdplot_main_coords]
\coordinate (A) at (1,1);
\path let \p1=(A),\n1={\x1*1pt/1cm},\n2={\y1*1pt/1cm} in (\n1,\n2,0) coordinate
(B);
\coordinate (C) at (1,1,0);
\begin{scope}[tdplot_screen_coords]
\coordinate (D) at (1,1);
\coordinate (E) at (1.16,0.81);
\end{scope}
\draw let \p1=(A),\n1={\x1*1pt/1cm},\n2={\y1*1pt/1cm} in (0,0,0)--
node[pos=0.95,above left,sloped] {\pgfmathsetmacro{\myx}{\n1}
\pgfmathsetmacro{\myy}{\n2}$A=(\pgfmathprintnumber{\myx},\pgfmathprintnumber{\myy})$}(A);
\draw[red] let \p1=(B),\n1={\x1*1pt/1cm},\n2={\y1*1pt/1cm} in
(0,0,0)-- node[pos=0.95,below left,sloped] {\pgfmathsetmacro{\myx}{\n1}
\pgfmathsetmacro{\myy}{\n2}$B=(\pgfmathprintnumber{\myx},\pgfmathprintnumber{\myy})$}(B);
\draw[blue] let \p1=(C),\n1={\x1*1pt/1cm},\n2={\y1*1pt/1cm} in (2,0,0)
-- node[pos=0.95,above right,sloped] {\pgfmathsetmacro{\myx}{\n1}
\pgfmathsetmacro{\myy}{\n2}$C=(\pgfmathprintnumber{\myx},\pgfmathprintnumber{\myy})$}(C);
\draw[green] let \p1=(D),\n1={\x1*1pt/1cm},\n2={\y1*1pt/1cm} in (2,2,0)
-- node[midway,above,sloped] {\pgfmathsetmacro{\myx}{\n1}
\pgfmathsetmacro{\myy}{\n2}$D=(\pgfmathprintnumber{\myx},\pgfmathprintnumber{\myy})$}(D);
\draw[orange] let \p1=(E),\n1={\x1*1pt/1cm},\n2={\y1*1pt/1cm} in (-2,2,0)
-- node[midway,above,sloped] {\pgfmathsetmacro{\myx}{\n1}
\pgfmathsetmacro{\myy}{\n2}$E=(\pgfmathprintnumber{\myx},\pgfmathprintnumber{\myy})$}(E);
\foreach\x in {0,1,2}
\draw[gray,thin] (\x,-.3,0) -- ++(0,2.6,0);
\foreach\y in {0,1,2}
\draw[gray,thin] (-.3,\y,0) -- ++(2.6,0,0);
\end{tikzpicture}
\end{document} Here,

1. A is defined to sit at (1,1) in the main coordinates. They correspond to (1.16,0.81) in the screen coordinates.
2. Now (1.16,0.81) is used to define B, where the coordinates have their meaning in the main coordinates. So you are telling TikZ to place B at (1.16,0.81,0) in the main coordinates.
3. C is defined at (1,1,0) in the main coordinates. It coincides with A.
4. D is defined to sit at (1,1) in the screen coordinates. It does not coincide with any of the points before, but the angles DOA and AOB coincide. This is the difference between active and passive transformations.
5. E is defined to sit at (1.16,0.81) in the screen coordinates, and thus coincides with A and C.

Overall, the point is that there are two coordinate systems. The main coordinates system which is used to define the points and which originates from an orthographic projection of 3d coordinates. And then there are the screen coordinates, which are those in which calc works.

Actually, there is one more thing to consider in your MWE.

\documentclass[convert,border=.3cm]{standalone}
\usepackage{tikz}
\usepackage{tikz-3dplot}
\usetikzlibrary{positioning,calc}

\begin{document}
\tdplotsetmaincoords{0}{10}
\begin{tikzpicture}[tdplot_main_coords]
\foreach\x in {0,1,2}
\draw[gray,thin] (\x,-.3,0) -- ++(0,2.6,0);
\foreach\y in {0,1,2}
\draw[gray,thin] (-.3,\y,0) -- ++(2.6,0,0);

\coordinate (A) at (1,1);
\draw (0,0,0)--(1,1);
\path let \p1=(A) in coordinate (B) at (\x1*1pt/1cm,\y1*1pt/1cm,0);
\draw[red] (0,0,0)--(B);
\path let \p1=(A) in coordinate (C) at (\x1,\y1);
\draw[green] (2,0,0)--(C);

\foreach\x in {0,1,2}
\draw[gray,thin] (\x,-.3,0) -- ++(0,2.6,0);
\foreach\y in {0,1,2}
\draw[gray,thin] (-.3,\y,0) -- ++(2.6,0,0);
\end{tikzpicture}
\end{document}


When you define C, you define it with two components both of which have units. TikZ takes these to be screen coordinates again. Why? Because these are just some dimensionful coordinates and this is how the parser treats it. On the other hand, and yes, this is really confusing, if TikZ sees a dimensionful 3d coordinate, it will strip of the dimensions and takes the resulting coordinates to be in the main coordinate system. Yes, this is truly confusing. This behavior is indeed a bit odd. Here is an attempt to summarize it.

\documentclass{article}
\usepackage{array}
\begin{document}
\begin{tabular}{|r|>{\centering\arraybackslash}p{5cm}|>{\centering\arraybackslash}p{5cm}|}
\hline
& dimensionful & dimensionless \\
\hline
2D & screen & main \\
3D & convert dimension to points, strip units off, and interpret the result in
main coordinate system &  main\\
\hline
\end{tabular}
\end{document} The maintainers of TikZ are actually aware of this, see this commit, which deals with the fact that a projection is a projection and implies loss of information.

See here for a way to store the 3d coordinates in pgfkeys.

• Yes. The points (1,1,0) and (1,1) coincide, but when I let \p1=(1,1) and define (B) to be (\x1,\y1,0), the output (red) des not agree with the previous two. Feb 10, 2019 at 4:58
• @D.Bogiokas I think it is still the same effect. You compute B from the projected coordinates. Since you installed 3d coordinates, A is not at (1cm,1cm) in the screen coordinates. tikz-3dplot has a special coordinate system for that: tdplot_screen_coords, if you were to use these to define A, you would not have the effect.
– user121799
Feb 10, 2019 at 5:19
• But since C is also defined using \x1 and \y1, shouldn't this affect C as well? Feb 10, 2019 at 5:32
• @D.Bogiokas You are absolutely right, this is very confusing. TikZ treats coordinates whose coordinates have dimensions (pt or cm) differently depending on whether these have two or three entries. If there are two components, these will be absolute or screen coordinates, if there are three of them, it will strip off the dimensions and consider them 3d coordinates.
– user121799
Feb 10, 2019 at 6:33
• Thank you again. The difference between the two coordinate frames is now crystal-clear and the last edit regarding the 2d and 3d case resolved my final confusion. P.S. I also think that working in the right tdplot_coords scope is going to also give me a good work-around. Feb 10, 2019 at 6:38