74

I'm having a bit of a headache right now as I can't draw this basic figure:

A straight line goes through points A and B. Another line is perpendicular to AB and goes through an arbitrary point P.

I fiddled with the |- operator but it only seems to work with horizontal or vertical lines. Is this even possible?

Bonus question: when drawing AB, is it possible to let the line poke out a little? For example, when writing \draw (A) -- (B); the line strictly goes from A to B. I'd rather have a line passing through these points but starting 1cm in front of A and ending 1cm after B (for example).

Thank you for your help :)

4
  • 4
    For the "bonus" question: You could use shorten >=-1cm,shorten <=-1cm together with a pseudo-arrow tip to extend the lines. May 29, 2011 at 13:29
  • 4
    @Martin: The shorten (note spelling mistake in your comment) keys work independently of arrow tips so it's not necessary to specify an arrow tip. Thus \draw[shorten >=-1cm] (0,0) -- (2,0); will work. May 29, 2011 at 17:44
  • Thanks @Andrew. I figured this out in the meantime. See my comment below Jakes answer. May 29, 2011 at 17:46
  • 2
    @Martin: I know, but some people may not read further and just see the comment here so I thought it worth pointing that out here as well. May 29, 2011 at 17:50

4 Answers 4

85

You can use the calc library for this, which allows to do coordinate calculations. The expression ($(A)!(P)!(B)$) yields the projection of (P) on the line from (A) to (B), for example.

As Martin Scharrer points out, you can extend the lines by using the shorten > and shorten < commands with negative values. I'm using them here in a style called extended line that takes an optional argument to set the length by which to extend the line.

Here's your example:

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

\begin{document}
\begin{tikzpicture}[dot/.style={circle,inner sep=1pt,fill,label={#1},name=#1},
  extended line/.style={shorten >=-#1,shorten <=-#1},
  extended line/.default=1cm]

\node [dot=A] at (0,0) {};
\node [dot=B] at (3,1) {};
\node [dot=P] at (1.9,-1.6) {};

\draw [extended line=0.5cm] (A) -- (B);
\draw [extended line] ($(A)!(P)!(B)$) -- (P);

\fill [red] ($(A)!(P)!(B)$) circle [radius=2pt];

\end{tikzpicture}
\end{document}

tikz projected point

10
  • 5
    Good answer. Note that you should also be able to give length instead of factors, e.g. ($(A)!-1cm!(B)$) instead of ($(A)!-0.2!(B)$). Also \draw [shorten >=-1cm,shorten <=-1cm] (A) -- (B); works well for the extension of the line. May 29, 2011 at 13:58
  • 2
    Good idea with the shorten commands, that's much more readable!
    – Jake
    May 29, 2011 at 14:02
  • 2
    The structure of this example would also be clearer if you defined, for example, \node (Q) at ($(A)!(P)!(B)$); and made reference to it.
    – Ryan Reich
    May 29, 2011 at 14:04
  • 2
    This answer has a good explanation of this sort of usage of the calc library
    – Seamus
    May 29, 2011 at 14:13
  • 5
    @Ryan: In that case you really should use \coordinate instead of \node to avoid issues with borders and minimal size etc. May 29, 2011 at 17:47
19

Here's how to do it using tkz-euclide; the code is, in fact, a variation of one example given in the tkz-euclide examples collection:

\documentclass{article}
\usepackage{tkz-euclide}

\begin{document}

\begin{tikzpicture}[scale=.5]
  \tkzDefPoint(0,0){A}
  \tkzDefPoint(4,2.5){B}
  \tkzDefPoint(4,5){C}
  \tkzDrawLine[add= 0.5 and 0.8,color=blue](A,B)
  \tkzDrawPoints(A,B,C)\tkzLabelPoints(A,B,C)
  \tkzDefLine[orthogonal=through C](A,B)
  \tkzDrawLine[add = .5 and .2,color=red](C,tkzPointResult)
\end{tikzpicture}

\end{document}

enter image description here

EDIT: since tkz-euclide is on CTAN but it is not included in TeX Live (at least not fot the moment), you'll have to download the files and install them manually.

8
  • Thanks for the answer but I think I'll rather use the calc method described above :) May 29, 2011 at 15:13
  • @Gonzalo Medina The announcement is not done yet but the new version in on CTAN. I added tkz-graph and tkz-berge. Now on CTAN, there is a directory tkz with all my packages based on TikZ. A big part of tkz will be on the next release of TeXLive 2011 (the beginning of July). Jun 7, 2011 at 15:26
  • @Altermundus: great! Thank you very much for the notice. Jun 7, 2011 at 17:21
  • @Gonzalo Medina your imagina is no longer available. Would it be possible to put it back in?
    – Vivi
    Jun 27, 2011 at 22:07
  • @Vivi: done. It's a problem with most of the images I uploaded; see this thread on meta: how-do-we-repair-gonzalo-medinas-posts-containing-images. Jun 27, 2011 at 22:14
9

1) tkz-euclide is on CTAN but not on TexLive I need to upload the sources of the documentation.

2) The solution with calc it's not effective. The next code is from the pgfmanualand I make a zoom on the intersection (see The Syntax of Projection Modifiers)

\begin{tikzpicture} \draw [help lines] (0,0) grid (3,2);
\coordinate (a) at (0,1); 
\coordinate (b) at (3,2); 
\coordinate (c) at (2.5,0);
\draw (a) -- (b) -- (c) -- cycle;
\draw[red]  (a) -- ($(b)!(a)!(c)$); 
\draw[orange] (b) -- ($(a)!(b)!(c)$); 
\draw[blue] (c) -- ($(a)!(c)!(b)$);
\end{tikzpicture}

enter image description here

On some cases, It's impossible to draw geometric picture without errors. In tkz-euclide, if I want a line from A perpendicular to BC, I define a vector BE perpendicular BC, then a vector AD perpendicular to BC and then I search the intersection of AD and BC

3) For the extend style, another solution is :

\tikzset{%
    add/.style args={#1 and #2}{
        to path={%
 ($(\tikztostart)!-#1!(\tikztotarget)$)--($(\tikztotarget)!-#2!(\tikztostart)$)%
  \tikztonodes}}
} 

example : the idea is to use percentage add = 1 and 0, double the line, with 1 and 1 we get the triple, and you can use negative numbers

\documentclass[a4paper]{scrartcl}
\usepackage{tikz} 
\usetikzlibrary{calc}   

\begin{document}

\begin{tikzpicture}[dot/.style={circle,inner sep=1pt,
                   fill,label={#1},name=#1},]
\tikzset{%
add/.style args={#1 and #2}{to path={%
 ($(\tikztostart)!-#1!(\tikztotarget)$)--($(\tikztotarget)!-#2!(\tikztostart)$)%
\tikztonodes}}
}

\node [dot=A](A) at (0,0) {};
\node [dot=B](B) at (3,1) {};  
\node [dot=C](C) at (3,-1) {};  
\draw[add = 1 and 0] (A) to (B);
\draw[add = .5 and .5] (A) to (C);      
\end{tikzpicture}
\end{document} 

enter image description here

6

Just another simpler solution with PSTricks.

enter image description here

\documentclass[pstricks]{standalone}
\usepackage{pst-eucl}
\begin{document}
\pspicture(8,6)
    \pstGeonode(2,3){A}(6,5){B}(6,2){P}
    \pstProjection[PointName=none]{A}{B}{P}
    \psset{nodesep=-1}
    \pstLineAB{A}{B}
    \pstLineAB{P}{P'}
\endpspicture
\end{document}

Applications

To answer this question (click).

\documentclass[pstricks]{standalone}
\usepackage{pst-eucl}
\usepackage{esvect}
\psset
{
    PointName=none,
    PointSymbol=none,
    linejoin=1,
    shortput=nab,
    arrows=->,
}
\begin{document}
\pspicture(8,6)
    \pstGeonode(1,1){A}(2,5){B}(7,3){C}
    \pcline(A)(B)^{$\vv v$}
    \pcline(A)(C)_{$\vv u$}
    \pstProjection{A}{C}{B}
    \pstRightAngle{C}{B'}{B}
    \pstMarkAngle{B'}{A}{B}{$\theta$}
    \psset{linecolor=blue}%
    \everypsbox{\color{blue}}%
    \pcline(B')(B)_{$\vv{v}_{{\scriptscriptstyle\bot}\vv u}$}
    \pcline(A)(B')_{$\vv{v}_{{\scriptscriptstyle\parallel}\vv u}$}
\endpspicture
\end{document}

enter image description here

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .