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 want to draw a 3D diamond crystal structure. The point where I struggle is quite in the beginning to draw connecting 3D rods:

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[english]{babel}
\usepackage{geometry}
\usepackage{pstricks}
\usepackage{pst-solides3d}

\begin{document}
 \begin{pspicture}(-4,-4)(14,14)
  \psSolid[object=cylindre,h=6,r=1,fillcolor=yellow,](0,0,0)
  \psSolid[object=sphere,r=2,fillcolor=red!25](0,0,0)
  \psSolid[object=sphere,r=2,fillcolor=red!25](0,0,6)
 \end{pspicture}
\end{document}

Desired result

In the end it should describe the cubic cell of diamond, e.g. like the following picture from Phase Transformations & Complex Properties Research Group. Cubic cell of diamond

Comments

share|improve this question
    
that is not really easy. See melusine.eu.org/syracuse/pstricks/pst-solides3d/doc/… and following pages –  Herbert Oct 30 '13 at 7:37

3 Answers 3

up vote 9 down vote accepted

Since you included the asymptote tag, I assume you will not object to an Asymptote solution:

%process:
% pdflatex filename.tex
% asy filename-*.asy
% pdflatex filename.tex
\documentclass{standalone}
\usepackage{asymptote}
\begin{document}
\begin{asy}
import three;
settings.render=8;
settings.prc=false;
size(10cm);

currentprojection = orthographic((3,4,5));

material spherecolor = material(diffusepen=black, ambientpen=gray(0.1), specularpen=white);
material cylcolor = material(diffusepen=white, ambientpen=white);

real cylRadius = 0.1;
real sphereRadius = 0.2;

void drawRod(triple a, triple b) {
  surface rod = extrude(scale(cylRadius)*unitcircle, axis=length(b-a)*Z);
  triple orthovector = cross(Z, b-a);
  if (length(orthovector) > .01) {
    real angle = aCos(dot(Z, b-a) / length(b-a));
    rod = rotate(angle, orthovector) * rod;
  }
  draw(shift(a)*rod, surfacepen=cylcolor);
}

void drawSphere(triple center) {
     draw(shift(center)*scale3(sphereRadius)*unitsphere, surfacepen=spherecolor);
}

triple a = O;
triple b = X;
triple c = 2Z;

drawSphere(a);
drawSphere(b);
drawSphere(c);
drawRod(a,b);
drawRod(b,c);
\end{asy}
\end{document}

gives the output

share|improve this answer
    
Could you provide a bigger one? –  Who is crazy first Oct 30 '13 at 16:12
    
@Marienplatz: If this is a joke that the image I've uploaded is a bit large, I agree but am not sure how to change that. Otherwise, I don't understand your request; are you asking for a picture with more nodes? –  Charles Staats Oct 30 '13 at 16:15
    
The former is correct. :-) –  Who is crazy first Oct 30 '13 at 16:23
1  
@CharlesStaats Very nice solution. It's a pitty that render=0 never really works on such pictures, though (render=8 is fine of course, but I simply like vector images :)). I've taken the liberty of scaling down your output picture: I usually use something like <img src="http://i.stack.imgur.com/Umw1B.png" height="400"> for that. I hope you don't mind. –  Philipp Oct 31 '13 at 16:09
    
@Philipp: Great improvement. I'll remember that for the future. –  Charles Staats Nov 10 '13 at 20:16

According to the hints in the answer of Charles Staats, I wrote the explicit code in asymptote (page of the developper).

Resulting figure - unit cell of diamond

enter image description here

Latex file with asymptote code

\documentclass{standalone}
\usepackage{asymptote}

\begin{document}
\begin{asy}
import three;
settings.render=8;
settings.prc=false;
size(10cm);

//currentprojection=perspective((45,45,30));
currentprojection = orthographic((3,6,1));

material sphereCcolor = material(diffusepen=black, ambientpen=gray(0.1), specularpen=white);
material cylcolor = material(diffusepen=white, ambientpen=white);

real cylRadius = 0.1;
real sphereRadius = 0.25;

void drawRod(triple a, triple b) {
  surface rod = extrude(scale(cylRadius)*unitcircle, axis=length(b-a)*Z);
  triple orthovector = cross(Z, b-a);
  if (length(orthovector) > .01) {
    real angle = aCos(dot(Z, b-a) / length(b-a));
    rod = rotate(angle, orthovector) * rod;
  }
  draw(shift(a)*rod, surfacepen=cylcolor);
}

void drawCarbon(triple center) {
     draw(shift(center)*scale3(sphereRadius)*unitsphere, surfacepen=sphereCcolor);
}

triple Aa = (0,0,0);
triple Ab = 4X;
triple Ac = 4Y;
triple Ad = 4X+4Y;
triple Ae = 2X+2Y;
triple Ba = 1X+1Y+1Z;
triple Bb = 3X+3Y+1Z;
triple Ca = 2X+2Z;
triple Cb = 2Y+2Z;
triple Cc = 4X+2Y+2Z;
triple Cd = 2X+4Y+2Z;
triple Da = 3X+1Y+3Z;
triple Db = 1X+3Y+3Z;
triple Ea = 4Z;
triple Eb = 4X+4Z;
triple Ec = 4Y+4Z;
triple Ed = 4X+4Y+4Z;
triple Ee = 2X+2Y+4Z;

drawRod(Ba,Aa);
drawRod(Ba,Ae);
drawRod(Bb,Ae);
drawRod(Bb,Ad);
drawRod(Ba,Ca);
drawRod(Ba,Cb);
drawRod(Bb,Cc);
drawRod(Bb,Cd);
drawRod(Da,Ca);
drawRod(Da,Cc);
drawRod(Db,Cb);
drawRod(Db,Cd);
drawRod(Da,Eb);
drawRod(Da,Ee);
drawRod(Db,Ee);
drawRod(Db,Ec);

drawCarbon(Aa);
drawCarbon(Ab);
drawCarbon(Ac);
drawCarbon(Ad);
drawCarbon(Ae);
drawCarbon(Ba);
drawCarbon(Bb);
drawCarbon(Ca);
drawCarbon(Cb);
drawCarbon(Cc);
drawCarbon(Cd);
drawCarbon(Da);
drawCarbon(Db);
drawCarbon(Ea);
drawCarbon(Eb);
drawCarbon(Ec);
drawCarbon(Ed);
drawCarbon(Ee);

// Frame
material framecolor = material(diffusepen=white, ambientpen=yellow);
void drawFrame(triple a, triple b) {
  surface rod = extrude(scale(.5*cylRadius)*unitcircle, axis=length(b-a)*Z);
  triple orthovector = cross(Z, b-a);
  if (length(orthovector) > .01) {
    real angle = aCos(dot(Z, b-a) / length(b-a));
    rod = rotate(angle, orthovector) * rod;
  }
  draw(shift(a)*rod, surfacepen=framecolor);
  draw(shift(b)*scale3(cylRadius)*unitsphere, surfacepen=framecolor);
}
drawFrame((0,0,0),4X);
drawFrame((0,0,0),4Y);
drawFrame((0,0,0),4Z);
drawFrame(4X,4X+4Y);
drawFrame(4X,4X+4Z);
drawFrame(4Y,4Y+4X);
drawFrame(4Y,4Y+4Z);
drawFrame(4Z,4X+4Z);
drawFrame(4Z,4Y+4Z);
drawFrame(4X+4Y+4Z,4Y+4Z);
drawFrame(4X+4Z,4X+4Y+4Z);
drawFrame(4X+4Y,4X+4Y+4Z);
\end{asy}
\end{document}
share|improve this answer
2  
very nice, I inserted a higher resolution image, you can roll back the change if you feel it's overkill, but I felt a prettier picture would do more justice to your code. –  PatrickT Feb 16 at 17:23

You want hidden lines and surfaces, the reason why you have to collect all objects by a significant name and then build a fusion object:

\documentclass{scrartcl}
\usepackage{pst-solides3d}

\psset{lightsrc=viewpoint,viewpoint=80 10 10 rtp2xyz,Decran=40}
\begin{document}
 \begin{pspicture}[solidmemory](-4,-4)(14,14)
  \psset{object=sphere,r=2,fillcolor=red!25,action=none}
  \psSolid[object=cylindre,h=6,r=0.5,fillcolor=yellow,name=C](0,0,0)
  \psSolid[name=S1](0,0,0)
  \psSolid[name=S2](0,0,6)
  \psSolid[name=S3](0,6,6)
  \defFunction[algebraic]{FIV}(t){0}{t}{t}% x(t)=0, y(t)=t, z(t)=t
  \psSolid[object=courbe,range=0 6,ngrid=16 16,function=FIV,r=0.5,
           fillcolor=black!20,name=L1]
%
  \psSolid[object=fusion,base=C S1 S2 S3 L1,linewidth=0.2pt,action=draw**]  
 \end{pspicture}
\end{document}

enter image description here

share|improve this answer

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.