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!

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.