# A perpendicular line to a plane in 3D

I have two line segments identified by two end points each. Two line segments are in the same plane and intersecting at a point. I would like to draw a line (normal of the plane) passing through the intersection point. I use TikZ, calc, and 3d libraries. But I couldn't figure out a straightforward way to do that. I can calculate the line (normal) end point using Matlab software. But I prefer TikZ solution, if it is possible.

Edit 1: Minimum Working Example

\documentclass[border=2pt]{standalone}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usetikzlibrary{calc,3d}

\begin{document}
\begin{tikzpicture}[x  = {(-0.5cm,-0.5cm)},
y  = {(0.9659cm,-0.25882cm)},
z  = {(0cm,1cm)},
scale = 0.8,
color = {lightgray}]

% the data input is created for minimal working example
\coordinate (A) at (1,1,4);
\coordinate (B) at (7,5,4);
\coordinate (SS) at (5,11/3,4);
\coordinate (C) at (7,1,7);
\coordinate (D) at ($(C)!7cm!(SS)$);

% two line segments
\draw[black] (A) -- (B);
\draw[black] (C) -- (D);

% intersection point (SS = S)
\coordinate (S) at (intersection of A--B and C--D);
\filldraw[green] (S) circle(2pt);

%% the plane
\draw[dashed,black,fill=red!30, opacity=0.5] (A) -- (C) -- (B) -- (D) -- cycle;

% labels
\node[above] at (A) {$A$};
\node[below] at (B) {$B$};
\node[left] at (C) {$C$};
\node[right] at (D) {$D$};
\node[right] at (S) {$S$};

% how to draw a line segment starting at (S) pointing outward
% and being perpendicular to the plane (A,B,C,D) ?

\end{tikzpicture}
\end{document}


• I guess the intersections library might help. Commented Feb 13, 2013 at 14:39

Here is a proof of concept, followed by discussion.

\documentclass[border=2pt]{standalone}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usetikzlibrary{calc,3d}

\begin{document}
\begin{tikzpicture}[x  = {(-0.5cm,-0.5cm)},
y  = {(0.9659cm,-0.25882cm)},
z  = {(0cm,1cm)},
scale = 0.8,
color = {lightgray}]

% the data input is created for minimal working example
\newdimen\Ax
\newdimen\Ay
\newdimen\Az
\Ax=1pt
\Ay=1pt
\Az=4pt

\coordinate (A) at (\Ax,\Ay,\Az);

\newdimen\Bx
\newdimen\By
\newdimen\Bz
\Bx=7pt
\By=5pt
\Bz=4pt

\coordinate (B) at (\Bx,\By,\Bz);

\newdimen\SSx
\newdimen\SSy
\newdimen\SSz
\SSx=5pt
\SSy=\dimexpr11pt/3\relax
\SSz=4pt

\coordinate (SS) at (\SSx,\SSy,\SSz);

\newdimen\Cx
\newdimen\Cy
\newdimen\Cz
\Cx=7pt
\Cy=1pt
\Cz=7pt

\coordinate (C) at (\Cx,\Cy,\Cz);

\newdimen\Dx
\newdimen\Dy
\newdimen\Dz
% D = t*SS + (1-t)*C; t=1.7
\Dx=\dimexpr1.7\SSx-0.7\Cx\relax
\Dy=\dimexpr1.7\SSy-0.7\Cy\relax
\Dz=\dimexpr1.7\SSz-0.7\Cz\relax

\coordinate (D) at (\Dx,\Dy,\Dz);

\newdimen\Nx
\newdimen\Ny
\newdimen\Nz
\Nx=\dimexpr(\By-\Ay)/100*(\Dz-\Cz)/100-(\Bz-\Az)/100*(\Dy-\Cy)/100\relax
\Ny=\dimexpr(\Bz-\Az)/100*(\Dx-\Cx)/100-(\Bx-\Ax)/100*(\Dz-\Cz)/100\relax
\Nz=\dimexpr(\Bx-\Ax)/100*(\Dy-\Cy)/100-(\By-\Ay)/100*(\Dx-\Cx)/100\relax

% two line segments
\draw[black] (A) -- (B);
\draw[black] (C) -- (D);

% intersection point (SS = S)
\coordinate (S) at (intersection of A--B and C--D);
\filldraw[green] (S) circle(2pt);

%% the plane
\draw[dashed,black,fill=red!30, opacity=0.5] (A) -- (C) -- (B) -- (D) -- cycle;

% labels
\node[above] at (A) {$A$};
\node[below] at (B) {$B$};
\node[left] at (C) {$C$};
\node[right] at (D) {$D$};
\node[right] at (S) {$S$};

% how to draw a line segment starting at (S) pointing outward
% and being perpendicular to the plane (A,B,C,D) ?

\coordinate (N) at ($(S)+0.01*(\Nx,\Ny,\Nz)$);
\node[right] at (N) {$N$};
\draw[->] (S) -- (N);

\end{tikzpicture}
\end{document}


The problem with tikz is that it doesn't do three-dimensional geometry. Any expression such as (1,5,2) is converted directly to a point in the plane, as 1 * xvector + 5 * yvector + 3 * zvector, where xvector in your example is (-0.5cm,-0.5cm), etc. This means that much of the three-dimensional inforamtion is lost at the stage when you use the \coordinate command to define (A) and the other points.

In particular, the projections (A),...,(D) in your code are not sufficient to determine the normal. E.g. if the 3d points A,...,D all sat in the plane of the page, the normal would point directly out towards us, on the other hand if A and D were a long way in front of the page, but C and B in the page, the normal would be close to parallel to the page.

So, assuming that you wanted to put in different 3d points to get similar such a diagrams, I have set up each point via new variables \Ax,\Ay,\Az, and then used those coordinates in the subsequent calculations and assignments.

You had point D defined as a certain distance along the line C--SS, I replaced that by a certain proportion, rather than starting to calculate distances in 3d. (The calculation you had was 7cm in the plane.)

Now given A,B,C,D in three-dimensions, the normal is specified via the cross product of the difference vectors: if (vx,vy,vz) = B - A, (wx,wy,wz) = D - C then the normal is

(vy*wz-vz-wy, vz*wx-vx*wz, vx*wy-vy*wx)


I put this into \Nx,\Ny,\Nz - but had to scale, because of arithmetic overflow. Once one has this normal, one can use the standard calc mechanisms to draw an arrow in that direction starting from (S). Again I scaled, so the arrow was a reasonable size.

• Nice answer! Four comments: (A) I guess (1,5,2) is converted to 1 * xvector + 5 * yvector + 2 * zvector, isn’t it? (B) Is there a reason that you dont use pgfmath to calculate the cross product? (C) could you add a bigger image (too big images will be scaled to fit the width …). (D) I’d use \def\Ax{1pt} since it’s shorter or \pgfmathsetmacro{\Ax}{1} to use pgfmath consequently.
– Tobi
Commented Feb 14, 2013 at 15:26
• @Tobi (A) Thanks for spotting the typo. (B) pgfmath would be a good way to go; this was just proof of concept. (C) Is this new image big enough? Commented Feb 14, 2013 at 15:31
• (C) Yes, big enough :-)
– Tobi
Commented Feb 14, 2013 at 15:34