# How to track rotated coordinates in tikz

I am trying to draw a cannon with a superposition of a triangle, circle and rectangle. I need it rotated, so I realized that when I draw a rotated shape, it doesn't read the old coordinate system, but a new rotated one instead.

I thought that a simple math would keep track on the desired coordinate. So I defined \rotx and \roty functions to help in the transformations. When I do \rot{0}, everything is fine. But when I do \rot{30} or any other angle, the shape assumes undesired form.

My question is: how to handle rotated coordinates in Tikz?

My code as example:

\begin{tikzpicture}
%-> USEFUL DEFINITIONS
\def\fs{0.1} %... fence width and height
\def\th{2} %... tower height
\def\wh{1} %... wall height
\def\cp{4.5} %... canon position
%-> x-rotation (#1=x, #2=y, $3=angle)$
\def\rotx#1#2#3{#1*cos(#3)+#2*sin(#3)}
\def\roty#1#2#3{-#1*sin(#3)+#2*cos(#3)}
\def\rot{30}

%----------> END DEFINITIONS <----------%

%-> DRAW THE FLOOR
\fill[gray!50]
(-5,-\fs) rectangle(2,0)
;

%-> DRAW THE CANNON
\fill[gray!50]
(-\cp-\cr,0)--
(-\cp+\cr,0)--
(-\cp,\cr)--cycle
(-\cp-\cr/2,3*\cr/2) circle(\cr)
;
\fill[gray!50,rotate=\rot]
({\rotx{-4.5}{0.2}{\rot}},{\roty{-4.5}{0.2}{\rot}})
rectangle({\rotx{-4}{0.6}{\rot}},{\roty{-4}{0.6}{\rot}})
%    ({\rotx{-\cp}{3*\cr/2}{0}},
%        {\roty{-\cp}{3*\cr/2}{0}})
%            rectangle({\rotx{-\cp+3*\cr}{5*\cr/2}{0}},
%                {\roty{-\cp+3*\cr}{5*\cr/2}{0}})
;

%-> DRAW THE CASTLE
\fill[gray!50]
%... tower
(0,0) rectangle(5*\fs,\th)
;
\foreach \x in {0,0.2,...,0.4}
\fill[gray!50]
(\x,\th) rectangle(\x+\fs,\th+\fs)
;
%... wall
\fill[gray!50]
(5*\fs,0) rectangle(20*\fs,\wh)
;
\foreach \x in {0.6,0.8,...,1.8}
\fill[gray!50]
(\x,\wh) rectangle(\x+\fs,\wh+\fs)
;
\end{tikzpicture}
• I guess you only need transform shape and nest the transformations in scopes (or, if you are confident enough, add them successively).
– user121799
Oct 16, 2018 at 0:00
• Hi, @marmot. Thank you for the response. But I still have no idea on how to do this. Oct 16, 2018 at 0:05
• My problem is that I do not precisely what the problem is. As far as I can see, \rotx and \roty are just coordinates of a given angle at an elliptic arc. This can be done much easier. Could you perhaps try to explain more precisely what you want? (And sorry, I will decouple soon but get back in 2h.) BTW, nice castle, +1 for that. ;-)
– user121799
Oct 16, 2018 at 0:08
• @marmot, I want to rotate the cannon as if it were firing into the castle. I find easy to draw it in the horizontal or vertical, but not at any other angle because coordinates change with rotation. Oct 16, 2018 at 0:17
• @marmot in other way, I would like to draw a rotated shape (in this case the rectangle) at a desired position (at the cannon) and with desired width/height. The problem I face here is that I only know how to rotate the shape [argument of ´\fill´] before entering the coordinates, which causes the coordinates I previously knew become unknown. Oct 16, 2018 at 0:28

I probably miss something basic but how about just drawing a line of a certain width from the center of the cannon circle in a given direction? And I would use a pic for that, which prevents you from adding the horizontal position to all coordinates.

\documentclass[tikz,border=3.14mm]{standalone}
\begin{document}
\begin{tikzpicture}
%-> USEFUL DEFINITIONS
\def\fs{0.1} %... fence width and height
\def\th{2} %... tower height
\def\wh{1} %... wall height
\def\cp{4.5} %... canon position
%-> x-rotation (#1=x, #2=y, $3=angle)$
\tikzset{pics/cannon/.style={code={
\fill[gray!50]
(-\cr,0)--
(+\cr,0)--
(0,\cr)--cycle
(-\cr/2,3*\cr/2) circle(\cr)
;
\draw[gray!50,line width=1mm](-\cr/2,3*\cr/2) -- ++(#1:1);
}}}

%----------> END DEFINITIONS <----------%

%-> DRAW THE FLOOR
\fill[gray!50]
(-5,-\fs) rectangle(2,0)
;

\pic at (-\cp,0) {cannon=30};

%-> DRAW THE CASTLE
\fill[gray!50]
%... tower
(0,0) rectangle(5*\fs,\th)
;
\foreach \x in {0,0.2,...,0.4}
\fill[gray!50]
(\x,\th) rectangle(\x+\fs,\th+\fs)
;
%... wall
\fill[gray!50]
(5*\fs,0) rectangle(20*\fs,\wh)
;
\foreach \x in {0.6,0.8,...,1.8}
\fill[gray!50]
(\x,\wh) rectangle(\x+\fs,\wh+\fs)
;
\end{tikzpicture}
\end{document}

• Wow! A really great and simpler idea! I will try it and see how it works. Then I can check your answer as the solution to this problem! Thank you! Oct 16, 2018 at 13:45
• Ah! Could you please explain the role of \tikzset? I am just starting to tikz, so I still don't know a looot of things. Thank you again! Oct 16, 2018 at 13:48
• @Brasil \tikzset is a shortcut for a pgfkeys command. What it does is to allow you to define a style or code. In this example, it is used to define the pic. You can define the style of nodes in a similar fashion etc.
– user121799
Oct 16, 2018 at 13:59

I present here a work around of the problem. As the drawing is the aim, it can be considered as a solution. Instead of trying to get the rotated coordinates of the rectangle, I simply used closed paths generating the desired rectangle of the canon.

I even used the very same idea to rotate the starburst and the velocity vector.

\begin{tikzpicture}
%-> USEFUL DEFINITIONS
\def\fs{0.1} %... fence width and height
\def\th{2} %... tower height
\def\wh{1} %... wall height
\def\cp{4.5} %... canon position
\def\cl{0.3} %... canon length
\def\rot{45}

%----------> END DEFINITIONS <----------%

%-> DRAW THE FLOOR
\fill[gray!50]
(-5,-\fs) rectangle(2,0)
;

%-> DRAW THE CANNON
\fill[gray!50]
(-\cp-\cr,0)--
(-\cp+\cr,0)--
(-\cp,\cr)--cycle
(-\cp-\cr/2,3*\cr/2) circle(\cr)
;
\fill[gray!50]
(-\cp-\cr/2,3*\cr/2)--++
({\rot-90}:\cr)--++
(\rot:\cl)--++
({\rot+90}:2*\cr)--++
({\rot+180}:\cl)--cycle
;

\begin{scope}
\clip
({-\cp-\cr/2+\cl*cos(\rot)},{3*\cr/2+\cl*sin(\rot)})--++
({\rot-90}:5*\cr)--++
(\rot:5*\cr)--++
({\rot+90}:11*\cr)--++
({\rot+180}:5*\cr)--cycle
;
\node[starburst, draw, minimum width=\cr mm, minimum height=\cr mm, white, fill=gray!50] at ({-\cp-\cr/2+\cl*cos(\rot)},{3*\cr/2+\cl*sin(\rot)}) {};
\end{scope}

%... the vectors
\draw[->, very thick, gray!50]
({-\cp-\cr/2+\cl*cos(\rot)},{3*\cr/2+\cl*sin(\rot)})--
({-\cp-\cr/2+3*\cl*cos(\rot)},{3*\cr/2+3*\cl*sin(\rot)})
node[above left]{$v_0$}
;
\draw[<->, gray!50]
(-0.2,0)--
(-0.2,\th) node[midway, fill=white]{$h$}
;
\draw[<->, gray!50]
(-\cp,-0.4)--
(0,-0.4) node[midway, fill=white]{$d$}
;

%-> DRAW THE CASTLE
\fill[gray!50]
%... tower
(0,0) rectangle(5*\fs,\th)
;
\foreach \x in {0,0.2,...,0.4}
\fill[gray!50]
(\x,\th) rectangle(\x+\fs,\th+\fs)
;
%... wall
\fill[gray!50]
(5*\fs,0) rectangle(20*\fs,\wh)
;
\foreach \x in {0.6,0.8,...,1.8}
\fill[gray!50]
(\x,\wh) rectangle(\x+\fs,\wh+\fs)
;

%-> DRAW THE BRICKS
\foreach \y in {0,0.2,...,\th}
\foreach \x in {0,0.2,...,2}
\draw[white]
(\x,\y) rectangle(\x+2*\fs,\y+\fs)
;
\foreach \y in {0.1,0.3,...,\th}
\foreach \x in {0.1,0.3,...,2}
\draw[white]
(\x,\y) rectangle(\x+2*\fs,\y+\fs)
;
\end{tikzpicture}