# Projected coordinate in TikZ is not properly placed

I'm trying to draw an airplane. When I was drawing the window for the cockpit, I was using projected points to get right angles. But things aren't working out as expected. Could anyone give me a pointer about what I'm doing incorrectly?

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\pagestyle{empty}
\begin{document}

\def\aeBodyNoseDistance{0.21cm}
\begin{tikzpicture}[x=5cm,y=5cm,scale=3,every node={transform shape}]

\coordinate (TAIL) at (0,0);
\coordinate (NOSE) at ($(TAIL)+(30:1)$);

\coordinate (MID)     at ($(TAIL)!0.75!(NOSE)$);

\coordinate (MID/TOP) at ($(MID)!\aeBodyRadius!90:(NOSE)$);
\coordinate (MID/BOT) at ($(MID)!\aeBodyRadius!-90:(NOSE)$);

\coordinate (NOSE/TIP) at ($(NOSE)!\aeBodyNoseDistance!90:(MID)$);

\coordinate (HIND/TOP) at ($(TAIL)!\aeBodyRadius!90:(NOSE)$);
\coordinate (HIND/BOT) at ($(TAIL)!\aeBodyRadius!-90:(NOSE)$);

\node[fill,circle,inner sep=1pt] at (MID/TOP) {};
\node[fill,circle,inner sep=1pt] at (MID/BOT) {};
\node[fill,circle,inner sep=1pt] at (HIND/TOP) {};
\node[fill,circle,inner sep=1pt] at (HIND/BOT) {};

\draw[rounded corners=10pt]
(HIND/TOP) --
(MID/TOP)  --
node [pos=0.25] (WINDOW/TOP/N) {}
node [pos=0.50] (WINDOW/BOT/N) {}
(NOSE/TIP) --
(MID/BOT)  --
(HIND/BOT);
\coordinate (WINDOW/TOP) at (WINDOW/TOP/N.center);
\coordinate (WINDOW/BOT) at (WINDOW/BOT/N.center);

\coordinate (WINDOW/RIG/T) at ($(TAIL)!(WINDOW/TOP)!(NOSE)$);
\coordinate (WINDOW/RIG)   at ($(WINDOW/TOP)!(WINDOW/BOT)!(WINDOW/RIG/T)$);

\draw (WINDOW/TOP) -- (WINDOW/RIG) -- (WINDOW/BOT);

\draw[red] (TAIL) -- (NOSE);

\end{tikzpicture}

\end{document}


The "red" line runs down the center of the plane clearly shows how my perpendicular is not what it should be.

UPDATE

What seems not to be working is the following snippet of code:

    \coordinate (WINDOW/RIG/T) at ($(TAIL)!(WINDOW/TOP)!(NOSE)$);
\coordinate (WINDOW/RIG)   at ($(WINDOW/TOP)!(WINDOW/BOT)!(WINDOW/RIG/T)$);


The projected points do not seem to lie on the appropriate perpendicular. In particular, (WINDOW/RIG) should lie above the red line since the line through (WINDOW/TOP) and (WINDOW/RIG/T) should be perpendicular to the red line through (TAIL) and (NOSE).

• Are you calling the concorde an airplane? What a shame :P – percusse Mar 27 '14 at 21:47
• @percusse Well actually it's suppose to be an Airbus. – A.Ellett Mar 27 '14 at 22:08
• Could you elaborate on what you think is wrong. You start with NOSE and TAIL and everything seems relative to those two points. Not sure where you expected the red line to be? – Peter Grill Mar 27 '14 at 22:42
• @PeterGrill I've added an update. I'll be away from the computer for about an hour and a half. When I get back I'll try to clean up the code a bit to make it more readable. – A.Ellett Mar 27 '14 at 22:52

As mentioned by A.Ellett, the error is caused by \pgfpointnormalised. A solution to obtain a better precision is given in this answer.

Applied on the MWE:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\pagestyle{empty}

% use the Mark Wibrow's correction
\makeatletter
\def\pgfpointnormalised#1{%
\pgf@process{#1}%
\pgfmathatantwo{\the\pgf@y}{\the\pgf@x}%
\let\pgf@tmp=\pgfmathresult%
\pgfmathcos@{\pgf@tmp}\pgf@x=\pgfmathresult pt\relax%
\pgfmathsin@{\pgf@tmp}\pgf@y=\pgfmathresult pt\relax%
}
\makeatother

\begin{document}

\def\aeBodyNoseDistance{0.21cm}
\begin{tikzpicture}[x=5cm,y=5cm,scale=3,every node={transform shape}]

\coordinate (TAIL) at (0,0);
\coordinate (NOSE) at ($(TAIL)+(30:1)$);

\coordinate (MID)     at ($(TAIL)!0.75!(NOSE)$);

\coordinate (MID/TOP) at ($(MID)!\aeBodyRadius!90:(NOSE)$);
\coordinate (MID/BOT) at ($(MID)!\aeBodyRadius!-90:(NOSE)$);

\coordinate (NOSE/TIP) at ($(NOSE)!\aeBodyNoseDistance!90:(MID)$);

\coordinate (HIND/TOP) at ($(TAIL)!\aeBodyRadius!90:(NOSE)$);
\coordinate (HIND/BOT) at ($(TAIL)!\aeBodyRadius!-90:(NOSE)$);

\node[fill,circle,inner sep=1pt] at (MID/TOP) {};
\node[fill,circle,inner sep=1pt] at (MID/BOT) {};
\node[fill,circle,inner sep=1pt] at (HIND/TOP) {};
\node[fill,circle,inner sep=1pt] at (HIND/BOT) {};

\draw[rounded corners=10pt]
(HIND/TOP) --
(MID/TOP)  --
node [pos=0.25] (WINDOW/TOP/N) {}
node [pos=0.50] (WINDOW/BOT/N) {}
(NOSE/TIP) --
(MID/BOT)  --
(HIND/BOT);
\coordinate (WINDOW/TOP) at (WINDOW/TOP/N.center);
\coordinate (WINDOW/BOT) at (WINDOW/BOT/N.center);

\coordinate (WINDOW/RIG/T) at ($(TAIL)!(WINDOW/TOP)!(NOSE)$);
\coordinate (WINDOW/RIG)   at ($(WINDOW/TOP)!(WINDOW/BOT)!(WINDOW/RIG/T)$);

\draw (WINDOW/TOP) -- (WINDOW/RIG) -- (WINDOW/BOT);

\draw[red] (TAIL) -- (NOSE);

\end{tikzpicture}

\end{document}


You probably intended to put WINDOW/RIG/T along the main axis, but this worked. (If it aint broke...)

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\pagestyle{empty}
\begin{document}
\def\aeBodyNoseDistance{0.21cm}
\begin{tikzpicture}[x=5cm,y=5cm,scale=3,every node={transform shape}]
\coordinate (TAIL) at (0,0);
\coordinate (NOSE) at ($(TAIL)+(30:1)$);
\coordinate (MID)     at ($(TAIL)!0.75!(NOSE)$);
\coordinate (MID/TOP) at ($(MID)!\aeBodyRadius!90:(NOSE)$);
\coordinate (MID/BOT) at ($(MID)!\aeBodyRadius!-90:(NOSE)$);
\coordinate (NOSE/TIP) at ($(NOSE)!\aeBodyNoseDistance!90:(MID)$);
\coordinate (HIND/TOP) at ($(TAIL)!\aeBodyRadius!90:(NOSE)$);
\coordinate (HIND/BOT) at ($(TAIL)!\aeBodyRadius!-90:(NOSE)$);
\node[fill,circle,inner sep=1pt] at (MID/TOP) {};
\node[fill,circle,inner sep=1pt] at (MID/BOT) {};
\node[fill,circle,inner sep=1pt] at (HIND/TOP) {};
\node[fill,circle,inner sep=1pt] at (HIND/BOT) {};
\draw[rounded corners=10pt]
(HIND/TOP) --
(MID/TOP)  --
node [pos=0.25] (WINDOW/TOP/N) {}
node [pos=0.50] (WINDOW/BOT/N) {}
(NOSE/TIP) --
(MID/BOT)  --
(HIND/BOT);
\coordinate (WINDOW/TOP) at (WINDOW/TOP/N.center);
\coordinate (WINDOW/BOT) at (WINDOW/BOT/N.center);

%start of modifications
\coordinate (WINDOW/RIG/T) at ($(TAIL)!(WINDOW/TOP)!90:(NOSE)$);
\coordinate (WINDOW/RIG)   at ($(WINDOW/TOP)!(WINDOW/BOT)!90:(WINDOW/RIG/T)$);
\node[fill,circle,inner sep=1pt] at (WINDOW/RIG/T) {};% way down near the tail
\draw[blue] (WINDOW/TOP) -- (WINDOW/RIG) -- (WINDOW/BOT);
%end of modifications

\draw[red] (TAIL) -- (NOSE);

\end{tikzpicture}

\end{document}

• I hadn't thought of that. +1 for now. Though I'd be interested in knowing why projection itself didn't give the correct result. – A.Ellett Mar 28 '14 at 16:00
• While this is something of a solution, it misses the point that the calc library's syntax of ($(A)!(B)!(C)$) which should project B orthogonally onto line AC is not behaving as it should. I've played with quite a bit now. I think the issue has to do with rounding error. In particular I think it has to do with how \pgfpointnormalised works. – A.Ellett May 19 '14 at 2:41
• @A.Ellett - You can also make it work if you draw it flat then rotate the image by 30 degrees, so you are probably right. – John Kormylo May 19 '14 at 15:12

To show what I meant by drawing it flat and rotating it:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\pagestyle{empty}

\newlength{\myx}
\newlength{\myy}

\begin{document}
\def\aeBodyNoseDistance{0.21cm}
\begin{tikzpicture}[x=5cm,y=5cm,scale=3,every node={transform shape},rotate=30]% changed here
\coordinate (TAIL) at (0,0);
\coordinate (NOSE) at ($(TAIL)+(1,0)$);% changed here
\coordinate (MID)     at ($(TAIL)!0.75!(NOSE)$);
\coordinate (MID/TOP) at ($(MID)!\aeBodyRadius!90:(NOSE)$);
\coordinate (MID/BOT) at ($(MID)!\aeBodyRadius!-90:(NOSE)$);
\coordinate (NOSE/TIP) at ($(NOSE)!\aeBodyNoseDistance!90:(MID)$);
\coordinate (HIND/TOP) at ($(TAIL)!\aeBodyRadius!90:(NOSE)$);
\coordinate (HIND/BOT) at ($(TAIL)!\aeBodyRadius!-90:(NOSE)$);
\node[fill,circle,inner sep=1pt] at (MID/TOP) {};
\node[fill,circle,inner sep=1pt] at (MID/BOT) {};
\node[fill,circle,inner sep=1pt] at (HIND/TOP) {};
\node[fill,circle,inner sep=1pt] at (HIND/BOT) {};
\draw[rounded corners=10pt]
(HIND/TOP) --
(MID/TOP)  --
node [pos=0.25] (WINDOW/TOP/N) {}
node [pos=0.50] (WINDOW/BOT/N) {}
(NOSE/TIP) --
(MID/BOT)  --
(HIND/BOT);
\coordinate (WINDOW/TOP) at (WINDOW/TOP/N.center);
\coordinate (WINDOW/BOT) at (WINDOW/BOT/N.center);

\node[fill,circle,inner sep=1pt] at (NOSE) {};
\node[fill,circle,inner sep=1pt] at (TAIL) {};
\coordinate (WINDOW/RIG/T) at ($(TAIL)!(WINDOW/TOP)!(NOSE)$);
\coordinate (WINDOW/RIG)   at ($(WINDOW/TOP)!(WINDOW/BOT)!(WINDOW/RIG/T)$);
\node[fill,circle,inner sep=1pt] at (WINDOW/RIG/T) {};
\draw[blue] (WINDOW/TOP) -- (WINDOW/RIG) -- (WINDOW/BOT);
\draw[red] (TAIL) -- (NOSE);

\end{tikzpicture}

\end{document}