4

I am trying to produce a figure of a wireframe torus, similar to the image produced by the following code which generates a wireframe sphere at a general "viewing angle":

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc,fadings,decorations.pathreplacing}
%% 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} % "THE GLOBE" showcase

\def\R{2.5} % sphere radius
\def\angEl{35} % elevation angle
\filldraw[ball color=blue!40!white!80!green!40!] (0,0) circle (\R);
\foreach \t in {-80,-60,...,80} { \DrawLatitudeCircle[\R]{\t} }
\foreach \t in {-5,-35,...,-175} { \DrawLongitudeCircle[\R]{\t} }

\end{tikzpicture}

\end{document}

enter image description here

This code fragment was taken from part of this texample.net page. I'm really quite unsure as to how to approach this problem. Seemingly I would want to parameterize the surface of the torus to draw the "Latitude" and "Longitude" lines, but I am not sure how to do so... Any insight into this problem would be greatly appreciated!

Note that any solution using any packages outsize TikZ/pgf are welcome.

  • Does How to draw a torus solves your problem? – Bobyandbob Nov 11 '17 at 16:39
  • Ideally I would have a "translucent" torus, where you can see the whole wireframe of the surface. I just edited the question with an image of the generated sphere. – pateryan Nov 11 '17 at 16:41
  • Specifically in a form that is as close to the above as possible. However in the worst case I will use one of those solutions. – pateryan Nov 11 '17 at 16:42
  • More like this=: How can I visualize a Torus with three paths? – Bobyandbob Nov 11 '17 at 16:42
  • @Bobyandbob, Yes that is much closer to what I had in mind! I'm pretty surprised at the volume of code required for the task in that thread. There must be a better way, no? – pateryan Nov 11 '17 at 16:44
3

I could not resist and stole my code almost entirely from this elegant answer. It is based on asymptote and reads

 \documentclass{article}
 \usepackage[inline]{asymptote}
 \begin{document}
 \begin{asy}
  size(200);
  import graph3;

  pen xarcPen=deepblue+0.7bp;
  pen yarcPen=deepred+0.7bp;

  currentprojection=perspective(5,4,4);

  int m=20;
  int n=10;
  real arcFactor=1;
  real R=2;
  real a=1;


  triple fs(pair t) {
    return ((R+a*Cos(t.y))*Cos(t.x),(R+a*Cos(t.y))*Sin(t.x),a*Sin(t.y));
  };

  pair p,q,v;

  for(int i=1;i<=n;++i){
    for(int j=0;j<m;++j){
      p=(j*360/m,(i%n)*360/n);
      q=(((j+arcFactor)%m)*360/m,i*360/n);
      v=(((j+arcFactor/2)%m)*360/m,i*360/n);
      //draw(fs(p)..fs(v)..fs(q),xarcPen,Arrow3(size=4));
      draw(fs(p)..fs(v)..fs(q),xarcPen);
      q=(j*360/m,((i%n)-arcFactor)*360/n);
      //draw(fs(p)..fs((p+q)/2)..fs(q),yarcPen,Arrow3(size=3));
      draw(fs(p)..fs((p+q)/2)..fs(q),yarcPen);
      dot(fs(p));
    }
  };


  surface s=surface(fs,(0,0),(360,360),8,8,Spline);
  draw(s,surfacepen=material(blue+opacity(0.6), emissivepen=0.2*white),render(compression=Low,merge=true));
 \end{asy}
 \end{document}
 \endinput

Suppose you call the TeX file lattice.tex, then invoke

pdflatex lattice
asy -f pdf -noprc -render=4 lattice-1.asy
pdflatex lattice

in order to obtain

enter image description here

  • Excellent! Thank you so much :). If I could bother you a little more, how would I go about removing the dots at intersection points? – pateryan Nov 12 '17 at 1:30
  • @pateryan just remove (or comment out) the line dot(fs(p)); – marmot Nov 12 '17 at 2: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.