Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

Suppose I have a plane $E: a*x_1 + b*x_2 + c*x_3 = d$ (a,..,d should be concrete numbers) in space and a point P. Is there a way to draw a 3-d coordinate system, E, P and perpendicular line to E through P?

share|improve this question
    
How do you want the plane to be drawn? –  Caramdir Jun 5 '11 at 17:42
    
Perhaps one need to distinguish different cases: If the plane intersects all three coordinate axis, I want to connect those intersection points and draw the resulting triangle. If this is not the case I want to have something like this –  student Jun 5 '11 at 18:06
add comment

1 Answer

TikZ has a built-in 3d coordinate system. You can set the directions of the unit vectors with the x, y and z options. Then you could just do the math by hand and draw the points and lines. Or, you can define some macros to do the job:

\documentclass{article}
\usepackage{tikz}

\makeatletter

% Set some defaults 
\tikzset{
    plane max x/.initial=2,
    plane max y/.initial=2,
    plane max z/.initial=2
}

\tikzset{plane/.style={fill opacity=0.5}}

% Define a plane.
% #1 = name of the plane
% #2*x + #3*y + #4*z = #5 is the equation of the plane
\newcommand*\definePlaneByEquation[5]{
    \expandafter\gdef\csname tsx@plane@#1\endcsname{
        \def\tsx@plane@xcoeff{#2}
        \def\tsx@plane@ycoeff{#3}
        \def\tsx@plane@zcoeff{#4}
        \def\tsx@plane@scalar{#5}
    }
}

% Draw a plane.
% The optional first argument is passed as options to TikZ.
% The mandatory second argument is the name of the plane.
\newcommand\drawPlane[2][]{
    \tikzset{plane max x/.get=\tsx@plane@maxx}
    \tikzset{plane max y/.get=\tsx@plane@maxy}
    \tikzset{plane max z/.get=\tsx@plane@maxz}
    \csname tsx@plane@#2\endcsname

    \ifdim\tsx@plane@xcoeff pt=0pt
        \ifdim\tsx@plane@ycoeff pt=0pt
            \ifdim\tsx@plane@zcoeff pt=0pt
                %invalid plane
            \else % x=0, y=0
                \filldraw[plane,#1,shift={(0,0,\tsx@plane@scalar/\tsx@plane@zcoeff)}]
                    (0,0,0) --
                    (\tsx@plane@maxx,0,0) --
                    (\tsx@plane@maxx,\tsx@plane@maxy,0) --
                    (0,\tsx@plane@maxy,0) --
                    cycle;
            \fi
        \else % x=0, y != 0
            \ifdim\tsx@plane@zcoeff pt=0pt % x=0, z=0
                \filldraw[plane,#1,shift={(0,\tsx@plane@scalar/\tsx@plane@ycoeff,0)}]
                    (0,0,0) --
                    (\tsx@plane@maxx,0,0) --
                    (\tsx@plane@maxx,0,\tsx@plane@maxz) --
                    (0,0,\tsx@plane@maxz) --
                    cycle;
            \else % x=0
                \filldraw[plane,#1]
                    (0,\tsx@plane@scalar/\tsx@plane@ycoeff,0) --
                    (0,0,\tsx@plane@scalar/\tsx@plane@zcoeff) --
                    (\tsx@plane@maxx,0,\tsx@plane@scalar/\tsx@plane@zcoeff) --
                    (\tsx@plane@maxx,\tsx@plane@scalar/\tsx@plane@ycoeff,0) --
                    cycle;
            \fi
        \fi
    \else % x!=0
        \ifdim\tsx@plane@ycoeff pt=0pt % x!=0,y=0
            \ifdim\tsx@plane@zcoeff pt=0pt % x!=0,y=0,z=0
                \filldraw[plane,#1,shift={(\tsx@plane@scalar/\tsx@plane@xcoeff,0,0)}]
                    (0,0,0) --
                    (0,0,\tsx@plane@maxz) --
                    (0,\tsx@plane@maxy,\tsx@plane@maxz) --
                    (0,\tsx@plane@maxy,0) --
                    cycle;
            \else % x!=0,y=0,z!=0
                \filldraw[plane,#1]
                    (\tsx@plane@scalar/\tsx@plane@xcoeff,0) --
                    (0,0,\tsx@plane@scalar/\tsx@plane@zcoeff) --
                    (0,\tsx@plane@maxy,\tsx@plane@scalar/\tsx@plane@zcoeff) --
                    (\tsx@plane@scalar/\tsx@plane@xcoeff,\tsx@plane@maxy,0) --
                    cycle;
            \fi
        \else % x!=0,y!=0
            \ifdim\tsx@plane@zcoeff pt=0pt % x!=0,y!=0,z=0
                \filldraw[plane,#1]
                    (\tsx@plane@scalar/\tsx@plane@xcoeff,0) --
                    (0,\tsx@plane@scalar/\tsx@plane@ycoeff,0) --
                    (0,\tsx@plane@scalar/\tsx@plane@ycoeff,\tsx@plane@maxz) --
                    (\tsx@plane@scalar/\tsx@plane@xcoeff,0,\tsx@plane@maxz) --
                    cycle;
            \else % x!=0,y!=0,z!=0
                \filldraw[plane,#1]
                    (\tsx@plane@scalar/\tsx@plane@xcoeff,0,0) --
                    (0,\tsx@plane@scalar/\tsx@plane@ycoeff,0) --
                    (0,0,\tsx@plane@scalar/\tsx@plane@zcoeff) --
                    cycle;
            \fi
        \fi
    \fi
}

% Define a point.
% #1 = name of the point
% (#2,#3,#4) is the location.
% Also creates a coordinate node of name #1 at the location.
\newcommand\definePointByXYZ[4]{
    \coordinate (#1) at (#2,#3,#4);
    \expandafter\gdef\csname tsx@point@#1\endcsname{
        \def\tsx@point@x{#2}
        \def\tsx@point@y{#3}
        \def\tsx@point@z{#4}
    }
}

% Project a point to a plane.
% #1 = name of the new point
% #2 = name of old point
% #3 = name of plane
\newcommand\projectPointToPlane[3]{{
    \csname tsx@point@#2\endcsname
    \csname tsx@plane@#3\endcsname

    % square of norm of the normal vector
    \pgfmathparse{\tsx@plane@xcoeff*\tsx@plane@xcoeff + \tsx@plane@ycoeff*\tsx@plane@ycoeff + \tsx@plane@zcoeff*\tsx@plane@zcoeff}
    \let\nnormsq\pgfmathresult

    % Calculate distance in terms of the (non-normalized) normal vector
    \pgfmathparse{(\tsx@point@x*\tsx@plane@xcoeff + \tsx@point@y*\tsx@plane@ycoeff + \tsx@point@z*\tsx@plane@zcoeff - \tsx@plane@scalar) / \nnormsq}
    \let\distance\pgfmathresult

    % Calculate point
    \pgfmathparse{\tsx@point@x - \distance*\tsx@plane@xcoeff}
    \let\x\pgfmathresult
    \pgfmathparse{\tsx@point@y - \distance*\tsx@plane@ycoeff}
    \let\y\pgfmathresult
    \pgfmathparse{\tsx@point@z - \distance*\tsx@plane@zcoeff}
    \let\z\pgfmathresult

    \definePointByXYZ{#1}{\x}{\y}{\z}
}}
\makeatother

\begin{document}
\begin{tikzpicture}[x={(240:0.8cm)}, y={(-10:1cm)}, z={(0,1cm)},
        plane max z=3]
    \draw[->] (0,0,0) -- (3,0,0);
    \draw[->] (0,0,0) -- (0,3,0);
    \draw[->] (0,0,0) -- (0,0,3);

    \definePlaneByEquation{myplane}{1}{1.5}{0}{2}
    \drawPlane[thick,fill=blue]{myplane}

    \definePointByXYZ{mypoint}{1}{1.5}{2};
    \draw (mypoint) circle [radius=1pt];

    \projectPointToPlane{proj}{mypoint}{myplane}
    \fill (proj) circle [radius=1pt];

    \draw[->, shorten <=1pt,shorten >=1pt] (mypoint) -- (proj);
\end{tikzpicture}
\end{document}

project a point to a plane

Some comments:

  • I hope I didn't mess up some case.
  • With the plane max x/y/z options, you can specify how far a plane with zero parameters should extend.
  • If you want to draw a line through the point, normal to the plane, you can use

    \definePlaneByEquation{myplane}{1}{1.5}{0}{2}
    \definePointByXYZ{mypoint}{1}{1.5}{2};
    \projectPointToPlane{proj}{mypoint}{myplane}
    
    \draw ($(proj)!-2cm!(mypoint)$) -- (proj);
    \drawPlane[thick,fill=blue]{myplane}
    \draw (proj) -- ($(mypoint)!-2cm!(proj)$);
    

    The order is important to get correct overpainting in case the plane is opaque or the line is non-black.

  • The tests for 0 should really be tests for being smaller than epsilon.
  • Maybe it would be useful to apply \pgfmathparse to the arguments of the definition macros.
share|improve this answer
    
Fine! It's a good starting point. I started a package about 3D geometry and this answer is interesting. –  Alain Matthes Jun 6 '11 at 8:40
    
@Astramundus, do you know the tikz-3dplot package? I use it all the time, might also be a good source for your 3d package? Check it out at: archive.cs.uu.nl/mirror/CTAN/graphics/pgf/contrib/tikz-3dplot/… –  romeovs Jun 6 '11 at 8:48
    
@Altermundus: I was wondering whether I should invest more time in this and add more things for 3D geometry (e.g. intersect various things) or if you are already working on a 3D version of TkZ. –  Caramdir Jun 6 '11 at 15:56
    
@romeovs: tikz-3dplot is nice, but as far as I am aware it doesn't have features to define planes and do intersections and such. –  Caramdir Jun 6 '11 at 15:58
    
@romeovs Yes :) but the author of the tikz-3dplot package uses some of my ideas. The author found interesting my "annotated-3d-box" example on texample.net: texample.net/tikz/examples/annotated-3d-box –  Alain Matthes Jun 6 '11 at 16:14
show 1 more comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.