9

Drawing a sphere is easy enough using the ball shading, or some more refined form as in How to draw a shaded sphere, but I would like a way to shade only one half (or even just slices). I currently have the following:

\documentclass{standalone}
\usepackage{tikz}
%% helpers for 3D sphere drawing
\newcommand\pgfmathsinandcos[3]{%
  \pgfmathsetmacro#1{sin(#3)}%
  \pgfmathsetmacro#2{cos(#3)}%
}
\newcommand\LongitudePlane[3][current plane]{%
  \pgfmathsinandcos\sinEl\cosEl{#2} % elevation
  \pgfmathsinandcos\sint\cost{#3} % azimuth
  \tikzset{#1/.style={cm={\cost,\sint*\sinEl,0,\cosEl,(0,0)}}}
}
\newcommand\LatitudePlane[3][current plane]{%
  \pgfmathsinandcos\sinEl\cosEl{#2} % elevation
  \pgfmathsinandcos\sint\cost{#3} % latitude
  \pgfmathsetmacro\yshift{\cosEl*\sint}
  \tikzset{#1/.style={cm={\cost,0,0,\cost*\sinEl,(0,\yshift)}}} %
}
\newcommand\DrawLongitudeCircle[2][2]{
  \LongitudePlane{\angEl}{#2}
  \tikzset{current plane/.prefix style={scale=#1}}
  % angle of "visibility"
  \pgfmathsetmacro\angVis{atan(sin(#2)*cos(\angEl)/sin(\angEl))} %
  \draw[current plane, very thin] (\angVis:1) arc (\angVis:\angVis+180:1);
  \draw[current plane,dashed,very thin] (\angVis-180:1) arc (\angVis-180:\angVis:1);
}
\newcommand\DrawLatitudeCircle[2][3]{
  \LatitudePlane{\angEl}{#2}
  \tikzset{current plane/.prefix style={scale=#1}}
  \pgfmathsetmacro\sinVis{sin(#2)/cos(#2)*sin(\angEl)/cos(\angEl)}
  % angle of "visibility"
  \pgfmathsetmacro\angVis{asin(min(1,max(\sinVis,-1)))}
  \draw[current plane] (\angVis:1) arc (\angVis:-\angVis-180:1);
  \draw[current plane,dashed] (180-\angVis:1) arc (180-\angVis:\angVis:1);
}
\begin{document}

\begin{tikzpicture}
\def\R{2.5} % sphere radius
\def\angEl{35} % elevation angle
\def\angAz{-105} % azimuth angle
\tikzset{xyplane/.style={cm={cos(\angAz),sin(\angAz)*sin(\angEl),-sin(\angAz),
      cos(\angAz)*sin(\angEl),(0,0)}}}
\LongitudePlane[xzplane]{\angEl}{\angAz}
% sphere
\filldraw[ball color=blue, opacity=.2] (0,0) circle (\R);

%\draw[xyplane] (-2*\R,-2*\R) rectangle (2.2*\R,2.8*\R);
\draw[xyplane,->] (-2.25*\R,0) -- (2.75*\R,0) node[below right] {$k_x$};
\draw[xyplane,->] (0, -1.1*\R)-- (0,1.5*\R) node[below left] {$k_y$};
\draw[->] (0,-1.25*\R) -- (0,1.5*\R) node[below right] {$k_z$};

% meridians
\foreach \t in {-80,-60,...,80} { \DrawLatitudeCircle[\R]{\t} }
\foreach \t in {-5,-35,...,-175} { \DrawLongitudeCircle[\R]{\t} }
\end{tikzpicture}

\end{document}

Which I got from this paper which refers to this TeXample from which I got the above projected drawing code. I unfortunately do not see a way to properly turn this into a sliced sphere or hemisphere at the least. As an additional improvement, perhaps the inside of the sphere can be "dark-shaded", such that the result looks like what I can do "easily" with Mathematica:

enter image description here

I understand the above needs some work wrt the line color and all, but what interests me here is the sectioning and the shading of the inside of the sphere. I would guess some handy clip action and two ball shadings with different opacities might get me close, but I have no idea how to get the clipping to work.

Thanks!

1

2 Answers 2

11

enter image description here

Here is a modification of the example in section 3.6.5 of the The tikz-3dplot Package manual.

\documentclass[12pt]{article}
\usepackage{amsmath}
\usepackage{enumerate}
\usepackage{tikz}
\usepackage{xcolor}
\usepackage{tikz-3dplot}
\usepackage{hyperref}
\usepackage{ifthen}
\usepackage{pgfplots}
\usetikzlibrary{calc,3d,intersections, positioning,intersections,shapes}
\pgfplotsset{compat=1.11} 

\begin{document}

  \tdplotsetmaincoords{60}{110}
  \begin{tikzpicture}[scale=2,line join=bevel,tdplot_main_coords,%
    fill opacity=.5]
    \tdplotsetpolarplotrange{0}{90}{0}{360}
    \tdplotsphericalsurfaceplot[parametricfill]{60}{32}%
    {1}{black}{\tdplotphi + 3*\tdplottheta}%
    {\draw[color=black,thick,->] (0,0,0)
      -- (2,0,0) node[anchor=north east]{$x$};}%
      {\draw[color=black,thick,->] (0,0,0)
        -- (0,2,0) node[anchor=north west]{$y$};}%
        {\draw[color=black,thick,->] (0,0,0)
          -- (0,0,2) node[anchor=south]{$z$};}%
   \end{tikzpicture}
\end{document}

In addition, here is the pgfplots version:

\documentclass[12pt]{article}
\usepackage{amsmath}
\usepackage{enumerate}
\usepackage{tikz}
\usepackage{xcolor}
\usepackage{tikz-3dplot}
\usepackage{hyperref}
\usepackage{ifthen}
\usepackage{pgfplots}

\usetikzlibrary{calc,3d,shapes, pgfplots.external}
\pgfplotsset{compat=1.11} 

\begin{document}
\begin{tikzpicture}
  \begin{axis}[width=\textwidth,
      samples=50,domain=0:360,y domain=0:90,
      xmin=-1.2,xmax=1.2,ymin=-1.2,ymax=1.2,zmin=0,zmax=1.2,
      xlabel={$x$},ylabel={$y$},zlabel={$z$},
    axis lines=center]
    \addplot3[surf,opacity=0.5]
    ({cos(x)*cos(y)}, {sin(x)*cos(y)}, {sin(y)});
  \end{axis}
\end{tikzpicture}

\end{document}

and here the pic:

Half sphere with psgfig

7

run with xelatex

\documentclass{article}
\usepackage{pst-solides3d}

\begin{document}

\begin{pspicture}(-4,-3)(4,4)
\psset{viewpoint=50 25 10 rtp2xyz,Decran=50}
\psSolid[object=calottesphere,r=3,ngrid=20 36,hue=0 
  1,theta=0,phi=-90,hollow,incolor=blue!30]
  \axesIIID[showOrigin=false](4,4,2)
\end{pspicture}

\begin{pspicture}(-4,-3)(4,4)
\psset{viewpoint=50 25 10 rtp2xyz,Decran=50}
\psSolid[object=calottesphere,r=3,ngrid=20 36,hue=0 1,
  theta=0,phi=-90,hollow,RotY=180,opacity=0.4,incolor=blue!30]
\axesIIID[showOrigin=false](4,4,4)
\end{pspicture}

\end{document}

enter image description here

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .