# Tikz: Draw A Wireframe Torus

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}
%% 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\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}


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

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

• 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)); – user121799 Nov 12 '17 at 2:05