39

I am doing a report on the Ising model, without going into the complex details of the model, in its two-dimensional form it involves a lattice of points.

Lattice of Points

Which, when periodic boundary conditions are imposed can be though of as on a torus.

For clarification, what I mean by "periodic boundary conditions" is that the right neighbour to a point in the far right column is a point in the far left column in the same row, and the bottom neighbour to a point in the bottom row is a point in the top row in the same column.

Torus

Therefore, what I want to do is plot a grid on a torus, and place dots on that grid.

I also eventually want to place arrows going from one point to the next on the torus, as I did here for the lattice:

Sweep through lattice

I'm just having a lot of trouble trying to put it all together. How can this be achieved with Tikz? If not with Tikz, then how can be achieved at all?

Thank you in advance for any answers or comments.

I've done a fair bit of research on drawing a torus:

And a few other things:

And if it helps, here is the source code to the drawings I made in this post:

\begin{tikzpicture}
    \clip (-1,-1) rectangle (6cm,6cm); 
    \draw[style=help lines,thick] (0,0) grid[step=.5cm] (5,5);

    \foreach \x in {0,1,...,10}
    {
        \foreach \y in {0,1,...,10}
        {
            \node[draw,circle,inner sep=2pt,fill] at (.5*\x,.5*\y) {};
        }
    }
\end{tikzpicture}

and...

\begin{tikzpicture}
    \clip (-1,-1) rectangle (6cm,6cm); 

    \foreach \x in {0,1,...,10}
    {
        \foreach \y in {10,9,...,0}
        {
            \node[draw,circle,inner sep=1pt,fill] at (.5*\x,.5*\y) {};
            \draw[thick,->] (.5*\x,.5*\y) -- (.5*\x+.4,.5*\y);
            \draw[thick,->] (.5*\x,.5*\y) -- (.5*\x,.5*\y-.4);
        }
    }
\end{tikzpicture}

My only request is that graphics created in non-LaTeX applications like InkScape, Blender, etc not be suggested.

NictraSavios
  • 1,697
  • 6
    I think you really want to look into Asymptote for these kinds of 3D diagrams. – Jake Dec 05 '13 at 14:04
  • Mathematica is the best choice. – kiss my armpit Dec 05 '13 at 14:37
  • 2
    @DonutE.Knot I don't have access to Mathematica, nor the money to purchase it. – NictraSavios Dec 05 '13 at 14:42
  • 3
    @DonutE.Knot Student + Thesis + Broken Laptop + New Apartment = not happening. Anyway, this is off topic. If you'd like to continue, we should do so in chat. – NictraSavios Dec 05 '13 at 14:49
  • 2
    @DonutE.Knot I've been using Mathematica since version 3 and used to be a fan of it. However, for serious computations it is to slow and memory hungry. Graphics look nice on screen, but if you export they are huge or crap. – Alex Dec 05 '13 at 17:43

2 Answers2

44

enter image description here

Edit A bug fixed (the outer equator midpoints was not calculated correctly, as pointed out by @Dror).

MWE with Asymptote, file lattice.asy:

size(200);
import graph3;

pen surfPen=rgb(1,0.7,0);
pen xarcPen=deepblue+0.7bp;
pen yarcPen=deepred+0.7bp;

currentprojection=perspective(5,4,4);

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));
}

surface s=surface(fs,(0,0),(360,360),8,8,Spline);
draw(s,surfPen,render(compression=Low,merge=true));

int m=20;
int n=10;
real arcFactor=0.85;

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));
    q=(j*360/m,((i%n)-arcFactor)*360/n);
    draw(fs(p)..fs((p+q)/2)..fs(q),yarcPen,Arrow3(size=3));
    dot(fs(p));
  }
}

Compile with asy -f pdf -noprc -render=4 lattice.asy to get a standalone lattice.pdf.

g.kov
  • 21,864
  • 1
  • 58
  • 95
  • It looks great, the only reason I choose the other answer is because it looks more "scientific". – NictraSavios Dec 05 '13 at 19:36
  • I get this mess when I render yours: http://s30.postimg.org/rijii354x/Page_1_torus_latice.jpg – NictraSavios Dec 06 '13 at 02:46
  • @NictraSavios: The command should be asy -f pdf -noprc -render=4 lattice.asy as noted. – g.kov Dec 06 '13 at 05:52
  • Got it, I wasn't using the render command because it errored on my machine. Turns out Ubuntu's in-repository package doesn't support it, so I compiled from source and it worked. See here: http://tex.stackexchange.com/questions/148622/surfaces-rendered-using-asymptote-wont-layer-correctly – NictraSavios Dec 07 '13 at 13:42
  • Very nice solution! Is there some artifact along the (outer) equator of the torus? – Dror Dec 11 '13 at 07:22
  • @Dror: Thanks for pointing this out. It was a bug (a miscalculated midpoints), see the edited version. – g.kov Dec 11 '13 at 12:00
  • Could you provide an answer with Asymptote as well here http://tex.stackexchange.com/a/70116/19356 especially for the helix wrapping the torus? I believe your answer will be the best and fastest to compile. :-) – kiss my armpit Dec 12 '13 at 03:59
  • I meant the helix wrapping another helix wrapping the torus. – kiss my armpit Dec 12 '13 at 04:03
  • @Donut E. Knot: I respect your request and will try if I can turn my head around this. It's just a busy time of the year, so don't expect a quick response. – g.kov Dec 12 '13 at 06:17
  • @Stiff Jokes: Check out the Charles Staats' third-order helix solution, it looks like the answer to your request. – g.kov Dec 14 '13 at 06:50
32

Are you thinking about something like this?

\documentclass{standalone}
\usepackage{asymptote}

\begin{document}

\begin{asy}[width=10cm,height=10cm]
import graph3;
import three;

size3(200);
currentprojection=orthographic(3,3,5);
currentlight=light(gray(0.4),specularfactor=3,viewport=true,
           (-0.5,-0.25,0.45),(0.5,-0.5,0.5),(0.5,0.5,0.75));

int nb = 20, ns = 10;
real rb = 5.0, rs = 2.0;

triple torus(pair z) {

  return ((rb + rs*cos(2*pi*z.x/ns))*cos(2*pi*z.y/nb),
      (rb + rs*cos(2*pi*z.x/ns))*sin(2*pi*z.y/nb),
      rs*sin(2*pi*z.x/ns));

}

surface site = scale3(0.1)*unitsphere;

for(int k1=0; k1<ns; ++k1) {
  for(int k2=0; k2<nb; ++k2) {
    draw(surface(torus((k1,k2))--torus((k1+1,k2))--torus((k1+1,k2+1))--torus((k1,k2+1))--cycle),
     lightgray);
    draw(torus((k1,k2))--torus((k1+1,k2)),Arrow3);
    draw(torus((k1,k2))--torus((k1,k2+1)),Arrow3);
    draw(shift(torus((k1,k2)))*site,red);
  }
}
\end{asy}

\end{document}

enter image description here

It's made with Asymptote.

Alex
  • 5,362
  • 5
    What sorcery is this! It's... it's beautiful... if it weren't free, I'd force the developers to take my money. Heck, I'll do it anyway! "Give me a donate button for I'll show up at your house" I say! Thank you! – NictraSavios Dec 05 '13 at 15:37
  • Really nice! Would it be very complicated to use round surfaces instead of planar ones (i.e. circular arcs for the arrows instead of straight lines)? – Jake Dec 05 '13 at 15:39
  • Can it do 2D graphics as well? – NictraSavios Dec 05 '13 at 15:41
  • That's impressive and in less than a page of code! – Alexander Dec 05 '13 at 15:42
  • 1
    @Jake No, it's not complicated, have a look at the gallery. – Alex Dec 05 '13 at 15:49
  • For some reason my torus is angled differently than the one you have here.... – NictraSavios Dec 05 '13 at 17:05
  • @NictraSavios You can change the projection, number of points, etc... – Alex Dec 05 '13 at 17:38
  • 2
    I know, but I can't figure out how. The documentation isn't that good and not well indexed. – NictraSavios Dec 05 '13 at 19:34
  • @NictraSavios Change the line currentprojection=orthographic(3,3,5);. The three numbers define the point (x,y,z) in space from which you look at the torus (which is in the xy-plane and centered at (0,0,0)). You can also switch to perspective projection, see the other answer. – Alex Dec 05 '13 at 20:54
  • Okay, I got it to somewhat work, but it looks a little messed up, can you tell me why its rendering so badly? http://s9.postimg.org/gepzmsg6n/Page_1_torus_latice.jpg – NictraSavios Dec 06 '13 at 02:38
  • Figured it out! Nevermind. See here: http://tex.stackexchange.com/questions/148622/surfaces-rendered-using-asymptote-wont-layer-correctly – NictraSavios Dec 07 '13 at 13:41