This is a long answer since there are good tools for spherical geometry scattered all around, so I created a few sections addressing those tools.
tikz-3dplot:especially tdplotdrawarc
I suggest to use \tdplotdrawarc . This is explained in the TikZ and PGF Manual. You need to define three angles $\alpha$, $\beta$ and $\gamma$ for the arc, theen the radius, origin, initial and final angle. I include here
and example with the angles used. With this example you can build new examples explaining other angle combinations.
\documentclass[12pt]{article}
\usepackage{amsmath}
\usepackage{enumerate}
\usepackage{tikz}
\usepackage{xcolor}
\usepackage{tikz-3dplot}
\usepackage{hyperref}
\usepackage{pgfplots}
\usetikzlibrary{calc,3d,intersections, positioning,intersections,shapes}
\newcommand{\InterSec}[3]{%
\path[name intersections={of=#1 and #2, by=#3, sort by=#1,total=\t}]
\pgfextra{\xdef\InterNb{\t}}; }
\begin{document}
\begin{center}
\begin{tikzpicture}[scale=2]
\pgfmathsetmacro\R{sqrt(3)}
\fill[ball color=white!10, opacity=0.1] (0,0,0) circle (\R); % 3D lighting effect
\tdplotsetmaincoords{80}{110}
\begin{scope}[tdplot_main_coords, shift={(0,0)}]
\coordinate (O) at (0,0,0);
% circle around Cp
% rotate circle to make it look better.
\pgfmathsetmacro{\thetavec}{0}
\pgfmathsetmacro{\phivec}{0}
\tdplotsetrotatedcoords{\phivec}{\thetavec}{0}
\tdplotdrawarc[tdplot_rotated_coords,color=blue]{(O)}{\R}{-70}{110}{}{}
\tdplotdrawarc[tdplot_rotated_coords,color=blue, dashed]{(O)}{\R}{110}{290}{}{}
\node[] at (-1,2,1) {\textcolor{blue}{\scriptsize
$\alpha=\thetavec \, , \, $\beta=\phivec}};
\pgfmathsetmacro{\thetavec}{90};
\tdplotsetrotatedcoords{\phivec}{\thetavec}{0};
\tdplotdrawarc[tdplot_rotated_coords,color=brown]{(O)}{\R}{0}{180}{}{};
\tdplotdrawarc[tdplot_rotated_coords,color=brown, dashed]{(O)}{\R}{180}{360}{}{};
\node[yshift=4 mm] at (-1,2,1) {\textcolor{brown}{\scriptsize $\alpha=\thetavec \, , \,
$\beta=\phivec}};
\pgfmathsetmacro{\phivec}{90}
\tdplotsetrotatedcoords{\phivec}{\thetavec}{0};
\tdplotdrawarc[tdplot_rotated_coords,color=red]{(O)}{\R}{0}{180}{}{};
\tdplotdrawarc[tdplot_rotated_coords,color=red, dashed]{(O)}{\R}{180}{360}{}{};
\node[yshift=8 mm] at (-1,2,1) {\textcolor{red}{\scriptsize $\alpha=\thetavec \, , \,
$\beta=\phivec}};
%axis
\coordinate (X) at (5,0,0) ;
\coordinate (Y) at (0,3,0) ;
\coordinate (Z) at (0,0,3) ;
\draw[-latex] (O) -- (X) node[anchor=west] {$X$};
\draw[-latex] (O) -- (Y) node[anchor=west] {$Y$};
\draw[-latex] (O) -- (Z) node[anchor=west] {$Z$};
\end{scope}
\end{tikzpicture}
\end{center}
\end{document}
The corresponding figure is:
Here is a post which addresses the drawing an equator when the north pole is given. A simple macro to speed up coding draw an equator when north pole is known .
Fake 2D, intersections package, and the instruction to [bend right], to [bend left]
Sometimes is better to say away from thinking and trying to do 3D.
So I am contradicting here myself with the advise of using tikz-3dplot .
Think how to draw a 3D thinking 2D (that is ellipses and arcs).
The next example is an improvement over an example shown here
Spherical triangles and great circles .
The code is based on @Tarass great insight. The example is shown here more to show the capabilities of Tikz and the use of it for other purposes. As I said, it is better to use, in general \tdplotdrawarc .
Here is the piece of code (copied and modified from @Tarass code)
\documentclass[12pt]{article}
\usepackage{amsmath}
\usepackage{enumerate}
\usepackage{tikz}
\usepackage{xcolor}
\usepackage{tikz-3dplot}
\usepackage{hyperref}
\usepackage{pgfplots}
\usetikzlibrary{calc,3d,intersections, positioning,intersections,shapes}
\pgfplotsset{compat=1.11}
\newcommand{\InterSec}[3]{%
\path[name intersections={of=#1 and #2, by=#3, sort by=#1,total=\t}]
\pgfextra{\xdef\InterNb{\t}}; }
\begin{document}
\begin{center}
\begin{tikzpicture}
\pgfmathsetmacro\R{2}
\fill[ball color=white!10, opacity=0.2] (0,0,0) circle (\R); % 3D lighting effect
\foreach \angle[count=\n from 1] in {-5,225,290} {
\begin{scope}[rotate=\angle]
\path[draw,dashed,name path global=d\n] (2,0) arc [start angle=0,
end angle=180,
x radius=2cm,
y radius=1cm] ;
\path[draw,name path global=s\n] (-2,0) arc [start angle=180,
end angle=360,
x radius=2cm,
y radius=1cm] ;
\end{scope}
}
\InterSec{s1}{s2}{I3} ;
\InterSec{s1}{s3}{I2} ;
\InterSec{s3}{s2}{I1} ;
%
\fill[fill=red,opacity=0.5] (I1) to [bend right=8.5] (I2) to [bend left=7]
(I3) to [bend left=6] (I1);
\InterSec{d1}{d2}{J3} ;
\InterSec{d1}{d3}{J2} ;
\InterSec{d3}{d2}{J1} ;
%\fill[blue] (J1)--(J2)--(J3)--cycle ;
\fill[fill=blue,opacity=0.5] (J1) to [bend right=8.5] (J2) to [bend left=7]
(J3) to [bend left=6] (J1);
\end{tikzpicture}
\end{center}
\end{document}
and here the picture.
Drawing lunes could be hard sometimes. I first refer to an StackExchange link with a problem with drawing lunes and solutions both in metapost and TiKz. The link is:
How to draw a lune and shade it in TiKz
I offer here another figure showing the duality between a segment and
its lune. In this particular example I combine 3D and 2D, so back into suggesting the use of tikz-3dplot: the code is next:
\documentclass[12pt]{article}
\usepackage{amsmath}
\usepackage{tikz}
\usepackage{tikz-3dplot}
\usetikzlibrary{calc,3d,decorations.markings, backgrounds, positioning,intersections,shapes}
\usepackage{pgfplots}
\newcommand{\InterSec}[3]{%
\path[name intersections={of=#1 and #2, by=#3, sort by=#1,total=\t}]
\pgfextra{\xdef\InterNb{\t}};
}
\newcommand\getEquator[2]
{
\def\yt{#1}
\def\zt{#2}
\pgfmathsetmacro{\betav}{acos(\zt)};
\def\gammav{0}
\ifthenelse{\equal{\betav}{0.0}}
{
\def\alphav{0}
}
{
\pgfmathsetmacro{\alphav}{asin(\yt/(sin(\betav))}
};
}
% to color a line
\tikzset{test/.style={
postaction={
decorate,
decoration={
markings,
mark=at position \pgfdecoratedpathlength-0.5pt with
{\arrow[blue,line width=#1] {>}; },
mark=between positions 0 and \pgfdecoratedpathlength step 0.5pt with {
\pgfmathsetmacro\myval{multiply(divide(
\pgfkeysvalueof{/pgf/decoration/mark info/distance from start},
\pgfdecoratedpathlength),100)};
\pgfsetfillcolor{blue!\myval!green};
\pgfpathcircle{\pgfpointorigin}{#1};
\pgfusepath{fill};}
}
}
}
}
\begin{document}
\begin{tikzpicture}[scale=1.3]
\coordinate (O) at (0,0,0);
\tdplotsetmaincoords{60}{110}
\pgfmathsetmacro\R{sqrt(3)}
\fill[ball color=white!10, opacity=0.2, name path global=C] (O) circle (\R); % 3D lighting effect
\begin{scope}[tdplot_main_coords, shift={(0,0)}]
\pgfmathsetmacro\R{sqrt(3)}
\pgfmathsetmacro{\thetavec}{0};
\pgfmathsetmacro{\phivec}{0};
\pgfmathsetmacro{\gammav}{0};
\tdplotsetrotatedcoords{\phivec}{\thetavec}{\gammav};
\def\angA{90}
\def\angB{60}
\pgfmathsetmacro{\ax}{cos(\angA)}
\pgfmathsetmacro{\ay}{sin(\angA)}
\pgfmathsetmacro{\z}{0}
\pgfmathsetmacro{\bx}{cos(\angB)}
\pgfmathsetmacro{\by}{sin(\angB)}
\pgfmathsetmacro{\aax}{\R*cos(\angA)}
\pgfmathsetmacro{\aay}{\R*sin(\angA)}
\pgfmathsetmacro{\bbx}{\R*cos(\angB)}
\pgfmathsetmacro{\bby}{\R*sin(\angB)}
\coordinate (A) at (\aax,\aay,\z);
\coordinate (B) at (\bbx,\bby,\z);
\getEquator{\ay}{\z};
\tdplotsetrotatedcoords{\alphav}{\betav}{\gammav};
\tdplotdrawarc[tdplot_rotated_coords,color=green, name path global=GF, opacity=0]
{(0,0)}{\R}{180}{360}{}{};
\tdplotdrawarc[tdplot_rotated_coords,color=green, name path global=GB, opacity=0]
{(0,0)}{\R}{0}{180}{}{};
\tdplotdrawarc[tdplot_rotated_coords,color=yellow, name path=YB, opacity=0]
{(0,0)}{\R}{90}{180}{}{};
\getEquator{\by}{\z};
\tdplotsetrotatedcoords{\alphav}{\betav}{\gammav};
\tdplotdrawarc[tdplot_rotated_coords,color=blue, name path=BF, opacity=0]
{(0,0)}{\R}{180}{360}{}{};
\tdplotdrawarc[tdplot_rotated_coords,color=blue, name path=BB, opacity=0]
{(0,0)}{\R}{0}{180}{}{};
\tdplotdrawarc[tdplot_rotated_coords,color=red, name path=RB, opacity=0]
{(0,0)}{\R}{90}{180}{}{};
%\draw[color=red] (A) arc (\angA:\angB:\R);
\draw[test=0.2mm] (A) arc (\angA:\angB:\R);
\InterSec{GF}{BF}{F};
\InterSec{GB}{BB}{B};
\InterSec{C}{GF}{CG};
\InterSec{C}{BF}{CB};
\InterSec{C}{RB}{RC};
\InterSec{GB}{RB}{RBF};
\InterSec{YB}{C}{T};
%\draw[] (F) circle (1pt) node[] {\; \; \tiny F};
%\draw[] (CG) circle (1pt) node[] {\tiny CG};
%\draw[] (CB) circle (1pt) node[] {\tiny CB};
%\draw[] (B) circle (1pt) node[] {\tiny B};
%\draw[] (RBF) circle (1pt) node[] {\; \; \tiny RBF};
%\draw[] (T) circle (1pt) node[] {\tiny T};
%\draw[] (RC) circle (1pt) node[] {\tiny RC};
%axis
\coordinate (X) at (4,0,0) ;
\coordinate (Y) at (0,3,0) ;
\coordinate (Z) at (0,0,3) ;
\draw[-latex] (O) -- (X) node[anchor=east] {\; \; $X$};
\draw[-latex] (O) -- (Y) node[anchor=north] {$Y$};
\draw[-latex] (O) -- (Z) node[anchor=south west] {$Z$};
\shade[left color=blue, right color=green, opacity=0.8] (F) to [bend right=50] (CB) to
[bend right=10] (CG) to [bend left] (F);
\shade[left color=blue, right color=green, opacity=0.3] (CB) to [bend right=10] (CG) to
[bend right] (B) to [bend left] (CB);
\shade[left color=green, right color=blue, opacity=0.3] (B) to [bend right=60] (RC) to
[bend right=10] (RBF) to [bend left ] (B);
\shade[left color=green, right color=blue, opacity=0.8] (F) to [bend left=10] (RC) to
[bend right=10] (T) to [bend right] (F);
\end{scope}
\end{tikzpicture}
\end{document}
and the figure is here:
Conversion of Coordinates and alternatives for drawing arcs
In spherical geometry understanding where coordinates (a point) are
and how to draw arcs is a fundamental issue.
There could be confusion because spherical coordinates for mathematicians and phycisist use different symbols, the following link provides
macros for conversion between spherical (azimuth, polar) and cartesian coordinates and addresses conversions in terms of geografic (latidue, altitude) coordinates as well: spherical coordinates in 3d .
Finally since TiKz do not seem to have tools to draw arcs given a center and a radius I wrote a macro and posted here .
Here's an alternative using Asymptote. It fulfills some version of most of your requests; for instance, the colors are defined in the preamble (but in Asymptote code rather than TeX code, so you might need to define TeX versions separately).
% To run: pdflatex --shell-escape filename.tex
\documentclass[margin=10pt,convert]{standalone}
\usepackage{asypictureB}
\begin{asyheader}
pen c1 = rgb(0.2,0.4,0.6); // Blue-ish
pen c2 = rgb(1.0,0.0,0.6); // Pink-ish
pen c3 = rgb(0.6,0.0,0.0); // Red
texpreamble("\newbox\BoxForRules
\newcommand{\boxToRule}[1]{%
\setbox\BoxForRules=\hbox{\hspace{2pt}#1\hspace{2pt}}%
$\rlap{\rule[\dimexpr-\dp\BoxForRules-2pt]{\wd\BoxForRules}{\dimexpr\ht\BoxForRules+\dp\BoxForRules+4pt}}\mbox{\hspace{2pt}#1\hspace{2pt}}$%
}");
import three;
void framed_label(string s, triple position, pen p = currentpen) {
label("\boxToRule{" + s + "}", position=position, p=white + opacity(0.6));
label(s, position=position, p=p);
}
\end{asyheader}
\begin{document}
\begin{asypicture}{name=cylinder}
settings.outformat = "pdf";
settings.render = 0;
real unit = 4cm;
unitsize(unit);
currentprojection = orthographic((-4,2.8,-2), up=Y);
real d = 1;
real r = 0.45 d;
real af = 0.5 d;
pen cubedraw = linewidth(0.8pt) + gray;
pen cubefill = opacity(0.5) + c1;
pen axis = linewidth(1.0 pt) + c3;
//Draw backside of cube
draw( surface((0,0,d) -- (0,d,d) -- (d,d,d) -- (d,0,d) -- cycle),
meshpen = cubedraw,
surfacepen = emissive(cubefill));
draw( surface((0,0,0) -- (0,0,d) -- (d,0,d) -- (d,0,0) -- cycle), meshpen = cubedraw, surfacepen = emissive(cubefill));
draw( surface((d,0,0) -- (d,0,d) -- (d,d,d) -- (d,d,0) -- cycle), meshpen = cubedraw, surfacepen = emissive(cubefill));
//Draw cylinder as surface of revolution
path3 cyl_center = shift(d/2,0,d/2) * (O -- d*Y);
path3 cyl_edge = shift(r*X) * cyl_center;
int n = 10;
guide3 to_revolve = point(cyl_edge, 0);
for (int i = 1; i <= n; ++i)
to_revolve = to_revolve -- point(cyl_edge, i/n);
surface cylinder = surface(to_revolve, c=(d/2,0,d/2), axis=Y);
draw(cylinder, meshpen = 0.3 c2 + 0.5 gray,
surfacepen = material(c2 + opacity(0.7), emissivepen = 0.2 c2));
//Draw the radius arrow and center line
draw(cyl_center, 0.8 c2);
//draw(circle(c=(d/2,d/2,d/2), r=r, normal=Y), 0.8 c2);
draw( (d/2,d,d/2) -- (d/2,d,d/2+r), c2 + linewidth(0.8), arrow=Arrows3(TeXHead2));
framed_label("$r$", position=(d/2, d, d/2 + r/2), p=c2);
//Draw front of cube
draw( (0,0,0) -- (0,d,0) ^^ (d,d,0) -- (0,d,0) ^^ (0,d,d) -- (0,d,0), cubedraw);
//Draw the axis arrows and annotations
draw(O -- af*X, axis, arrow=Arrow3(TeXHead2));
framed_label("$x$", position=(1 + 18pt/unit)*af*X, p=axis);
draw(O -- af*Y, axis, arrow=Arrow3(TeXHead2));
framed_label("$y$", position=(1 + 12pt/unit)*af*Y, p=axis);
draw(O -- af*Z, axis, arrow=Arrow3(TeXHead2));
framed_label("$z$", position=(1 + 10pt/unit)*af*Z, p=axis);
//Draw cube lattice length measures
draw((0,0,d*5/6) -- (0,d,d*5/6), p=linewidth(0.8pt) + c1, arrow=Arrows3(TeXHead2));
framed_label("$d$", (0,d/2,d*5/6), c1);
draw((d*5/6,0,0) -- (d*5/6,d,0), p=linewidth(0.8pt) + c1, arrow=Arrows3(TeXHead2));
framed_label("$d$", (d*5/6, d/2, 0), c1);
draw((d*5/6, d, 0) -- (d*5/6, d, d), p=linewidth(0.8pt) + c1, arrow=Arrows3(TeXHead2));
framed_label("$d$", (d*5/6, d, d/2), c1);
//Material parameters label
framed_label("$\varepsilon_c, \mu_c$", position=(d/2, d/2+r/2, d/2), p=c1);
\end{asypicture}
\begin{asypicture}{name=sphere}
settings.outformat = "pdf";
settings.render = 0;
import graph3;
real unit = 4cm;
unitsize(unit);
currentprojection = orthographic((-4,2.8,-2), up=Y);
real d = 1;
real r = 0.45 d;
real af = 0.5 d;
pen cubedraw = linewidth(0.8pt) + gray;
pen cubefill = opacity(0.5) + c1;
pen axis = linewidth(1.0 pt) + c3;
//Draw backside of cube
draw( surface((0,0,d) -- (0,d,d) -- (d,d,d) -- (d,0,d) -- cycle),
meshpen = cubedraw,
surfacepen = emissive(cubefill));
draw( surface((0,0,0) -- (0,0,d) -- (d,0,d) -- (d,0,0) -- cycle), meshpen = cubedraw, surfacepen = emissive(cubefill));
draw( surface((d,0,0) -- (d,0,d) -- (d,d,d) -- (d,d,0) -- cycle), meshpen = cubedraw, surfacepen = emissive(cubefill));
//Draw sphere as surface of revolution
triple centerpoint = (d/2, d/2, d/2);
path3 centerline = (centerpoint - r*Y) -- (centerpoint + r*Y);
path3 to_revolve = Arc(centerpoint - r*Y, centerpoint + r*Y, c=centerpoint, normal=X, n=16);
surface sphere = surface(to_revolve, c=centerpoint, axis=Y);
draw(sphere, meshpen = 0.3 c2 + 0.5 gray,
surfacepen = material(c2 + opacity(0.7), emissivepen = 0.2 c2));
//Draw the radius arrow and helper lines
draw(centerline, 0.8 c2);
draw(circle(c=(d/2,d/2,d/2), r=r, normal=Y), 0.8 c2);
draw( (d/2,d/2,d/2) -- (d/2,d/2,d/2+r), c2 + linewidth(0.8), arrow=Arrows3(TeXHead2));
framed_label("$r$", position=(d/2, d/2, d/2 + r/2), p=c2);
//Draw front of cube
draw( (0,0,0) -- (0,d,0) ^^ (d,d,0) -- (0,d,0) ^^ (0,d,d) -- (0,d,0), cubedraw);
//Draw the axis arrows and annotations
draw(O -- af*X, axis, arrow=Arrow3(TeXHead2));
framed_label("$x$", position=(1 + 18pt/unit)*af*X, p=axis);
draw(O -- af*Y, axis, arrow=Arrow3(TeXHead2));
framed_label("$y$", position=(1 + 12pt/unit)*af*Y, p=axis);
draw(O -- af*Z, axis, arrow=Arrow3(TeXHead2));
framed_label("$z$", position=(1 + 10pt/unit)*af*Z, p=axis);
//Draw cube lattice length measures
draw((0,0,d*5/6) -- (0,d,d*5/6), p=linewidth(0.8pt) + c1, arrow=Arrows3(TeXHead2));
framed_label("$d$", (0,d/2,d*5/6), c1);
draw((d*5/6,0,0) -- (d*5/6,d,0), p=linewidth(0.8pt) + c1, arrow=Arrows3(TeXHead2));
framed_label("$d$", (d*5/6, d/2, 0), c1);
draw((d*5/6, d, 0) -- (d*5/6, d, d), p=linewidth(0.8pt) + c1, arrow=Arrows3(TeXHead2));
framed_label("$d$", (d*5/6, d, d/2), c1);
//Material parameters label
framed_label("$\varepsilon_c, \mu_c$", position=(d/2, d/2+r/2, d/2), p=c1);
\end{asypicture}
\end{document}
Here's the result:
From a technical standpoint, the most difficult aspect was the white boxes framing the text; as you can see, I gave up on the rounded corners.
I'd also note that a lot of this would be easier if you were willing to use high-resolution rasterized graphics: it would be determined automatically what objects go in front of what others (independent of the drawing order), and the gridlines would not be necessary.
A note on workflows using Asymptote: here are some of the available options. (All of them require a working Asymptote installation, although that is automatic with TeXLive.)
Use a standard latex command (e.g., pdflatex
) with the -shell-escape
option enabled. This requires the asypictureB
package. On any given run, only those pictures that have changed (or been deleted) since the last run will be recompiled. You can create a "common preamble" that is shared among all your Asymptote files including e.g. color definitions, but definitions in your TeX preamble do not carry over automatically.
This is the option I have suggested using above.
Use the latexmk
script, with the configuration file augmented as described in this documentation. For this, you should probably use the asymptote
package rather than asypictureB
, which is not designed to be used this way. You still have the option of a common Asymptote preamble. With the inline
option of the asymptote
package, you also have access to all the packages and macros of your main document in the labels.
Use either asymptote
or asypictureB
with multiple runs to compile the pictures separately. The command sequence
pdflatex filename
asy filename-*.asy
pdflatex filename
will usually work with either package (or both), although every image will be recompiled--including those that have not changed since the last run. A more efficient alternative to the middle line is offered by the asypictureB
package; see the package documentation, section 2.1, page 4.
Personally, I prefer the first option, because it offers the best debugging support by a fair margin. At the same time, I recommend that LaTeX users in general be familiar with using latexmk
, since it can be used to automate an entire workflow, including making the index (if necessary) and multiple runs to define labels and the table of contents (again, only if necessary; latexmk
is good at detecting this).
Best Answer
Here's an effort in fake-3D in Metapost which might encourage someone to show something similar in TikZ. There's no
buildcycle
for TikZ, but you can get the same effects with theintersections
library, I believe.