Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I am working in the field of Nanostructures and have to draw many figure like : enter image description here enter image description here

share|improve this question
7  
It's generally good to show what you've tried so far... have you looked at the manual for pst-3d? –  cmhughes May 4 '12 at 8:52
8  
Could you please accept an answer by clicking the the tick button on the upper left side of the answer, just below the voting arrows. This way you are concluding the question and assign some reputation to the answerer and you. If the question isn't fully answer yet, please state so by commenting on it or editing your question. Please do this also for you other questions. At the moment you have a 0% accept rate, which doesn't look good to other people. Thank you. –  Martin Scharrer May 12 '12 at 9:19
    
Considering the solution provided is exactly what you asked for, and extremely well explained, it seems unkind (to say the least) not to accept that answer neither thank him. –  Fèlix Galindo Allué May 26 '12 at 13:34

1 Answer 1

How about this:

\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{tikz}
\usetikzlibrary{3d}


\begin{document}

\pgfmathtruncatemacro{\tubelength}{5} % in "double hexagon lengths"
\pgfmathtruncatemacro{\tubecirumferenceatoms}{12} 
\pgfmathsetmacro{\tuberadius}{3}
\newcommand{\carboncolor}{red}
\newcommand{\bondcolor}{black}

\tikzset{yzplane/.style={canvas is yz plane at x=#1,very thin}}

\begin{tikzpicture}[x={(-0.2cm,-0.5cm)}, y={(1cm,0cm)}, z={(0cm,1cm)}]
\foreach \x in {1,...,\tubelength}
{ \foreach \y in {1,...,\tubecirumferenceatoms}
    {   \pgfmathsetmacro{\ycoord}{cos(\y/\tubecirumferenceatoms*360)*\tuberadius}
        \pgfmathsetmacro{\zcoord}{sin(\y/\tubecirumferenceatoms*360)*\tuberadius}
        \draw[thick,\bondcolor] (\x*3+0.5,\ycoord,\zcoord) -- (\x*3+1.5,\ycoord,\zcoord);
    }
    \begin{scope}[yzplane=\x*3+0.5]
        \foreach \y in {1,...,\tubecirumferenceatoms}
    {   \shade[ball color=\carboncolor] (\y/\tubecirumferenceatoms*360:\tuberadius) circle (0.2) ;
    }
    \end{scope}

    \foreach \y in {1,...,\tubecirumferenceatoms}
    {   \pgfmathsetmacro{\ycoord}{cos(\y/\tubecirumferenceatoms*360)*\tuberadius}
        \pgfmathsetmacro{\zcoord}{sin(\y/\tubecirumferenceatoms*360)*\tuberadius}
        \pgfmathsetmacro{\rotangle}{\y/\tubecirumferenceatoms*360+360/2/\tubecirumferenceatoms}
        \pgfmathsetmacro{\ycoordtwo}{cos(\rotangle)*\tuberadius}
        \pgfmathsetmacro{\zcoordtwo}{sin(\rotangle)*\tuberadius}
        \pgfmathsetmacro{\rotanglethree}{\y/\tubecirumferenceatoms*360-360/2/\tubecirumferenceatoms}
        \pgfmathsetmacro{\ycoordthree}{cos(\rotanglethree)*\tuberadius}
        \pgfmathsetmacro{\zcoordthree}{sin(\rotanglethree)*\tuberadius}
        \draw[thick,\bondcolor] (\x*3+1.5,\ycoord,\zcoord) -- (\x*3+2,\ycoordtwo,\zcoordtwo);
        \draw[thick,\bondcolor] (\x*3+1.5,\ycoord,\zcoord) -- (\x*3+2,\ycoordthree,\zcoordthree);
    }
    \begin{scope}[yzplane=\x*3+1.5]
        \foreach \y in {1,...,\tubecirumferenceatoms}
    {   \shade[ball color=\carboncolor] (\y/\tubecirumferenceatoms*360:\tuberadius) circle (0.2);
    }
    \end{scope}

    \foreach \y in {1,...,\tubecirumferenceatoms}
    {   \pgfmathsetmacro{\rotangle}{\y/\tubecirumferenceatoms*360+360/2/\tubecirumferenceatoms}
        \pgfmathsetmacro{\ycoord}{cos(\rotangle)*\tuberadius}
        \pgfmathsetmacro{\zcoord}{sin(\rotangle)*\tuberadius}
        \draw[thick,\bondcolor] (\x*3+2,\ycoord,\zcoord) -- (\x*3+3,\ycoord,\zcoord);
    }
    \begin{scope}[yzplane=\x*3+2]
        \foreach \y in {1,...,\tubecirumferenceatoms}
    {   \pgfmathsetmacro{\rotangle}{\y/\tubecirumferenceatoms*360+360/2/\tubecirumferenceatoms}
        \shade[ball color=\carboncolor] (\rotangle:\tuberadius) circle (0.2);
    }
    \end{scope}

    \foreach \y in {1,...,\tubecirumferenceatoms}
    {   \pgfmathsetmacro{\ycoord}{cos(\y/\tubecirumferenceatoms*360)*\tuberadius}
        \pgfmathsetmacro{\zcoord}{sin(\y/\tubecirumferenceatoms*360)*\tuberadius}
        \pgfmathsetmacro{\rotangle}{\y/\tubecirumferenceatoms*360+360/2/\tubecirumferenceatoms}
        \pgfmathsetmacro{\ycoordtwo}{cos(\rotangle)*\tuberadius}
        \pgfmathsetmacro{\zcoordtwo}{sin(\rotangle)*\tuberadius}
        \pgfmathsetmacro{\rotanglethree}{\y/\tubecirumferenceatoms*360-360/2/\tubecirumferenceatoms}
        \pgfmathsetmacro{\ycoordthree}{cos(\rotanglethree)*\tuberadius}
        \pgfmathsetmacro{\zcoordthree}{sin(\rotanglethree)*\tuberadius}
        \draw[thick,\bondcolor] (\x*3+3.5,\ycoord,\zcoord) -- (\x*3+3,\ycoordtwo,\zcoordtwo);
        \draw[thick,\bondcolor] (\x*3+3.5,\ycoord,\zcoord) -- (\x*3+3,\ycoordthree,\zcoordthree);
    }
    \begin{scope}[yzplane=\x*3+3]
        \foreach \y in {1,...,\tubecirumferenceatoms}
    {   \pgfmathsetmacro{\rotangle}{\y/\tubecirumferenceatoms*360+360/2/\tubecirumferenceatoms}
        \shade[ball color=\carboncolor] (\rotangle:\tuberadius) circle (0.2);
    }
    \end{scope}


}
\end{tikzpicture}

\end{document}

You can modify a few things:

  • The length of the tube (multiples of 4 atoms)

  • The amount of atoms on one circle

  • The radius of the tube

  • The color of the atoms

  • The color of the bonds

The above produces:

enter image description here


Edit 1: If you play around with the settings, e.g. like

\pgfmathtruncatemacro{\tubelength}{20} % in "double hexagon lengths"
\pgfmathtruncatemacro{\tubecirumferenceatoms}{20} 
\pgfmathsetmacro{\tuberadius}{4}
\newcommand{\carboncolor}{red!80!black}
\newcommand{\bondcolor}{blue!20!black}

you get this, which looks a lot "nanotubier":

enter image description here


Edit 2:

  • The "back" atoms now fade to white, the "back" bonds now fade to gray
  • As I don't know which atoms will be in the back (depends on your choice of xyz-axes), I added a key \initialrotationangle which rotates the tube by that angle, you'll have to find a good value yourself
  • Before, the "bondlength" was a static value of 1, which looked bad for small radii, so now it's computed dynamically (it does not account for the curvature of the cylinder, so it might look bad for very small values of \tubecircumferenceatoms)
  • The atom size also was static before, now you can specify it as a fraction of the bondlength. You can set this fraction to zero to have just the "bond net" without any atoms
  • As I computed the coordinates for the bonds anyway, I now compute the ones for the atoms as well and therefore got rid of the 3D library if TikZ
  • You can now influence the look of the bonds, e.g. thin or dashed to your liking

And here's the new code. I'm aware that I have several loops running over \y, but I can not put everything in one loop, as their order is important for drawing foreground and background things.

\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{tikz}

\begin{document}

\pgfmathtruncatemacro{\tubelength}{10} % in "double hexagon lengths"
\pgfmathtruncatemacro{\tubecirumferenceatoms}{12} 
\pgfmathsetmacro{\tuberadius}{3}
\newcommand{\carboncolor}{red}
\newcommand{\bondcolor}{blue}
\pgfmathsetmacro{\initialrotationangle}{270}
\pgfmathsetmacro{\atombondlengthfraction}{0.2}
\newcommand{\bonddrawoptions}{thin}

\begin{tikzpicture}[x={(-0.2cm,-0.5cm)}, y={(1cm,0cm)}, z={(0cm,1cm)}, scale=0.5]
\foreach \x in {1,...,\tubelength}
{ \pgfmathsetmacro{\bondlength}{2*3.14159265*\tuberadius/sqrt(3)/\tubecirumferenceatoms}
    \pgfmathsetmacro{\atomradius}{\bondlength*\atombondlengthfraction}
    \foreach \y in {1,...,\tubecirumferenceatoms}
    {   \pgfmathsetmacro{\rotangle}{\y/\tubecirumferenceatoms*360}
        \pgfmathsetmacro{\ycoord}{cos(\rotangle)*\tuberadius}
        \pgfmathsetmacro{\zcoord}{sin(\rotangle)*\tuberadius}
        \pgfmathtruncatemacro{\shadingcolor}{50*cos(\rotangle+\initialrotationangle)+50}
        \draw[\bonddrawoptions,\bondcolor!\shadingcolor!gray] (\x*3*\bondlength+0.5*\bondlength,\ycoord,\zcoord) -- (\x*3*\bondlength+1.5*\bondlength,\ycoord,\zcoord);
        \shade[ball color=\carboncolor!\shadingcolor] (\x*3*\bondlength+0.5*\bondlength,\ycoord,\zcoord) circle (\atomradius*1cm) ;
    }

    \foreach \y in {1,...,\tubecirumferenceatoms}
    {
        \pgfmathsetmacro{\ycoord}{cos(\y/\tubecirumferenceatoms*360)*\tuberadius}
        \pgfmathsetmacro{\zcoord}{sin(\y/\tubecirumferenceatoms*360)*\tuberadius}
        \pgfmathsetmacro{\rotangle}{\y/\tubecirumferenceatoms*360+360/2/\tubecirumferenceatoms}
        \pgfmathsetmacro{\ycoordtwo}{cos(\rotangle)*\tuberadius}
        \pgfmathsetmacro{\zcoordtwo}{sin(\rotangle)*\tuberadius}
        \pgfmathsetmacro{\rotanglethree}{\y/\tubecirumferenceatoms*360-360/2/\tubecirumferenceatoms}
        \pgfmathsetmacro{\ycoordthree}{cos(\rotanglethree)*\tuberadius}
        \pgfmathsetmacro{\zcoordthree}{sin(\rotanglethree)*\tuberadius}
        \pgfmathtruncatemacro{\shadingcolor}{50*cos(\rotangle+\initialrotationangle)+50}
        \draw[\bonddrawoptions,\bondcolor!\shadingcolor!gray] (\x*3*\bondlength+1.5*\bondlength,\ycoord,\zcoord) -- (\x*3*\bondlength+2*\bondlength,\ycoordtwo,\zcoordtwo);
        \draw[\bonddrawoptions,\bondcolor!\shadingcolor!gray] (\x*3*\bondlength+1.5*\bondlength,\ycoord,\zcoord) -- (\x*3*\bondlength+2*\bondlength,\ycoordthree,\zcoordthree);
        \shade[ball color=\carboncolor!\shadingcolor] (\x*3*\bondlength+1.5*\bondlength,\ycoord,\zcoord) circle (\atomradius*1cm);
    }

    \foreach \y in {1,...,\tubecirumferenceatoms}
    {   \pgfmathsetmacro{\rotangle}{\y/\tubecirumferenceatoms*360+360/2/\tubecirumferenceatoms}
        \pgfmathsetmacro{\ycoord}{cos(\rotangle)*\tuberadius}
        \pgfmathsetmacro{\zcoord}{sin(\rotangle)*\tuberadius}
        \pgfmathtruncatemacro{\shadingcolor}{50*cos(\rotangle+\initialrotationangle)+50}
        \draw[\bonddrawoptions,\bondcolor!\shadingcolor!gray] (\x*3*\bondlength+2*\bondlength,\ycoord,\zcoord) -- (\x*3*\bondlength+3*\bondlength,\ycoord,\zcoord);
        \shade[ball color=\carboncolor!\shadingcolor] (\x*3*\bondlength+2*\bondlength,\ycoord,\zcoord) circle (\atomradius*1cm);
    }

    \foreach \y in {1,...,\tubecirumferenceatoms}
    {   \pgfmathsetmacro{\ycoord}{cos(\y/\tubecirumferenceatoms*360)*\tuberadius}
        \pgfmathsetmacro{\zcoord}{sin(\y/\tubecirumferenceatoms*360)*\tuberadius}
        \pgfmathsetmacro{\rotangle}{\y/\tubecirumferenceatoms*360+360/2/\tubecirumferenceatoms}
        \pgfmathsetmacro{\ycoordtwo}{cos(\rotangle)*\tuberadius}
        \pgfmathsetmacro{\zcoordtwo}{sin(\rotangle)*\tuberadius}
        \pgfmathsetmacro{\rotanglethree}{\y/\tubecirumferenceatoms*360-360/2/\tubecirumferenceatoms}
        \pgfmathsetmacro{\ycoordthree}{cos(\rotanglethree)*\tuberadius}
        \pgfmathsetmacro{\zcoordthree}{sin(\rotanglethree)*\tuberadius}
        \pgfmathtruncatemacro{\shadingcolor}{50*cos(\rotangle+\initialrotationangle)+50}
        \draw[\bonddrawoptions,\bondcolor!\shadingcolor!gray] (\x*3*\bondlength+3.5*\bondlength,\ycoord,\zcoord) -- (\x*3*\bondlength+3*\bondlength,\ycoordtwo,\zcoordtwo);
        \draw[\bonddrawoptions,\bondcolor!\shadingcolor!gray] (\x*3*\bondlength+3.5*\bondlength,\ycoord,\zcoord) -- (\x*3*\bondlength+3*\bondlength,\ycoordthree,\zcoordthree);
    }
    \foreach \y in {1,...,\tubecirumferenceatoms}
    { \pgfmathsetmacro{\rotangle}{\y/\tubecirumferenceatoms*360+360/2/\tubecirumferenceatoms}
        \pgfmathsetmacro{\ycoordtwo}{cos(\rotangle)*\tuberadius}
        \pgfmathsetmacro{\zcoordtwo}{sin(\rotangle)*\tuberadius}
        \pgfmathtruncatemacro{\shadingcolor}{50*cos(\rotangle+\initialrotationangle)+50}
        \shade[ball color=\carboncolor!\shadingcolor] (\x*3*\bondlength+3*\bondlength,\ycoordtwo,\zcoordtwo) circle (\atomradius*1cm);
    }

}
\end{tikzpicture}

\end{document}

And a few samples:

enter image description here

And just the bonds:

enter image description here

share|improve this answer
12  
Awesome! How about sending it to texample.net? –  Speravir May 5 '12 at 22:31
    
Probably, but not yet. It still has several flaws that I want to work out first, and I think I can simplify it quite a bit. So maybe when I'm done. –  Tom Bombadil May 5 '12 at 22:33
    
I cannot differentiate the front parts from the rear ones. Is it possible to improve this appearance issue? –  In PSTricks we trust May 6 '12 at 2:32
    
I'm working on it. It will fade the color to white for the "back" atoms. –  Tom Bombadil May 6 '12 at 11:05
    
Absolutely amazing! –  Yiannis Lazarides May 6 '12 at 12:32

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.