# How can I draw an arc from point A -> B on a 3D sphere in TikZ?

I'm basing myself on http://www.texample.net/tikz/examples/spherical-and-cartesian-grids/ and now I need to add a arc from point P to Q. What I was able to get so far:

\begin{tikzpicture}[scale=1,every node/.style={minimum size=1cm}]
%% some definitions

\def\angEl{25} % elevation angle
\def\angAz{-100} % azimuth angle
\def\angPhiOne{-110} % longitude of point P
\def\angPhiTwo{-45} % longitude of point Q
\def\angBeta{30} % latitude of point P and Q

%% working planes

\pgfmathsetmacro\H{\R*cos(\angEl)} % distance to north pole
\LongitudePlane[xzplane]{\angEl}{\angAz}
\LongitudePlane[pzplane]{\angEl}{\angPhiOne}
\LongitudePlane[qzplane]{\angEl}{\angPhiTwo}
\LongitudePlane[nzplane]{\angEl}{-86}
\LatitudePlane[equator]{\angEl}{0}
\fill[ball color=white!10] (0,0) circle (\R); % 3D lighting effect
\coordinate (O) at (0,0);
\coordinate[mark coordinate] (N) at (0,\H);
\coordinate[mark coordinate] (S) at (0,-\H);

\DrawLongitudeCircle[\R]{\angPhiOne} % pzplane
\DrawLongitudeCircle[\R]{\angPhiTwo} % qzplane
\DrawLatitudeCircle[\R]{\angBeta}
\DrawLatitudeCircle[\R]{0} % equator
%labelling north and south
\node[above=8pt] at (N) {$\mathbf{N}$};
\node[below=8pt] at (S) {$\mathbf{S}$};
\draw[-,dashed, thick] (N) -- (S);

%setup coordinates P and Q
\path[pzplane] (0:\R) coordinate (P);
\draw[->] (O) -- node[above=4pt] {$\overrightarrow{P}$} (P);
\path[qzplane] (\angBeta:\R) coordinate (Q);
\draw[->] (O) -- node[above=2pt] {$\overrightarrow{Q}$} (Q);
\path[nzplane] (153:\R) coordinate (N);
\draw[->,color=red] (O) -- node[right=2pt] {$\overrightarrow{N}$} (N);
\draw (P) arc (-110:-45:\R) (Q);
\end{tikzpicture}


Is there a possibility to make an arc from P to Q with the center O?

Upon request, the full compilable sourcecode: http://pastebin.com/m809Jwp7

• mark coordinate ?? Mar 5, 2012 at 10:11
• While code snippets are useful in explanations, it is always best to compose a fully compilable MWE that illustrates the problem including the \documentclass and the appropriate packages so that those trying to help don't have to recreate it. This is especially important with tikz as there are numerous libraries. Mar 5, 2012 at 15:46
• Sorry, my fault! I added a complete dump of the code via pastebin. Works perfectly with MacTeX 2011 and pdflatex.
– mhk
Mar 5, 2012 at 17:12
• I think you need to define the plane POQ like the others planes (qzplane, etc.) with \tikzset{POQ/.estyle={cm={..,..,..,..,(0,0)}}} but the problem is to find ..,..,..,.., !! Mar 5, 2012 at 17:52
• How "mark coordinate" is defined ? Mar 5, 2012 at 17:53

To give a correct answer, we need to define cross product and vector product (this work is done with metapost in cahier gutemberg 48 but it's in french)

I don't have enough time to define all these macros but it's possible to find a way to draw the arc. First we know that the arc PQ (blue) is in the plane OPQ and is a part of a circle of center O and radius OP. So I search a Coordinate system xyz with x=OP and y=OA'. A is a point of the equator of longitude = -20. Why ? because I want OP and OA radius of the equator and OP perpendicular at OA. Then I need to find A' of longitude-20 and latitude >30 but I need to calculate the value.

Update How to determine the latitude of A' ?

In the next pictures, H is the projection of Q on the plane (OPA). It's possible to calculate PH with two sides (OP=1 and OH=0.866) I find 1.001. Then the lines PH and OA have an intersection at the point I. Now i calculate OI=1.238 and PI=1.591. J is a point of the line OA' and I is the projection of J on the plane (OPA). P, Q, J are aligned and IJ= 0.795. IJ/OI=0.641=tan(32.7). The latitude of A' is 32.7. Now I can draw the circle of radius 1 that passes through P and A' with center O.

Now I need to draw the circle of center O and radius 1. The circle passes through P and A' but also by Q. I draw the diameter POP' and QOQ'.

Todo : Calculus to determine correctly the latitude of A', cross product to determine N'. A macro to place a point with longitude and latitude.

In my code, I redefined personal macro with names that I understand correctly.

\documentclass[11pt]{scrartcl}
\usepackage{tikz}
\usetikzlibrary{calc}
\tikzset{%
to path={%
($(\tikztostart)!-#1!(\tikztotarget)$)--($(\tikztotarget)!-#2!(\tikztostart)$)%
}

\tikzset{%
mark coordinate/.style={inner sep=0pt,outer sep=0pt,minimum size=2pt,
fill=black,circle}%
}

\newcommand\pgfmathsinandcos[3]{%
\pgfmathsetmacro#1{sin(#3)}%
\pgfmathsetmacro#2{cos(#3)}%
}
\newcommand\LongitudePlane[2][current plane]{%
\pgfmathsinandcos\sinEl\cosEl{\Elevation} % elevation
\pgfmathsinandcos\sint\cost{#2} % azimuth
\tikzset{#1/.estyle={cm={\cost,\sint*\sinEl,0,\cosEl,(0,0)}}}
}
\newcommand\LatitudePlane[2][current plane]{%
\pgfmathsinandcos\sinEl\cosEl{\Elevation} % elevation
\pgfmathsinandcos\sint\cost{#2} % latitude
\pgfmathsetmacro\ydelta{\cosEl*\sint}
\tikzset{#1/.estyle={cm={\cost,0,0,\cost*\sinEl,(0,\ydelta)}}} %
}
\newcommand\DrawLongitudeCircle[1]{
\LongitudePlane{#1}
\tikzset{current plane/.prefix style={scale=\R}}
\pgfmathsetmacro\angVis{atan(sin(#1)*cos(\Elevation)/sin(\Elevation))} %
\draw[current plane,thin,black]  (\angVis:1)     arc (\angVis:\angVis+180:1);
\draw[current plane,thin,dashed] (\angVis-180:1) arc (\angVis-180:\angVis:1);
}%

\newcommand\DrawLatitudeCircle[1]{
\LatitudePlane{#1}
\tikzset{current plane/.prefix style={scale=\R}}
\pgfmathsetmacro\sinVis{sin(#1)/cos(#1)*sin(\Elevation)/cos(\Elevation)}
\pgfmathsetmacro\angVis{asin(min(1,max(\sinVis,-1)))}
\draw[current plane,thin,black] (\angVis:1) arc (\angVis:-\angVis-180:1);
\draw[current plane,thin,dashed] (180-\angVis:1) arc (180-\angVis:\angVis:1);
}%

\newcommand\DrawPointOnSphere[3]{%
\pgfmathsinandcos\sinLoM\cosLoM{#1}
\pgfmathsinandcos\sinLaM\cosLaM{#2}
}

\begin{document}
\null\vfill
\begin{center}
\begin{tikzpicture}
\def\Elevation{25} % elevation angle
\def\angleLongitudeP{-110} % longitude of point P
\def\angleLongitudeQ{-45} % longitude of point Q
\def\angleLatitudeQ{30} % latitude  Q    ; 0 latitude of P
\def\angleLongitudeA{-20} % longitude of point A

\pgfmathsetmacro\H{\R*cos(\Elevation)} % distance to north pole
\LongitudePlane[PLongitudePlane]{\angleLongitudeP}
\LongitudePlane[QLongitudePlane]{\angleLongitudeQ}
\LongitudePlane[ALongitudePlane]{\angleLongitudeA}

\fill[ball color=white!10] (0,0) circle (\R); % 3D lighting effect
\coordinate (O) at (0,0);
\coordinate[] (N) at (0,\H);
\coordinate[] (S) at (0,-\H);

\DrawLongitudeCircle{\angleLongitudeP} % PLongitudePlane
\DrawLongitudeCircle{\angleLongitudeQ} % QLongitudePlane
\DrawLongitudeCircle{\angleLongitudeA}
\DrawLatitudeCircle{\angleLatitudeQ}
\DrawLatitudeCircle{0} % equator
\DrawLongitudeCircle{0}
%setup coordinates P and Q
\path[ALongitudePlane] (0:\R) coordinate (A);
\path[ALongitudePlane] (32.5:\R) coordinate (A');
\path[ALongitudePlane] (122.5:\R) coordinate (N');
\path[PLongitudePlane] (0:\R) coordinate (P);
\draw[dashed,add= 1 and 0] (O) to  (P);
\path[QLongitudePlane] (\angleLatitudeQ:\R) coordinate (Q);
\draw[dashed,add= 1 and 0] (O) to  (Q) ;
\path[QLongitudePlane] (0:\R) coordinate (B);
\draw [dashed] (O) --  (B) ;
\draw [dashed] (O) --  (N) ;

\foreach \v in {A,O,N,S,P,Q,A',B,N'} {\coordinate[mark coordinate] (v) at (\v);
\node [above] at (\v) {\v};}
\begin{scope}[ x={(P)}, y={(A')}, z={(N')}]
\draw[dashed,fill opacity=.3] circle (1);
\draw[blue] ( 0:1) arc (0:68:1) ;
\draw[] ( 68:1) arc (68:115:1) ;
\draw[] (-55:1) arc (-55:0:1);
\draw[red,->](0,0,0)--(0,0,1);
\draw[red,->](0,0,0)--(0,1,0);
\draw[red,->](0,0,0)--(1,0,0);
\end{scope}
\end{tikzpicture}
\end{center}
\vfill

\end{document}

• Really nice answer! Mar 27, 2012 at 22:56
• Thanks Gonzalo but if I have enough time it will be interesting to write some macros. The paper of "cahier gutemberg" is very interesting but with metapost. I hope to translate the macro from metapost to tikz ! Mar 27, 2012 at 23:00
• I'll be looking forward to seeing those macros. Mar 27, 2012 at 23:13
• The french article is available in english as a TUGboat article tug.org/tugboat/tb30-1/tb94roegel-spheres.pdf Apr 2, 2012 at 5:03
• I just started drawing on spheres with tikz and it would be really nice to have a function/command to draw geodesics on the sphere (i.e. arbitrary points P and Q) - have you made any progress in translating the macros @AlainMatthes ? That would be really neat. Oct 30, 2014 at 16:05

The trick is to rotate the coordinate system. This bit of code shows the great circle passing through your particular values for P and Q, as well as a blue arc from P to Q.

\begin{scope}[rotate around={30:(0,0)}]
\DrawLatitudeCircle[\R]{11}
\draw[current plane,blue,thick] (240:1) arc (240:310:1);
\end{scope}


(I dropped a couple of your drawing commands to make the result a bit clearer. Obviously all the parameters are specific to this problem and, less obviously, were chosen visually.)

• Are you sure of the method ? If you take Q with longitude 0 and altitude 30, I think you get a problem ! What is exactly the rotation of 30 degree of the equator ? And last point, if you take P with longitude 135 and altitude 0 then Q,O,P,N and S are on the same plane, the arc PQ contains N Mar 26, 2012 at 18:46
• I confess that I did not bother to work out all the trig. I just rotated the equator until it was parallel to the great circle that passed through P and Q. I then futzed with the arc parameters to get the right section of the great circle. Mar 26, 2012 at 20:01
• "Is there a possibility to make an arc from P to Q with the center O? ?" but the blue arc is not in the plane OPQ because O is not the center of the circle. Mar 27, 2012 at 6:23
• I added too a visual answer and if you compare the circle of center O that passes through P and Q, you can see the problem in your picture. Mar 27, 2012 at 7:19
• Yes, my answer is not a great circle. I blithely overlooked the need for a great circle solution and opted for one that looked reasonable. Apr 2, 2012 at 5:00

Here is a different algorithm which is faster and it is more flexible because it uses "\pgfplotfunction" instead of plotting each point at the time. The algorithm is based on the post:

Arc between two tips of vectors in 3D

Basially the equation posted by Rahul which was obtained from the

Slerp Formula. The formula is easy to code into a "\pgfplotfunction" .

I use the same test on my post above with arcs on a sphere, but the macro is different (renamed as \myarctwo) and it is here:

  \newcommand\myarctwo[9]
{
%center
\def\ox{#1};
\def\oy{#2};
\def\oz{#3};

%start
\def\ax{#4};
\def\ay{#5};
\def\az{#6};

%end
\def\bx{#7}
\def\by{#8}
\def\bz{#9}

% parameter t in [0,1], s is a scale
\pgfmathsetmacro\s{divide(1,\tempa}

% shift coordinates
\pgfmathsetmacro\aox{\ax-\ox}
\pgfmathsetmacro\aoy{\ay-\oy}
\pgfmathsetmacro\aoz{\az-\oz}
\pgfmathsetmacro\boxo{\bx-\ox}
\pgfmathsetmacro\boy{\by-\oy}
\pgfmathsetmacro\boz{\bz-\oz}
\pgfmathsetmacro\bax{\bx-\ax}
\pgfmathsetmacro\bay{\by-\ay}
\pgfmathsetmacro\baz{\bz-\az}

% find radius r, actually we want r^2
\pgfmathsetmacro\r{\aox*\aox+\aoy*\aoy+\aoz*\aoz}

% find angle  between the vectors O->A and O->B
\pgfmathsetmacro\dotab{\aox*\boxo + \aoy*\boy + \aox*\boz}
\pgfmathsetmacro\cosphi{\dotab/\r}
\pgfmathsetmacro\sinphi{sqrt(1.0-(\cosphi * \cosphi))}
\pgfmathsetmacro\phia{acos(\cosphi)}

\pgfmathsetmacro\xap{divide(\aox,\sinphi)}
\pgfmathsetmacro\yap{divide(\aoy,\sinphi}
\pgfmathsetmacro\zap{divide(\aoz,\sinphi}
\pgfmathsetmacro\xbp{divide(\boxo,\sinphi}
\pgfmathsetmacro\ybp{divide(\boy,\sinphi}
\pgfmathsetmacro\zbp{divide(\boz,\sinphi}

\begin{scope}[color=\tempb]
\pgfplothandlerlineto
\pgfplotfunction{\t}{0,1,...,\tempa}
{\pgfpointxyz {\ox + \xap*sin((1-\s*\t)*\phia) + \xbp*sin(\s*\t*\phia)}
{\oy + \yap*sin((1-\s*\t)*\phia) + \ybp*sin(\s*\t*\phia)}
{\oz + \zap*sin((1-\s*\t)*\phia) + \zbp*sin(\s*\t*\phia)}}
\pgfusepath{stroke}
\end{scope}
}


Here is the plot with 200 points:

One thing that confuses me much in tikz/pgfplots is the lack of a clear function to draw an arc between two points with a common center of curvature.

As far as I can see the arcs shown here are all either great circles or arcs with constant altitude (parallel to the equator). I took this problem and thought first about how to draw an arc in general in 3D with a fixed center of curvature. That is, we need thee points $A$, $B$, and $O$ the center of curvature of the arc. Initially I wanted to come up with a mathematical equation which does not depends on how my coordinates are set up and I could not find it. I posted the problem in the mathematics site of Stack Exchange and the next day I came up with a solution. The solution of that problem is here:

arc between two points with a center of curvature

Since the maximum number of arguments taken by a "\newcommand" macro is 9, and I wanted 11 parameters (3 points each with 3 coordinates, number of points in arc, and color) I created two macros as follows :

\newcommand\pointscolors[2]
{
\def\tempa{#1}
\def\tempb{#2}
}
\newcommand\myarc[9]
{
%center
\def\ox{#1};
\def\oy{#2};
\def\oz{#3};
\coordinate (O) at (\ox,\oy,\oz);

%start
\def\ax{#4};
\def\ay{#5};
\def\az{#6};
\coordinate (A) at (\ax,\ay,\az);

%end
\def\bx{#7}
\def\by{#8}
\def\bz{#9}
\coordinate (B) at (\bx,\by,\bz);

\draw[] (O) --(A) node[anchor=west] {$A$};
\draw[] (O) --(B) node[anchor=west] {$B$};
%\node[anchor=east] at (O) {$O$};

\draw[fill=\tempb] (O) circle (2pt);
\draw[fill=\tempb] (A) circle (2pt);
\draw[fill=\tempb] (B) circle (2pt);

\foreach \t in {0,1,...,\tempa}
{%
% cosine and sine

% paramter s in [0,1]
\pgfmathsetmacro\scl{divide(1,\tempa}
\pgfmathsetmacro\s{\scl*\t}

% shift coordinates
\pgfmathsetmacro\aox{\ax-\ox}
\pgfmathsetmacro\aoy{\ay-\oy}
\pgfmathsetmacro\aoz{\az-\oz}
\pgfmathsetmacro\boxo{\bx-\ox}
\pgfmathsetmacro\boy{\by-\oy}
\pgfmathsetmacro\boz{\bz-\oz}
\pgfmathsetmacro\bax{\bx-\ax}
\pgfmathsetmacro\bay{\by-\ay}
\pgfmathsetmacro\baz{\bz-\az}

\coordinate (AO) at (\aox, \aoy, \aoz );
\coordinate (BO) at (\boxo, \boy, \boz );

\pgfmathsetmacro\r{sqrt(\aox*\aox+\aoy*\aoy+\aoz*\aoz)}

% find p
\pgfmathsetmacro\px{\aox+\s*(\boxo-\aox}
\pgfmathsetmacro\py{\aoy+\s*(\boy-\aoy)}
\pgfmathsetmacro\pz{\aoz+\s*(\boz-\aoz)}

% find ||p||
\pgfmathsetmacro\p{sqrt(\px*\px + \py*\py + \pz*\pz)}

% find ||u||
\pgfmathsetmacro\ux{divide(\px,\p)}
\pgfmathsetmacro\uy{divide(\py,\p)}
\pgfmathsetmacro\uz{divide(\pz,\p)}

% find the solution x
\pgfmathsetmacro\xx{\r*\ux}
\pgfmathsetmacro\xy{\r*\uy}
\pgfmathsetmacro\xz{\r*\uz}

\pgfmathsetmacro\x{\xx + \ox}
\pgfmathsetmacro\y{\xy + \oy}
\pgfmathsetmacro\z{\xz + \oz}

\coordinate (X) at (\x,\y, \z);

\node[color=\tempb] at (X) {.};
}
}


Note that this macro does what my equations in the find arc between two tips of vectors in 3D suggests.

The macro goes into the LaTeX preamble. Then in the main document I used a test to call it. Here is the test:

\tdplotsetmaincoords{10}{100}
\begin{tikzpicture}[scale=1.0, tdplot_main_coords]

% axes and origin of coordinate system
\coordinate (Xa) at (4,0,0);
\coordinate (Ya) at (0,4,0);
\coordinate (Za) at (0,0,22);
\coordinate (C) at (0,0,0);

% draw sphere
\def\R{4};
\fill[ball color=white!10] (C) circle (\R); % 3D lighting effect

% set color and number of points
\pointscolors[100][red];

% call macro "myarc"
\myarc{0}{0}{3}{3}{1}{0.45}{-3}{1}{0.45}

% draw coordinate axes
\draw[-latex] (C)--(Xa) node[yshift=-2mm] {$X$};
\draw[-latex] (C)--(Ya) node[anchor=west] {$Y$};
\draw[-latex] (C)--(Za) node[anchor=south] {$Z$};

\end{tikzpicture}


Then the figure is here:

I created another plot to help explain why the shortest path between two points in a sphere is along a great circle. This was motivated by the stack exchange post: shortest path in a sphere

The figure for that post is next.

and the code for it is here:

 \tdplotsetmaincoords{25}{60}
\begin{tikzpicture}[scale=1.0, tdplot_main_coords]

\coordinate (Xa) at (4,0,0);
\coordinate (Ya) at (0,4,0);
\coordinate (Za) at (0,0,8);
\coordinate (C) at (0,0,0);

% draw sphere
\def\R{4};
\fill[ball color=white!10] (C) circle (\R); % 3D lighting effect

%\foreach \t in {0,4,1}
%{
%\myarc{0}{0}{\t}{0}{3}{2.645751311064591}{0}{-3}{2.645751311064591};
%}

\pointscolors{200}{green};
\myarc{0}{0}{0}{0}{3}{2.645751311064591}{0}{-3}{2.645751311064591};
\pointscolors{200}{blue};
\myarc{0}{0}{0.5}{0}{3}{2.645751311064591}{0}{-3}{2.645751311064591};
\pointscolors{200}{red};
\myarc{0}{0}{1.0}{0}{3}{2.645751311064591}{0}{-3}{2.645751311064591};
\pointscolors{200}{brown};
\myarc{0}{0}{1.5}{0}{3}{2.645751311064591}{0}{-3}{2.645751311064591};
\pointscolors{200}{orange};
\myarc{0}{0}{2.0}{0}{3}{2.645751311064591}{0}{-3}{2.645751311064591};
\pointscolors{200}{orange};
%\myarc{0}{0}{2.645751311064591}{0}{3}{2.645751311064591}{0}{-3}{2.645751311064591};
%\pointscolors{100}{yellow};

% draw coordinate axes
\draw[-latex] (C)--(Xa) node[yshift=-2mm] {$X$};
\draw[-latex] (C)--(Ya) node[anchor=west] {$Y$};
\draw[-latex] (C)--(Za) node[anchor=south] {$Z$};

\end{tikzpicture}


The argument for the shortest path is that I am using 200 points on each arc. The green arc corresponds to a great circle and the points are all squeezed. The other arcs grow in length as the center of curvature moves up from the origin.

The plot of points by using "node" is no elegant at all. The number of points is hard coded as well. I do not have the high level specifications to develop low level code. If anyone can help to improve this function this could be very beneficial for all LaTeX community..

Thanks.

• use low level \pgfpatharcto and variants instead of the TikZ frontend especially the precomputed one Nov 2, 2015 at 21:06
• Do you mean to write a macro using \pgfpatharcto or there is already a function that does what we want called \pgfpatharcto? Could you please be more specific? Looking at it, it looks as a 2D function. Is there 3D examples of this? Nov 2, 2015 at 21:13
• they are in the manual explained in detail Nov 3, 2015 at 0:58
• @percusse : from the manual. \pgfpatharcto is a 2D function, the arcs drawn here are 3D. Here is the prototype for \pgfpatharcto (from the manual). \pgfpatharc{ start angle }{ end angle }{ radius and y-radius } Looking at the code again I ask what lines can I change to low label. Of course every line with "node" I can move out, labels and axes I can move out of the code. But what is the low level equivalent of: \pgfmathsetmacro ? is "\def" better and faster? The key point here is how to store the points in memory and plot them with a single instruction instead of ploting each point at a time Nov 3, 2015 at 13:41
• Incomplete \ifx; all text was ignored after line 114.<inserted text> \fi <*> sphere2 This is the error when I run your code. Jan 15, 2023 at 16:14

For a comparison, I add an Asymptote way using built-in arc in the module three. Note that the normal of the arc plane is not necessary to calculate. In case one want to use the normal for decorations, just compute n=unit(cross(P,Q));.

Dashed lines are not given to show the figure naturally. I never seen any contexts that needs the intersecting point of visible and invisible line. Of course we can make the hidden line dashed with some kind of hacks or tricks.

// http://asymptote.ualberta.ca/
import three;
unitsize(1cm);
currentprojection=orthographic(2,1,.6,zoom=.9);
real r=3;
draw(scale3(r)*unitsphere,lightyellow+opacity(.2));

// 2 points on the sphere
triple P=r*expi(-30,-30), Q=r*expi(60,70);

// 2 arc on the sphere connecting P and Q
path3 aPQ=arc(O,P,Q);
draw(aPQ,blue,Arrow3);
path3 aPQcw=arc(O,P,Q,CW);
draw(reverse(aPQcw),red,Arrow3);

dot(P^^Q);
dot("$O$",align=plain.S,O);
draw(Label("$x$",EndPoint),O--(r+4)*X);
draw(Label("$y$",EndPoint),O--(r+1)*Y);
draw(Label("$z$",EndPoint),O--(r+1)*Z);


Above, Alain Matthes mentioned that "To give a correct answer, we need to define cross product ...", and that sounds like my idea of fun this evening, so let's get at it.

We have two points on a sphere, and we want to draw an arc of a great circle between them. For simplicity's sake, let's say we're on the unit sphere and that the points are not co-linear through the center. Let's think of them as vectors A and B.

tikz-3dplot will do all the work for you with \tdplotdrawarc if your points are (rotated into) the xy-plane.

We find the cross product C of A and B, then we rotate the space such that the Z axis is co-linear with C, by defined the Euler angles for the \tdplotsetrotatedcoords command.

Next challenge is to find the angles of A and B in that rotated plane, measured counter-clockwise from the x-axis (and figure out which angle is first).

To do this, we find out what the x and y axes would be in the rotated plane using the \tdplottransformrotmain command, and the two measurements remove any quadrant ambiguity.

First comes the pretty picture:

And then comes the tricky part - understanding my code, with the latex-isms, such as using units for \lengthtest

This will help:

Here we go:

\documentclass[12pt]{amsart}
\usepackage{amsmath, amsthm, amsfonts, amssymb, latexsym, ifthen, pgfplots, tikz-3dplot}
% posted here: https://tex.stackexchange.com/questions/46850/how-can-i-draw-an-arc-from-point-a-b-on-a-3d-sphere-in-tikz

\begin{document}

% there's got to be a better way to do this.
\newcommand{\Normalize}[3]
{
\pgfmathsetmacro{\normyn}{sqrt(#1*#1+#2*#2+#3*#3)}
\pgfmathsetmacro{\normx}{#1/\normyn}\pgfmathsetmacro{\normy}{#2/\normyn}\pgfmathsetmacro{\normz}{#3/\normyn}
}

% calculate the counterclockwise angle of a vector of length 1 in the rotated xy plane.
\newcommand{\toAngle}[3]
{
\tdplottransformrotmain{1}{0}{0}
\pgfmathsetmacro\xa{acos(\tdplotresx *#1 + \tdplotresy* #2 + \tdplotresz* #3)}
\tdplottransformrotmain{0}{1}{0}
\pgfmathsetmacro\ya{acos(\tdplotresx *#1 + \tdplotresy* #2 + \tdplotresz* #3)}
\pgfmathsetmacro\normySum{round(\xa+\ya)}
\pgfmathsetmacro\normyDiff{round(\xa-\ya )}
\ifthenelse{\lengthtest{\normySum pt = 270pt}} {
\pgfmathsetmacro\normyAngle{\ya+90}
}{
\ifthenelse{\lengthtest{\normyDiff pt = -90pt}} {
\pgfmathsetmacro\normyAngle{360-\xa }
}{
\pgfmathsetmacro\normyAngle{\xa }
}
}
}

\newcommand{\drawArc}[8]
{
\Normalize{#1}{#2}{#3}
\pgfmathsetmacro{\pax}{\normx}\pgfmathsetmacro{\pay}{\normy}    \pgfmathsetmacro{\paz}{\normz}

\Normalize{#4}{#5}{#6}
\pgfmathsetmacro{\pbx}{\normx}\pgfmathsetmacro{\pby}{\normy}    \pgfmathsetmacro{\pbz}{\normz}

% take the cross product and normalize it
\tdplotcrossprod(\pax,\pay,\paz)(\pbx,\pby,\pbz)

% calculate the rotation that maps the z axis onto the cross product
\tdplotsetrotatedcoords{atan2(\tdplotresy,\tdplotresx)}{atan2(sqrt(\tdplotresx*\tdplotresx+\tdplotresy*\tdplotresy),\tdplotresz)}{0.0}

% calculate the counterclockwise angles from the rotated x axis to each vector, then order them increasing.
\toAngle{\pax}{\pay}{\paz}
\pgfmathsetmacro\xangle{\normyAngle}

\toAngle{\pbx}{\pby}{\pbz}
\pgfmathsetmacro\yangle{\normyAngle}

\ifthenelse{\lengthtest{\xangle pt < \yangle pt}} {
\pgfmathsetmacro\first{\xangle}
\pgfmathsetmacro\second{\yangle}
}{
\pgfmathsetmacro\first{\yangle}
\pgfmathsetmacro\second{\xangle}
}
\pgfmathsetmacro\delta{\second  - \first }
\ifthenelse{\lengthtest{\delta pt > 180 pt}} {
\pgfmathsetmacro\s{\first  }
\pgfmathsetmacro\first{\second-360}
\pgfmathsetmacro\second{\s  }
}
% draw the arc at radius R from the first angle to the second

\tdplotdrawarc[tdplot_rotated_coords,#8]{(0,0,0)}{#7}{\first }{\second }{}{}
}

% spherical triangle

\tdplotsetmaincoords{60}{130}
\begin{tikzpicture}[scale=5,tdplot_main_coords]
\shade[ball color = gray!10, opacity = 0.1] (0,0,0) circle (1cm);
\pgfmathsetmacro{\ax}{.9}\pgfmathsetmacro{\ay}{.2}\pgfmathsetmacro{\az}{.2}
\pgfmathsetmacro{\bx}{.2}\pgfmathsetmacro{\by}{.9}\pgfmathsetmacro{\bz}{.2}
\pgfmathsetmacro{\cx}{.4}\pgfmathsetmacro{\cy}{.2}\pgfmathsetmacro{\cz}{.9}
\end{tikzpicture}

\clearpage

% let's see that math
\tdplotsetmaincoords{60}{130}
\begin{tikzpicture}[scale=7,tdplot_main_coords]
\draw[->,black] (0,0,0) -- (1,0,0) node[anchor=west]{$\vec{x}$};
\draw[->,black] (0,0,0) -- (0,1,0) node[anchor=west]{$\vec{y}$};
\draw[->,black] (0,0,0) -- (0,0,.5) node[anchor=west]{$\vec{z}$};

\Normalize{0.3}{0.7}{0.5}
\pgfmathsetmacro{\cx}{\normx}\pgfmathsetmacro{\cy}{\normy}\pgfmathsetmacro{\cz}{\normz}

\draw[->,blue!50!black] (0,0,0) -- (\cx,\cy,\cz) node[anchor=west]{$(x,y,z)$};
\draw[->,dashed,blue!50!black] (0,0,0) -- node[above] {$\sqrt{x^2+y^2}$}  (\cx,\cy,0) node[anchor=west]{};
\draw[dashed,blue!50!black] (\cx,\cy,0) -- node[right] {$z$}  (\cx,\cy,\cz) ;
\draw[dashed,blue!50!black] (\cx,0,0) -- node[right] {$y$}  (\cx,\cy,0) ;
\path[dashed,blue!50!black] (0,0,0) -- node[left] {$x$}  (\cx,0,0) ;

\drawArc{0}{0}{1}{\cx}{\cy}{\cz}{.1}{}
\path[dashed,blue!50!black] (0,0,0) -- node  [sloped] {$\tan^{-1}(\sqrt{x^2+y^2}/z)$} ({\cx/1.5},{\cy/1.5},{(1+\cz)/1.5}) ;

\drawArc{1}{0}{0}{\cx}{\cy}{0}{.1}{}
\path[dashed,blue!50!black] (0,0,0) -- node  [sloped] {$\tan^{-1}(y/x)$} ({(1+\cx)/1.5},{\cy/1.5},{0/1.5}) ;
\end{tikzpicture}

\end{document}