1

I plan to draw the following picture using Tikz

Stereographic projection

I used a couple of codes from the Tikz website. However, I am not able to tilt the planes in the way I want it in the above figure. Any pointer will be of great help.

The code I have used is given below:

\documentclass[tikz]{standalone}
\usetikzlibrary{calc,fadings,decorations.pathreplacing}
\usepackage{verbatim}

\begin{comment}

:Title: Stereographic and cylindrical map projections
:Tags: 3D
:Slug: map-projections
:Grid: 2x2

Examples inspired by the thread at comp.text.tex about `how to convert some hand
drawn pictures into programmatic 3D sketches`__.

.. __: http://groups.google.com/group/comp.text.tex/browse_thread/thread/a03baf5d6fa64865/f7e7b903f1d87a6a

The sketches present stereographic and cylindrical map projections and they
pose some interesting challenges for doing them with a 2D drawing package PGF/TikZ.

The main idea is to draw in selected 3D planes and then project onto the canvas
coordinate system with an appriopriate transformation. Some highlights:

- usage of pgf math engine for calculation of projection transformations and
  transitions points from visible (solid lines) to invisible (dashed lines) on
  meridians and latitude circles
- definition of 3D plane transformation with expanded styles so that they are robust
  against redefinition of macros used in their construction
- usage of named coordinates (nodes) for definition of characteristic points in
  local coordinate systems so that they are accessible outside of their plane of
  definition
- calculation of intersections points with TikZ intersection coordinate system
- usage of 'to' path operation instead of 'arc' for marking angles to allow for
  easy positioning of text labels on the curve
- 3D lighting effects with shading

:Author: Tomasz M. Trzeciak
:Source: LaTeX-Community.org_

.. _LaTeX-Community.org: http://www.latex-community.org/viewtopic.php?f=4&t=2111

\end{comment}

%% helper macros

\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][1]{
  \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] (\angVis:1) arc (\angVis:\angVis+180:1);
  \draw[current plane,dashed] (\angVis-180:1) arc (\angVis-180:\angVis:1);
}
\newcommand\DrawLatitudeCircle[2][1]{
  \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);
}

%% document-wide tikz options and styles

\tikzset{%
  >=latex, % option for nice arrows
  inner sep=0pt,%
  outer sep=2pt,%
  mark coordinate/.style={inner sep=0pt,outer sep=0pt,minimum size=3pt,
    fill=black,circle}%
}

\begin{document}

\begin{tikzpicture} % CENT

%% some definitions

\def\R{2.5} % sphere radius
\def\angEl{35} % elevation angle
\def\angAz{-105} % azimuth angle
\def\angPhi{-40} % longitude of point P
\def\angBeta{19} % latitude of point P

%% working planes

\pgfmathsetmacro\H{\R*cos(\angEl)} % distance to north pole
\tikzset{xyplane/.style={cm={cos(\angAz),sin(\angAz)*sin(\angEl),-sin(\angAz),
                              cos(\angAz)*sin(\angEl),(0,-\H)}}}
\LongitudePlane[xzplane]{\angEl}{\angAz}
\LongitudePlane[pzplane]{\angEl}{\angPhi}
\LatitudePlane[equator]{\angEl}{0}

%% draw xyplane and sphere

\draw[xyplane] (-2*\R,-2*\R) rectangle (2.2*\R,2.8*\R);
\fill[ball color=white] (0,0) circle (\R); % 3D lighting effect
\draw (0,0) circle (\R);

\draw[xyplane] (2*\R,2*\R) rectangle (2.2*\R,2.8*\R);

\begin{scope}[shift={(-0.5,-0.5)}, xshift=0, every node/.append style={
            yslant=0.5,xslant=0.5},xslant=-0.9,yslant=0.3
                     ]
        \fill[white,fill opacity=.9] (0,0) rectangle (5,5);
        \draw[black,very thick] (0,0) rectangle (5,5);
        \draw[step=4mm, black] (0,0) grid (5,5);
    \end{scope}


%% characteristic points

\coordinate (O) at (0,0);
\coordinate[mark coordinate] (N) at (0,\H);
\coordinate[mark coordinate] (S) at (0,-\H);
\path[pzplane] (\angBeta:\R) coordinate[mark coordinate] (P);
\path[pzplane] (\R,0) coordinate (PE);
\path[xzplane] (\R,0) coordinate (XE);
\path (PE) ++(0,-\H) coordinate (Paux); % to aid Phat calculation
\coordinate[mark coordinate] (Phat) at (intersection cs: first line={(N)--(P)},
                                        second line={(S)--(Paux)});

%% draw meridians and latitude circles

\DrawLatitudeCircle[\R]{0} % equator
%\DrawLatitudeCircle[\R]{\angBeta}
\DrawLongitudeCircle[\R]{\angAz} % xzplane
\DrawLongitudeCircle[\R]{\angAz+90} % yzplane
\DrawLongitudeCircle[\R]{\angPhi} % pzplane

%% draw xyz coordinate system

\draw[xyplane,<->] (1.8*\R,0) node[below] {$x,\xi$} -- (0,0) -- (0,2.4*\R)
    node[right] {$y,\eta$};
\draw[->] (0,-\H) -- (0,1.6*\R) node[above] {$z,\zeta$};

%% draw lines and put labels

\draw[dashed] (P) -- (N) +(0.3ex,0.6ex) node[above left] {$\mathbf{N}$};
\draw (P) -- (Phat) node[above right] {$\mathbf{\hat{P}}$};
\path (S) +(0.4ex,-0.4ex) node[below] {$\mathbf{S}$};
\draw[->] (O) -- (P) node[above right] {$\mathbf{P}$};
\draw[dashed] (XE) -- (O) -- (PE);
\draw[pzplane,->,thin] (0:0.5*\R) to[bend right=15]
    node[pos=0.4,right] {$\beta$} (\angBeta:0.5*\R);
\draw[equator,->,thin] (\angAz:0.4*\R) to[bend right=30]
    node[pos=0.4,below] {$\phi$} (\angPhi:0.4*\R);
\draw[thin,decorate,decoration={brace,raise=0.5pt,amplitude=1ex}] (N) -- (O)
    node[midway,right=1ex] {$a$};

\end{tikzpicture}
\end{document} 

\begin{tikzpicture} % MERC

%% some definitions

\def\R{3} % sphere radius
\def\angEl{25} % elevation angle
\def\angAz{-100} % azimuth angle
\def\angPhiOne{-50} % longitude of point P
\def\angPhiTwo{-35} % longitude of point Q
\def\angBeta{33} % latitude of point P and Q

%% working planes

\pgfmathsetmacro\H{\R*cos(\angEl)} % distance to north pole
\LongitudePlane[xzplane]{\angEl}{\angAz}
\LongitudePlane[pzplane]{\angEl}{\angPhiOne}
\LongitudePlane[qzplane]{\angEl}{\angPhiTwo}
\LatitudePlane[equator]{\angEl}{0}

%% draw background sphere

\fill[ball color=white] (0,0) circle (\R); % 3D lighting effect
%\fill[white] (0,0) circle (\R); % just a white circle
\draw (0,0) circle (\R);

%% characteristic points

\coordinate (O) at (0,0);
\coordinate[mark coordinate] (N) at (0,\H);
\coordinate[mark coordinate] (S) at (0,-\H);
\path[xzplane] (\R,0) coordinate (XE);
\path[pzplane] (\angBeta:\R) coordinate (P);
\path[pzplane] (\R,0) coordinate (PE);
\path[qzplane] (\angBeta:\R) coordinate (Q);
\path[qzplane] (\R,0) coordinate (QE);

%% meridians and latitude circles

% \DrawLongitudeCircle[\R]{\angAz} % xzplane
% \DrawLongitudeCircle[\R]{\angAz+90} % yzplane
\DrawLongitudeCircle[\R]{\angPhiOne} % pzplane
\DrawLongitudeCircle[\R]{\angPhiTwo} % qzplane
\DrawLatitudeCircle[\R]{\angBeta}
\DrawLatitudeCircle[\R]{0} % equator

% shifted equator in node with nested call to tikz 
% (I didn't know it's possible)
\node at (0,1.6*\R) { \tikz{\DrawLatitudeCircle[\R]{0}} };

%% draw lines and put labels

\draw (-\R,-\H) -- (-\R,2*\R) (\R,-\H) -- (\R,2*\R);
\draw[->] (XE) -- +(0,2*\R) node[above] {$y$};
\node[above=8pt] at (N) {$\mathbf{N}$};
\node[below=8pt] at (S) {$\mathbf{S}$};
\draw[->] (O) -- (P);
\draw[dashed] (XE) -- (O) -- (PE);
\draw[dashed] (O) -- (QE);
\draw[pzplane,->,thin] (0:0.5*\R) to[bend right=15]
    node[midway,right] {$\beta$} (\angBeta:0.5*\R);
\path[pzplane] (0.5*\angBeta:\R) node[right] {$\hat{1}$};
\path[qzplane] (0.5*\angBeta:\R) node[right] {$\hat{2}$};
\draw[equator,->,thin] (\angAz:0.5*\R) to[bend right=30]
    node[pos=0.4,above] {$\phi_1$} (\angPhiOne:0.5*\R);
\draw[equator,->,thin] (\angAz:0.6*\R) to[bend right=35]
    node[midway,below] {$\phi_2$} (\angPhiTwo:0.6*\R);
\draw[equator,->] (-90:\R) arc (-90:-70:\R) node[below=0.3ex] {$x = a\phi$};
\path[xzplane] (0:\R) node[below] {$\beta=0$};
\path[xzplane] (\angBeta:\R) node[below left] {$\beta=\beta_0$};

\end{tikzpicture}


\begin{tikzpicture} % KART

\def\R{2.5}

\node[draw,minimum size=2cm*\R,inner sep=0,outer sep=0,circle] (C) at (0,0) {};
\coordinate (O) at (0,0);
\coordinate[mark coordinate] (Phat) at (20:2.5*\R);
\coordinate (T1) at (tangent cs: node=C, point={(Phat)}, solution=1);
\coordinate (T2) at (tangent cs: node=C, point={(Phat)}, solution=2);
\coordinate[mark coordinate] (P) at ($(T1)!0.5!(T2)$);

\draw[dashed] (T1) -- (O) -- (T2) -- (Phat) -- (T1) -- (T2);
\draw[<->] (0,1.5*\R) node[above] {$y$} |- (2.5*\R,0) node[right] {$x$};
\draw (O) node[below left] {$\mathbf{O}$} -- (P)
    +(1ex,0) node[above=1ex] {$\mathbf{P}$};
\draw (P) -- (Phat) node[above=1ex] {$\mathbf{\hat{P}}$};

\end{tikzpicture}
  • Welcome to TEXSE, could you provide us a compilable MWE? – Raaja_is_at_topanswers.xyz Aug 4 '19 at 15:41
  • 2
    I would suggest redoing the whole thing using tikz3d. If not, try to make the aspect ratio for the grid in xyplane match the aspect ratio of the latitude plane (which appears to be \sinE1). – John Kormylo Aug 4 '19 at 17:37
4

As John Kormylo is saying, you can use tikz-3dplot. The visible angle ranges have been worked out e.g. here, but in different conventions. This answer has analytic expressions for the visible domains of latitude and longitude arcs, which are called alpha1 and so on. This allows you to draw grids on the sphere. The plane grids can be added using the canvas is xy plane at z=... keys from the 3d library.

\documentclass[tikz]{standalone}
\usepackage{tikz-3dplot}
\begin{document}
\tdplotsetmaincoords{110}{40} 
\begin{tikzpicture}[tdplot_main_coords,declare function={R=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));%
}]
 \begin{scope}[canvas is xy plane at z=-R-1]
  \draw (-4,-4) grid (4,4);
 \end{scope}
 \draw[tdplot_screen_coords,ball color=gray!30] (0,0,0) circle[radius=R*1cm];
 \foreach \X in {60,90,...,210}
 {\draw plot[smooth,variable=\t,
     domain={beta1(\tdplotmaintheta,\tdplotmainphi,\X)}:{beta2(\tdplotmaintheta,\tdplotmainphi,\X)}] 
   (xyz spherical cs:radius=R,latitude=\t,longitude=\X);
 }
 \foreach \Y in {70,50,...,-70}
 {
  \draw plot[smooth,variable=\t,
     domain={alpha1(\tdplotmaintheta,\tdplotmainphi,\Y)}:{alpha2(\tdplotmaintheta,\tdplotmainphi,\Y)}] 
   (xyz spherical cs:radius=R,latitude=\Y,longitude=\t);
  }
 \begin{scope}[canvas is xy plane at z=R+1]
  \draw (-4,-4) grid (4,4);
 \end{scope}
\end{tikzpicture}
\end{document}

enter image description here

| improve this answer | |
  • Thanks, John and user1217199 for the response. When I use user121799's code, the two planes are cropped. I did a bit tweaking and I got a decent diagram. See the code and the diagram below. However, I could not get grids in the two planes. Any suggestion will be useful. Thanks, – Shanki Aug 6 '19 at 9:20
0

Solved. Here is the final LaTeX code:

\documentclass[tikz, border=2mm]{standalone}

\usepackage{pgfplots}

\usepackage{amsmath,amssymb,amsfonts}

\usepackage{mathrsfs}

\pgfplotsset{compat=1.12}

\begin{document}

\begin{tikzpicture}[
  point/.style = {draw, circle, fill=black, inner sep=0.7pt},
]

\def\rad{2cm}

\coordinate (O) at (0,0); 
\coordinate (N) at (0,\rad); 
\coordinate (S) at (0,-\rad); 


\begin{scope}[xslant=0.65,yshift=-\rad,xshift=2]

\filldraw[fill=white,opacity=0.2]
  (-3,-1) -- (4,-1) -- (4,1) -- (-3,1) -- cycle;

\node[text=red] at (4.2,0.8) {$\mathscr{B}$};  

\draw[step=2mm, thick, black] (-3,-1) -- (4,-1) -- (4,1) -- (-3,1) -- cycle;

\draw[thin, gray, step=0.4cm] (-3,-1) grid (4,1);

\end{scope}
%
\filldraw[ball color=white] (O) circle [radius=\rad];

\draw[dashed,blue] 
  (\rad,0) arc [start angle=0,end angle=180,x radius=\rad,y radius=5mm];

\draw[blue]
  (\rad,0) arc [start angle=0,end angle=-180,x radius=\rad,y radius=5mm];
%
\begin{scope}[xslant=0.5,yshift=\rad,xshift=-2]

\filldraw[fill=gray!10,opacity=0.2]
  (-4,1) -- (3,1) -- (3,-1) -- (-4,-1) -- cycle;

\node[text=red] at (3.2,0.6) {$\mathscr{A}$};  

\draw[step=2mm, thick, black] (-4,1) -- (3,1) -- (3,-1) -- (-4,-1) -- cycle;

\draw[thin, gray, step=0.4cm] (-4,-1) grid (3,1);

\end{scope}
%

\draw[dashed]
  (N) node[above] {} -- (O) node[below] {};

 \draw[dashed]
  (O) node[above] {} -- (S) node[below] {}; 

\end{tikzpicture}

\end{document}

Here is the output:

enter image description here

| improve this answer | |
  • 2
    Please do not ask additional questions inside an answer to your own question. Instead create a new question for it or ask for clarification from user121799. – epR8GaYuh Aug 6 '19 at 10:05

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.