22

I need to draw 3D lattice of DO3 type (Ni-Mn-Al, DO3) and more complex ones. Both TiKZ and PSTricks packages draw following objects on top of previously drawn disregarding "real" 3D position. For example, on this picture 2 red atoms on the right cover white ones, when they shouldn't.

\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}[->]
\draw (0,0) -- (4,0,0);
\draw (0,0) -- (0,4,0);
\draw (0,0) -- (0,0,4);
\foreach \x in {1,2,3}
\foreach \y in {1,2,3}
\foreach \z in {1,2,3}
        \draw (\x,\y,\z) circle (2pt);
\foreach \x in {1.5,2.5}
\foreach \y in {1.5,2.5}
\foreach \z in {1,2,3}
        \draw[gray,very thin] (\x,\y,\z) +(-.5,-.5) rectangle ++(.5,.5);
\foreach \x in {1,2,3}
        \draw (\x,1,1) -- (\x,1,3) (\x,2,1) -- (\x,2,3) (\x,3,1) -- (\x,3,3)  ;

\foreach \x in {1.5,2.5}
\foreach \y in {1.5,2.5}
\foreach \z in {1.5,2.5}
        \filldraw[red] (\x,\y,\z) circle (2pt);
\end{tikzpicture}
\end{document}

It is possible, to obtain right behavior with layers or certain order of the drawing. However for complex lattices it is very difficult and depends on view angle.

2
  • 1
    AFAIK, TikZ doesn't support a complete spatial model such as you need. You may get better results from ray-tracing software, maybe POVRay. Commented Feb 7, 2013 at 22:53
  • 1
    Another option is Asymptote. It can embed 3D models into PDFs, i.e., you could rotate the lattice when viewing the document with acroread.
    – Alex
    Commented Feb 8, 2013 at 15:54

1 Answer 1

19

Here's an Asymptote solution:

\documentclass{standalone}
\usepackage{asymptote}

\begin{document}

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

currentprojection=perspective(300,-650,500,center=true);


// define two types of ions
surface iona = scale3(20)*unitsphere;
surface ionb = scale3(25)*unitsphere;

// surface properties and color of the ions
material White = material(diffusepen=gray(0.4),emissivepen=gray(0.6));
material Red = material(diffusepen=red,emissivepen=lightred);

// style of lines connecting ions
pen thick=linewidth(2);

for(int x=-1; x<2; ++x) {
  for(int y=-1; y<2; ++y) {
    for(int z=-1; z<2; ++z) {
      draw(shift(100*(x,y,z))*iona,White);
    }
  }
}

for(int x=-1; x<2; ++x) {
  for(int y=-1; y<2; ++y) {
    for(int z=-1; z<2; ++z) {
      if(x<1) draw(100*(x,y,z)--100*(x+1,y,z),thick);
      if(y<1) draw(100*(x,y,z)--100*(x,y+1,z),thick);
      if(z<1) draw(100*(x,y,z)--100*(x,y,z+1),thick);
    }
  }
}

for(int x=-1; x<2; x+=2) {
  for(int y=-1; y<2; y+=2) {
    for(int z=-1; z<2; z+=2) {
      draw(shift(50*(x,y,z))*ionb,Red);
    }
  }
}
\end{asy}


\end{document}

To compile, first run pdflatex on the file, then asy on the generated .asy file, finally pdflatex once or twice again.

crystal lattice

5
  • 1
    Nice solution, but sadly I get a segmentation fault, when I try to compile your example with asy <filename>.asy. However if I use the -noprc option, i.e. asy -noprc <filename>.asy, everything goes fine. I'm using Windows 7 (64bit) and Asymptote 2.23. Is there something wrong with the code or is it my system?
    – Philipp
    Commented Jul 2, 2013 at 11:32
  • @Philipp Strange, could be some bug in Asymptote 2.2x or its interplay with the asymptote LaTeX package (which adds a few lines to the above asy code). With TeXLive 2012 and Asymptote 2.15 it works fine, with 2.20 and 2.23 I also get segfaults (on Linux). Needs further investigation...
    – Alex
    Commented Jul 2, 2013 at 15:08
  • Should I report it to the Asympotote people?
    – Philipp
    Commented Jul 2, 2013 at 15:21
  • @Philipp Yes, this doesn't seem to be a LaTeX problem. The segfault occurs for pdf with prc, other output formats work as expected.
    – Alex
    Commented Jul 2, 2013 at 16:06
  • 1
    I reported the bug and it has been fixed recently. With Asymptote version 2.24 everything should be fine again.
    – Philipp
    Commented Jul 14, 2013 at 2:36

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .