# tikz-3dplot: Find projection of a vector on a unitary sphere

I am using TikZ (with the 3dplot package) to draw figures that mostly represent vectors lying on 2-Spheres surfaces. I have to say I am a bit of a newbie with TikZ, but I think i got the basic concepts.

In this MWE I am drawing a figure with 3 unitary length vectors m, n and l (with m orthogonal to both l and n). I also have a point x that lies on the "meridian" connecting m and l, and its orthogonal projection xp on the n,m plane.

\documentclass{article}
\usepackage{tikz}
\usepackage{tikz-3dplot}

\begin{document}

\begin{figure}[ht]
\centering

\tdplotsetmaincoords{70}{135}
\pgfmathsetmacro{\rvec}{1}
\pgfmathsetmacro{\thetavec}{320}
\pgfmathsetmacro{\phivec}{240}

\begin{tikzpicture}[tdplot_main_coords, scale=8]

\coordinate (O) at (0,0,0);
\draw[thick,->] (O) -- (0,\rvec,0) node[anchor=north west]{$\mathbf{n}$};
\draw[thick,->] (O) -- (0,0,\rvec) node[anchor=south]{$\mathbf{m}$};

\tdplotsetcoord{X}{\rvec}{\thetavec}{\phivec};
\tdplotsetcoord{L}{\rvec}{270}{\phivec}

\draw[thick,->] (O) -- (X) node[anchor=east]{$\mathbf{x}$};
\draw[thick,->] (O) -- (L) node[anchor=east]{$\mathbf{l}$};

\draw[thick,->] (O) -- (Xyz) node[anchor=south east]{$\mathbf{x_p}$};
\draw[dashed] (X) -- (Xyz);

\tdplotsetthetaplanecoords{90};
\tdplotdrawarc[tdplot_rotated_coords, style=dashed]{(O)}{\rvec}{0}{90}{}{};

\tdplotsetthetaplanecoords{\phivec};
\tdplotdrawarc[tdplot_rotated_coords, style=dashed]{(O)}{\rvec}{-90}{0}{}{};

\end{tikzpicture}
\end{figure}

\end{document}


My question is: Is it possible to draw a line that connects xp to its projection on the sphere? Or, alternatively, a line that starts from the origin and stops at the projection of xp on the sphere?

In another context I would have simply L2-normalized xp to unitary lenght, but in TikZ this doesn't seem to be a viable option (correct me if I'm wrong).

For a better understanding, the picture shows what I am looking for: that really ugly red segment.

Thank you for your time and sorry for the occasionally bad English!

• There are two ways to do this: find the angles (using inverse trig functions with pgfmath) and use polar coordinates, or project the path and find the intersection with the corresponding arc (keeping in mind that the intersections are computed in 2D). BTW, where is (Xyz) defined? Jan 15, 2016 at 22:29
• Thank you for your comment. I think that the second approach could be more easily implemented, but I will have to think about it. Should I use the shorten command (with negative value)? Xyz is never explicitly defined becuse tikz-3dplot automatically computes the projection of a point to the 3 planes xy, xz, yz (and actually also the 3 components x, y and z).
– UJIN
Jan 17, 2016 at 13:16
• calc is generally used to extend lines: ($(O)!2!(Xyz)$) Jan 17, 2016 at 18:25

I should mention that P is defined using screen coordinates. You would need to project the screen coordinates onto the appropriate plane to get 3D coordinates.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc,intersections}
\usepackage{tikz-3dplot}

\begin{document}

\begin{figure}[ht]
\centering

\tdplotsetmaincoords{70}{135}
\pgfmathsetmacro{\rvec}{1}
\pgfmathsetmacro{\thetavec}{320}
\pgfmathsetmacro{\phivec}{240}

\begin{tikzpicture}[tdplot_main_coords, scale=8]

\coordinate (O) at (0,0,0);
\draw[thick,->] (O) -- (0,\rvec,0) node[anchor=north west]{$\mathbf{n}$};
\draw[thick,->] (O) -- (0,0,\rvec) node[anchor=south]{$\mathbf{m}$};

\tdplotsetcoord{X}{\rvec}{\thetavec}{\phivec};
\tdplotsetcoord{L}{\rvec}{270}{\phivec}

\draw[thick,->] (O) -- (X) node[anchor=east]{$\mathbf{x}$};
\draw[thick,->] (O) -- (L) node[anchor=east]{$\mathbf{l}$};

\draw[thick,->] (O) -- (Xyz) node[anchor=south east]{$\mathbf{x_p}$};
\draw[dashed] (X) -- (Xyz);

\tdplotsetthetaplanecoords{90};
\tdplotdrawarc[tdplot_rotated_coords, style=dashed]{(O)}{\rvec}{0}{90}{}{};

\tdplotsetthetaplanecoords{\phivec};
\tdplotdrawarc[tdplot_rotated_coords, style=dashed]{(O)}{\rvec}{-90}{0}{}{};

\path[name path=line1] (O) -- ($(O)!2!(Xyz)$);% extended line
\tdplotsetthetaplanecoords{90};
\path[tdplot_rotated_coords, name path=arc1] (O) circle (\rvec);% extended arc
\path[name intersections={of=line1 and arc1}]
coordinate (P) at (intersection-1);
\draw[red,thick] (Xyz) -- (P);% could have combined the two steps

\end{tikzpicture}
\end{figure}

\end{document}


• Thank you very much! In the end I managed to draw the line before reading your answer (but following your really useful comments). What I did was naming the arc that I'm already drawing and then add these lines: \path[name path=line, color=blue] (O) -- ($(O)!2!(Xyz)$); \path[name intersections={of=line and arc, name=i}] (i-1); \draw[thick, color=red] (Xyz) -- (i-1); By the way I'm accepting your answer! Thank you a lot for your help :)
– UJIN
Jan 18, 2016 at 11:29