How to draw this arc (intersection of a plane and a sphere) automatically?

Based on the answer at here How can I get correct the point A and B automatically in this picture?, I tried with the sphere

\documentclass[tikz,border=1mm, 12 pt]{standalone}
\usepackage{tikz-3dplot}
\usetikzlibrary{backgrounds}
\begin{document}
\tdplotsetmaincoords{70}{50}
\begin{tikzpicture}[scale=1,tdplot_main_coords,declare function={R=25*sqrt(78)*(1/52);r=7*sqrt(3)*(1/3);
alpha1(\th,\ph,\b)=\ph-asin(cot(\th)*tan(\b));%
alpha2(\th,\ph,\b)=-180+\ph+asin(cot(\th)*tan(\b));%
beta1(\th,\ph,\a)=90+atan(cot(\th)/sin(\a-\ph));%
beta2(\th,\ph,\a)=270+atan(cot(\th)/sin(\a-\ph));%
}]
\path
coordinate (O) at (0,0,0)
coordinate (A) at (-3/2, {-13*sqrt(3)*(1/6)}, 0)
coordinate (B) at (3/2, {-13*sqrt(3)*(1/6)}, 0)
coordinate (C) at (4, {(1/3)*sqrt(3)}, 0)
coordinate (S) at (0, 0, {(1/3)*sqrt(78)})
coordinate (T) at  (0, 0, {-23*sqrt(78)*(1/156)});
\begin{scope}[tdplot_screen_coords, on background layer]
\draw[thick] (T) circle (R);
\end{scope}

\begin{scope}[canvas is xy plane at z={0}]
\draw[dashed] (O) circle (r);
\draw[thick] ({alpha1(\tdplotmaintheta,\tdplotmainphi,{atan(r/R)})}:r) arc({alpha1(\tdplotmaintheta,\tdplotmainphi,{atan(r/R)})}: {alpha2(\tdplotmaintheta,\tdplotmainphi,{atan(r/R)})}:r) ;
\end{scope}
\begin{scope}[on background layer]
\foreach \v/\position in {T/above,O/below,A/below,B/below,C/below,S/right} {
\draw[draw =black, fill=black] (\v) circle (1.2pt) node [\position=0.2mm] {$\v$};
}
\end{scope}
\foreach \X in {A,B,C,O} \draw[dashed] (\X) -- (S);
\draw[dashed] (A) -- (B) -- (C) -- cycle;
\end{tikzpicture}
\end{document}


The result incorrect. How can I repair it automatically with this method?

I used another way.

\documentclass[tikz,border=1mm, 12 pt]{standalone}
\usepackage{fouriernc}
\usepackage{tikz-3dplot}
\usetikzlibrary{backgrounds}
\begin{document}
\tdplotsetmaincoords{70}{50}
\begin{tikzpicture}[scale=1,tdplot_main_coords,declare function={R=25*sqrt(78)*(1/52);r=7*sqrt(3)*(1/3);}]
\path
coordinate (O) at (0,0,0)
coordinate (A) at (-3/2, {-13*sqrt(3)*(1/6)}, 0)
coordinate (B) at (3/2, {-13*sqrt(3)*(1/6)}, 0)
coordinate (C) at (4, {(1/3)*sqrt(3)}, 0)
coordinate (S) at (0, 0, {(1/3)*sqrt(78)})
coordinate (T) at  (0, 0, {-23*sqrt(78)*(1/156)});
\begin{scope}[tdplot_screen_coords, on background layer]
\draw[thick] (T) circle (R);
\end{scope}
\begin{scope}[canvas is xy plane at z=0]
\draw[dashed] (\tdplotmainphi:r) arc(\tdplotmainphi:\tdplotmainphi+180:r);
\draw[thick] (\tdplotmainphi:r)  arc(\tdplotmainphi:\tdplotmainphi-180:r)
;
\end{scope}
\foreach \v/\position in {T/above,O/below,A/below,B/below,C/right,S/right} {
\draw[draw =black, fill=black] (\v) circle (1.2pt) node [\position=0.2mm] {$\v$};
}
\foreach \X in {A,B,C,O} \draw[dashed] (\X) -- (S);
\draw[dashed] (A) -- (B) -- (C) -- cycle;

\end{tikzpicture}
\end{document}


• The answer you link does it below the equator, your question is above the equator, so a fix is probably some reflection / addition of nice angles. Like setting alpha1(\th,\ph,\b)=90-(\ph-asin(cot(\th)*tan(\b))); will get you the right starting point on the right. Not sure about the left though. – Jānis Lazovskis Aug 31 '19 at 9:31

The linked answer works fine, and so does its application to your problem. Let me reconstruct what you are doing from the output. You draw a sphere with center at T, which is not the origin and a circle in the xy plane at the origin. What is the latitude of the circle? It is not atan(r/R), rather the latitude is given by atan(T_z/r), where T_z is the z component of T. We need a minus here because of the conventions, which is why there is a minus in \pgfmathsetmacro{\myel}{-atan(23*sqrt(78)*(1/156)/r)}. This may well be what Jānis Lazovskis's comment wants to tell us. This could be changed, if you ask me here. (The conventions were such that there was no minus needed in the other answer.) Altogether this works fine IMHO.

\documentclass[tikz,border=1mm, 12 pt]{standalone}
\usepackage{tikz-3dplot}
\usetikzlibrary{backgrounds}
\begin{document}
\tdplotsetmaincoords{70}{50}
\begin{tikzpicture}[scale=1,tdplot_main_coords,declare function={R=25*sqrt(78)*(1/52);r=7*sqrt(3)*(1/3);
alpha1(\th,\ph,\b)=\ph-asin(cot(\th)*tan(\b));%
alpha2(\th,\ph,\b)=-180+\ph+asin(cot(\th)*tan(\b));%
beta1(\th,\ph,\a)=90+atan(cot(\th)/sin(\a-\ph));%
beta2(\th,\ph,\a)=270+atan(cot(\th)/sin(\a-\ph));%
}]
\path
coordinate (O) at (0,0,0)
coordinate (A) at (-3/2, {-13*sqrt(3)*(1/6)}, 0)
coordinate (B) at (3/2, {-13*sqrt(3)*(1/6)}, 0)
coordinate (C) at (4, {(1/3)*sqrt(3)}, 0)
coordinate (S) at (0, 0, {(1/3)*sqrt(78)})
coordinate (T) at  (0, 0, {-23*sqrt(78)*(1/156)});
\begin{scope}[tdplot_screen_coords, on background layer]
\draw[thick] (T) circle (R);
\end{scope}

\begin{scope}[canvas is xy plane at z={0}]
\draw[dashed] (O) circle (r);
\pgfmathsetmacro{\myel}{-atan(23*sqrt(78)*(1/156)/r)}
\typeout{\myel}
\draw[thick] ({alpha1(\tdplotmaintheta,\tdplotmainphi,{\myel})}:r)
arc({alpha1(\tdplotmaintheta,\tdplotmainphi,{\myel})}:
{alpha2(\tdplotmaintheta,\tdplotmainphi,{\myel})}:r) ;
\end{scope}
\begin{scope}[on background layer]
\foreach \v/\position in {T/above,O/below,A/below,B/below,C/below,S/right} {
\draw[draw =black, fill=black] (\v) circle (1.2pt) node [\position=0.2mm] {$\v$};
}
\end{scope}
\foreach \X in {A,B,C,O} \draw[dashed] (\X) -- (S);
\draw[dashed] (A) -- (B) -- (C) -- cycle;
\end{tikzpicture}
\end{document}


An arguably more elegant solution is to redefine alpha1 and alpha2 in such a way that the minus is taken care of, and to extract the z component of T with a code.

\documentclass[tikz,border=1mm, 12 pt]{standalone}
\usepackage{tikz-3dplot}
\usetikzlibrary{backgrounds}
\makeatletter
% retrieves the 3D coordinates
\def\RawCoord(#1){\csname tikz@dcl@coord@#1\endcsname}%
\def\scalprod#1=#2.#3;{%
\edef\coordA{\RawCoord#2}%
\edef\coordB{\RawCoord#3}%
\pgfmathsetmacro\pgfutil@tmpa{scalarproduct({\coordA},{\coordB})}
\edef#1{\pgfutil@tmpa}}%
\makeatother
\newcommand{\spaux}[6]{(#1)*(#4)+(#2)*(#5)+(#3)*(#6)}
\pgfmathdeclarefunction{scalarproduct}{2}{% scalar product of two 3-vectors
\begingroup%
\pgfmathparse{\spaux#1#2}%
\pgfmathsmuggle\pgfmathresult\endgroup}
\begin{document}
\tdplotsetmaincoords{70}{50}
\begin{tikzpicture}[scale=1,tdplot_main_coords,declare function={R=25*sqrt(78)*(1/52);r=7*sqrt(3)*(1/3);
alpha1(\th,\ph,\b)=\ph+asin(cot(\th)*tan(\b));%
alpha2(\th,\ph,\b)=-180+\ph-asin(cot(\th)*tan(\b));%
beta1(\th,\ph,\a)=90+atan(cot(\th)/sin(\a-\ph));%
beta2(\th,\ph,\a)=270+atan(cot(\th)/sin(\a-\ph));%
}]
\path (0,0,0) coordinate (O)
(-3/2, {-13*sqrt(3)*(1/6)}, 0) coordinate (A)
(3/2, {-13*sqrt(3)*(1/6)}, 0) coordinate (B)
(4, {(1/3)*sqrt(3)}, 0) coordinate (C)
(0, 0, {(1/3)*sqrt(78)}) coordinate (S)
(0, 0, {-23*sqrt(78)*(1/156)}) coordinate (T)
(0,0,1) coordinate(Z);
\begin{scope}[tdplot_screen_coords, on background layer]
\draw[thick] (T) circle (R);
\end{scope}

\begin{scope}[canvas is xy plane at z={0}]
\draw[dashed] (O) circle (r);
\scalprod\myz=(T).(Z); % z component of T
\pgfmathsetmacro{\myel}{atan(-1*\myz/r)}
\draw[thick] ({alpha1(\tdplotmaintheta,\tdplotmainphi,{\myel})}:r)
arc({alpha1(\tdplotmaintheta,\tdplotmainphi,{\myel})}:
{alpha2(\tdplotmaintheta,\tdplotmainphi,{\myel})}:r) ;
\end{scope}
\begin{scope}[on background layer]
\foreach \v/\position in {T/above,O/below,A/below,B/below,C/below,S/right} {
\draw[draw =black, fill=black] (\v) circle (1.2pt) node [\position=0.2mm] {$\v$};
}
\end{scope}
\foreach \X in {A,B,C,O} \draw[dashed] (\X) -- (S);
\draw[dashed] (A) -- (B) -- (C) -- cycle;
\end{tikzpicture}
\end{document}

• I understood. Thank you very much. – minhthien_2016 Sep 1 '19 at 1:15
• Is this always true if circle on the plane z = 0 and coordinates S(x,y,z)? z \neq 0? – minhthien_2016 Sep 1 '19 at 10:15
• @minhthien_2016 What do you mean by "always true"? If you mean to ask whether or not alpha1 and alpha2 yield the domain for circles at a given latitude, then the answer is: "Yes, I hope they do.". – user194703 Sep 1 '19 at 15:09
• Yes. I tried 6 spheres. All of them are correct. Thank you very much. – minhthien_2016 Sep 2 '19 at 8:57