I am creating a document explaining the concept of a solid angle in Astronomy to students. I would like to create a graphic as shown below in TikZ to illustrate the concept clearly, but I have no idea where to start. It is supposed to illustrate a sphere of radius r and a solid D whose projection onto the sphere gives the area A. Any help is appreciated!
-
Surely we have done this already? tex.stackexchange.com/questions/108915/…– ThrustonCommented Jul 9, 2018 at 9:17
-
The lines of projection and labelling of the solid before projection are not present, and the formatting is quite different since my solid is outside the sphere.– TeyyfCommented Jul 9, 2018 at 9:52
-
All you need to do is to draw a circle on a sphere. This can be done with pgfplots or without.– user121799Commented Jul 9, 2018 at 10:25
Add a comment
|
1 Answer
\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{backgrounds}
\usepackage{tikz-3dplot}
\makeatletter
%along z axis
\define@key{z sphericalkeys}{radius}{\def\myradius{#1}}
\define@key{z sphericalkeys}{theta}{\def\mytheta{#1}}
\define@key{z sphericalkeys}{phi}{\def\myphi{#1}}
\tikzdeclarecoordinatesystem{z spherical visible}{%
\setkeys{z sphericalkeys}{#1}%
\pgfmathsetmacro{\Xtest}{cos(90-\tdplotmaintheta)*cos(\tdplotmainphi-90)*cos(\mytheta)*cos(\myphi)
+cos(90-\tdplotmaintheta)*sin(\tdplotmainphi-90)*cos(\mytheta)*sin(\myphi)
+sin(90-\tdplotmaintheta)*sin(\mytheta)}
% \Xtest is the projection of the coordinate on the normal vector of the visible plane
\pgfmathsetmacro{\ntest}{ifthenelse(\Xtest<0,0,1)}
\ifnum\ntest=0
\pgfmathsetmacro{\myx}{\myradius*cos(\mytheta)*cos(\myphi)*\raarot
+\myradius*cos(\mytheta)*sin(\myphi)*\rabrot+\myradius*sin(\mytheta*\racrot}
\pgfmathsetmacro{\myy}{\myradius*cos(\mytheta)*cos(\myphi)*\rbarot
+\myradius*cos(\mytheta)*sin(\myphi)*\rbbrot+\myradius*sin(\mytheta*\rbcrot}
\pgfpoint{\RadiusSphere*cos(atan2(\myy,\myx))*1cm}{\RadiusSphere*sin(atan2(\myy,\myx))*1cm}
\else
\pgfpointxyz{\myradius*cos(\mytheta)*cos(\myphi)}{%
\myradius*cos(\mytheta)*sin(\myphi)}{\myradius*sin(\mytheta)}
\fi
}
\tikzdeclarecoordinatesystem{z spherical invisible}{%
\setkeys{z sphericalkeys}{#1}%
\pgfmathsetmacro{\Xtest}{cos(90-\tdplotmaintheta)*cos(\tdplotmainphi-90)*cos(\mytheta)*cos(\myphi)
+cos(90-\tdplotmaintheta)*sin(\tdplotmainphi-90)*cos(\mytheta)*sin(\myphi)
+sin(90-\tdplotmaintheta)*sin(\mytheta)}
% \Xtest is the projection of the coordinate on the normal vector of the visible plane
%\typeout{\raarot,\rbarot,\rabrot,\rbbrot,\racrot, \rbcrot}
\pgfmathsetmacro{\ntest}{ifthenelse(\Xtest<0,0,1)}
\ifnum\ntest=1
\pgfmathsetmacro{\myx}{\myradius*cos(\mytheta)*cos(\myphi)*\raarot
+\myradius*cos(\mytheta)*sin(\myphi)*\rabrot+\myradius*sin(\mytheta*\racrot}
\pgfmathsetmacro{\myy}{\myradius*cos(\mytheta)*cos(\myphi)*\rbarot
+\myradius*cos(\mytheta)*sin(\myphi)*\rbbrot+\myradius*sin(\mytheta*\rbcrot}
\pgfpoint{\RadiusSphere*cos(atan2(\myy,\myx))*1cm}{\RadiusSphere*sin(atan2(\myy,\myx))*1cm}
\else
\pgfpointxyz{\myradius*cos(\mytheta)*cos(\myphi)}{%
\myradius*cos(\mytheta)*sin(\myphi)}{\myradius*sin(\mytheta)}
\fi
}
%%%%%%%%%%%%%%%%%
\makeatother
% decoration
\begin{document}
\pgfmathsetmacro{\RadiusSphere}{3}
\foreach \X in {30}
{\begin{tikzpicture}
% \path[use as bounding box] ({-1.2*\RadiusSphere},{-1.2*\RadiusSphere}) rectangle
% ({1.2*\RadiusSphere},{1.2*\RadiusSphere});
\shade[ball color = gray!40, opacity = 0.5] (0,0) circle (\RadiusSphere);
\tdplotsetmaincoords{110}{\X}
\begin{scope}[tdplot_main_coords,samples=60]
%
% \draw[-latex,orange] (0,0,0) -- (z spherical cs: radius=\RadiusSphere,
% phi={\tdplotmainphi-90},theta={90-\tdplotmaintheta});
% \draw[-latex] (0,0,0) -- (\RadiusSphere,0,0) node[below]{$x$};
% \draw[-latex] (0,0,0) -- (0,\RadiusSphere,0) node[left]{$y$};
% \draw[-latex] (0,0,0) -- (0,0,\RadiusSphere) node[left]{$z$};
\pgfmathtruncatemacro{\Dis}{ifthenelse(\X<50,1,0)+ifthenelse(\X>130,1,0)}
\ifnum\Dis=0
\else
\draw[opacity=0.3,fill opacity=0.2,fill=blue] plot[smooth,variable=\x,domain=-180:180]
(z spherical invisible cs: radius=\RadiusSphere,phi={15*sin(\x)},theta={15*cos(\x)});
\fi
\pgfmathtruncatemacro{\Dis}{ifthenelse(\X<230,1,0)+ifthenelse(\X>320,1,0)}
\ifnum\Dis=0
\else
\draw[fill opacity=0.5,fill=blue] plot[smooth,variable=\x,domain=-180:180]
(z spherical visible cs: radius=\RadiusSphere,phi={15*sin(\x)},theta={15*cos(\x)});
\fi
\coordinate (C) at (z spherical visible cs: radius=2.5*\RadiusSphere,phi=0,theta=0);
\coordinate (CT) at (z spherical visible cs:
radius=2.5*\RadiusSphere,phi={-15*sin(\X)},theta={15*cos(\X)});
\coordinate (CB) at (z spherical visible cs:
radius=2.5*\RadiusSphere,phi={15*sin(\X/2)},theta={-15*cos(\X/2)});
% \draw[gray] plot[smooth,variable=\x,domain=-180:180]
% (z spherical visible cs: radius=2.5*\RadiusSphere,phi={15*sin(\x)},theta={15*cos(\x)});
\draw[black] plot[smooth,variable=\x,domain=-180:180]
(z spherical visible cs: radius=\RadiusSphere,phi={90},theta={\x});
\draw[gray] plot[smooth,variable=\x,domain=-180:180]
(z spherical invisible cs: radius=\RadiusSphere,phi={90},theta={\x});
\end{scope}
\begin{scope}[on background layer]
\shade[ball color = blue!40, opacity = 1] (C) circle (0.66*\RadiusSphere);
\draw (0,0) -- (CT) (0,0) -- (CB);
\end{scope}
\end{tikzpicture}
}
\end{document}