12

I have the problem, that I want to draw a vector that is decomposed into two orthogonal parts. A short example:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}[dot/.style={circle,inner sep=2pt,fill,label={#1},name=#1,color=red},
  extended line/.style={shorten >=-#1,shorten <=-#1},
  extended line/.default=1cm,scale=2]
\begin{scope}[rotate=30]
  \node [dot=A] at (1,4) {};
  \node [dot=B] at (2,2) {};
  \node [dot=P] at (4,4) {};
  \draw [->] (A) -- (B);
  \draw [->] (A) -- (P -| B);
  \draw [->] (A) -- ($(B) - (P-|B) + (A)$);
\end{scope}
\end{tikzpicture}
\end{document}

Here I have the vector AB. I want one of the component vecors to be in the direction of AP. The other should be orthogonal (as seen).

In the example I solved it using -| but this works only if the desired vectors are parallel to the actual axes. I need it for arbitrary points A, B and P.

Can you give me a hint, how to draw it?

Werner
  • 603,163
  • 4
    Does http://tex.stackexchange.com/questions/19348/how-to-draw-a-line-passing-through-a-point-and-perpendicular-to-another solve your problem? – Caramdir Aug 09 '11 at 21:03
  • Well, if I define a new coordinate at the tip of the vector on the line AP using (A)!(P)!(B) and then doing some calculations this should work. Thanks – Christian Wolf Aug 09 '11 at 21:22

3 Answers3

13

The projection syntax from the calc library also takes an optional angle: ($(A)!(P)!90:(B)$) is the projection of point (P) on the line from (A) to (B) after that line has been rotated 90 degrees around point (A). This makes it easy to draw the vector components:

decomposing vector into orthogonal components

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}[
    dot/.style={
        circle,
        inner sep=2pt,
        fill,
        label={#1},
        name=#1,
        color=red
    },
    scale=2]
\begin{scope}
  \node [dot=A,gray] at (1,4) {};
  \node [dot=B,gray] at (2,2) {};
  \node [dot=P] at (4,3) {};
  \node [dot=P2,cyan] at (3,2.5) {};
  \draw [->] (A) -- (B);
  \draw [->,red] (A) -- ($(A)!(B)!(P)$);
  \draw [->,red] (A) -- ($(A)!(B)!90:(P)$);
  \draw [->,cyan] (A) -- ($(A)!(B)!(P2)$);
  \draw [->,cyan] (A) -- ($(A)!(B)!90:(P2)$);
\end{scope}
\end{tikzpicture}
\end{document}
Jake
  • 232,450
5

Here are two styles that do what you want. You have to specify the direction AP as an argument of the style, as shown in my example.

\documentclass{minimal}

\usepackage{xcolor}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{decorations.pathreplacing}

\tikzstyle{ortho proj}=[decorate,decoration={show path construction,
lineto code={
    \draw let 
    \p{O} = (\tikzinputsegmentfirst),
    \p{A} = (\tikzinputsegmentlast),
    \p{OA} = ($(\p{A})-(\p{O})$),
    \p{w} = #1,
    \n{dot} =  {\x{w}*\x{OA}+\y{w}*\y{OA}},
    \p{proj} = ($\n{dot}/(veclen(\x{w},\y{w}))^2*(\p{w})$)
    in
    (\p{O}) -- ++(\p{proj});}}]


\tikzstyle{perp proj}=[decorate,decoration={show path construction,
lineto code={
    \draw let 
    \p{O} = (\tikzinputsegmentfirst),
    \p{A} = (\tikzinputsegmentlast),
    \p{OA} = ($(\p{A})-(\p{O})$),
    \p{w} = #1,
    \n{dot} =  {\x{w}*\x{OA}+\y{w}*\y{OA}},
    \p{proj} = ($\n{dot}/(veclen(\x{w},\y{w}))^2*(\p{w})$),
    \p{perp} = ($(\p{OA}) - (\p{proj})$)
    in
    (\p{O}) -- ++(\p{perp});}}]

\begin{document}

\begin{tikzpicture}

\draw[->] (0,0) -- (2,2);
\draw[ortho proj={(1.5,1)},->] (0,0) -- (2,2);
\draw[perp proj={(1.5,1)},->] (0,0) -- (2,2);

\end{tikzpicture}

\end{document}

The result is

enter image description here

Frédéric
  • 11,087
  • 3
  • 37
  • 43
3

I use the following sort of solution (taken from this wonderful answer):

\documentclass{minimal}
\usepackage{tikz}
\begin{document}
\newcommand{\tikzAngleOfLine}{\tikz@AngleOfLine}
\def\tikz@AngleOfLine(#1)(#2)#3{%
  \pgfmathanglebetweenpoints{%
    \pgfpointanchor{#1}{center}}{%
    \pgfpointanchor{#2}{center}}
  \pgfmathsetmacro{#3}{\pgfmathresult}%
}
\begin{tikzpicture}
 \coordinate (a) at (0.2,0.3);
 \coordinate (b) at (1.3,2.4);
 \draw[->] (a) -- (b) ;
 \tikzAngleOfLine(a)(b){\angle};
\draw[blue,->] (a) -- ++(\angle+90:2);
\draw[green,->] (a) -- ++(\angle-90:2);
\end{tikzpicture}
\end{document}

Maybe will be useful for others.

Dror
  • 22,613