I am working in the field of Nanostructures and have to draw many figure like :
1 Answer
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:
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":
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 ifTikZ
- You can now influence the look of the bonds, e.g.
thin
ordashed
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:
And just the bonds:
-
15
-
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. May 5, 2012 at 22:33
-
I cannot differentiate the front parts from the rear ones. Is it possible to improve this appearance issue? May 6, 2012 at 2:32
-
I'm working on it. It will fade the color to white for the "back" atoms. May 6, 2012 at 11:05
-
pst-3d
?