You are here

Examples for technical illustration


  • Planetary Landscapes
  • Digital Molecular Models
  • A Nuclear Magnetic Resonance Magnet

Whew! We've come a long way. Let's look at some objects that might come up in technical circumstances -- illustrations of things that could appear in a technical training session, or a college class, or a lab manual.

Planetary Landscapes

Planets, in general, are spherical or nearly so, and are easy to represent in POV-Ray. Because of POV-Ray's detailed treatment of light and surface properties, stunning images are easy to create.

Let's make a rendition of the Earth-Moon system -- seen from outside, from several different vantage points. To do this, POV-Ray will need some sort of map of the Earth and Moon. Having found them:

#include "colors.inc"
#include "textures.inc"
#include "finish.inc"

//1 POV-Ray unit = 1000 km
//Earth is approx. 150 e6 km from Sun
//Moon is approx. 384 e3 km from Earth

camera {location <-2000,0,149.9E3> look_at <100,0,150E3> angle 1}
light_source {<0,0,0> color rgb<1,1,0.9>}  //Sun


POV-Ray units can be set to essentially any scale. For added realism, I'm using values actually corresponding to the distances between Sun, Earth, and Moon. I chose 1 POV-Ray unit to equal 1000 km.

I'm also representing the Sun with a point light. It isn't one -- from Earth it's about 30 arcminutes across -- but for the purposes of this depiction, a point source is fine.

#declare Earth = sphere {
 <0,0,0>, 6.38

 pigment {image_map {gif "earthmap.gif" map_type 1}}
 finish {ambient 0.01 diffuse 0.85 specular 0 roughness 0.01}
 }


#declare Moon = sphere {
 <0,0,0>, 1.74
 pigment {image_map {gif "moonmap2.gif" map_type 1}}
 finish {ambient 0 diffuse 0.95 specular 0 roughness 0.5}
 }


These dimensions for the Earth and Moon are accurate to several km, neglecting centrifugal flattening effects. The pigment here is a special type called image_map. image_map "pastes" a bitmapped image onto an object. To use it, type image_map followed by the image file type, file name, and the map_type. map_type is 0 for a flat map, 1 for a sphere, and 2 for a cylinder. POV-Ray supports several file types for image map pigments, but only GIF and PNG are likely to be widely available. The maps I used were converted from JPEG files from the Mister Print web site.

The finishes I used are fairly hypothetical. They're almost free of highlights, and have a high value of diffuse to make the contrast between lighted and dark regions high.

object {Earth translate <0,0,150E3>}
object {Moon translate <384,0,150E3>}

Move the two bodies out an appropriate distance: 150,000,000 km from the origin (i.e., the Sun). The Moon averages 384,000 km from Earth, so to simplify the geometry I've put it perpendicular to the Sun-Earth vector, at 384,000 km along the x-axis.

I've set the camera to be 2 million miles from Earth, in a direction opposite the Moon, looking at a point in between the two. I've also set the angle small -- 1 degree -- which mimics a low-power telescopic view of the pair. The rendered result:

earthmoon.jpg

Almost as good as being there...There is one serious problem, though. The Earth map I used didn't have any clouds, so the rendition looks a little odd. You could create a fairly realistic cloud layer by making a translucent sphere slightly larger than the Earth object, spotted with an appropriate pigment pattern.

The Moon doesn't have any clouds, so that's not an issue for it. Let's move our camera a bit and zoom in on the Moon. Change the one line:

camera {location <7,0,150E3> look_at <384,0,150E3> angle 1}


leaving the rest of the file the same. This is roughly the view of the Moon from Earth orbit. The result:

Mare Crisium and some of the other prominent features of the first-quarter Moon are visible!

Finally, let's zoom over a bit and look at lunar farside, the half of the Moon never visible from Earth. Move the camera to:

camera {location <500,0,149.95E3> look_at <384,0,150E3> angle 2}


earthmoon3.jpg

And there's the dark farside crater Tsiolkovski just below center.

Digital Molecular Models

If you've taken any college chemistry courses, you're probably familiar with a molecular model set: a box of plastic balls with holes in them to represent atoms, and a bunch of sticks to make chemical bonds between atoms. You can use POV-Ray to do much the same thing.

Let's make a couple of simple molecules: water, ammonia, and methane. We'll represent the atoms with conventional colors in model kits:







Atom typeColor
Hydrogen White
Carbon Black
Nitrogen Blue
Oxygen Red

I'll start the scene file out with some color and texture declarations:

#include "colors.inc"
#include "finish.inc"

camera {location <0,0,-10> look_at <0,0,0>}
light_source {<0,0,-50> color White}
background {color Gray80}

#declare BallFinish = finish {phong 0.9 phong_size 50 ambient 0.01 diffuse 0.7}
#declare StickFinish = finish {phong 0.25 phong_size 2 ambient 0.01 diffuse 0.5}


These finishes will give the balls a nice hard plastic appearance, and the bonds ("sticks") a softer, more diffuse look.

#declare HydrogenColor = color rgb <1,1,1>
#declare CarbonColor = color rgb <0.1,0.1,0.1>
#declare NitrogenColor = color rgb <0,0.2,1>
#declare OxygenColor = color rgb <1,0.1,0.1>


Traditional colors, or close to them. Next, atomic radii, treating 1 POV-Ray unit as 1 angstrom.

//atomic (VdW) radii in angstroms:  R. Chang, _Chemistry_ 3rd edition (1988)
#declare HydrogenSize = 0.32
#declare CarbonSize = 0.91
#declare NitrogenSize = 0.92
#declare OxygenSize = 0.73
//for ball and stick, want atoms to be well-separated from each other
//for space filling, need actual bond lengths
#declare StickLength = 1.5


Then individual atoms as textured spheres, which I'll use later:

#declare Hydrogen = sphere {<0,0,0>, HydrogenSize 
                     texture {pigment {color HydrogenColor} 
                              finish {BallFinish}
                     } }
#declare Carbon = sphere {<0,0,0>, CarbonSize 
                     texture {pigment {color CarbonColor} 
                              finish {BallFinish}
                     } }
#declare Nitrogen = sphere {<0,0,0>, NitrogenSize 
                     texture {pigment {color NitrogenColor} 
                              finish {BallFinish}
                     } }
#declare Oxygen = sphere {<0,0,0>, OxygenSize 
                     texture {pigment {color OxygenColor} 
                              finish {BallFinish}
                     } }


#declare Bond = cylinder {<0,0,0>, <0,StickLength,0>, 0.1
                     texture {pigment {Gray50} finish {StickFinish}}}


Finally, render each atom once to show what they look like:

object {Hydrogen translate -x*3}
object {Carbon translate -x}
object {Nitrogen translate x}
object {Oxygen translate x*3}


molecules.jpg

Let's make a water molecule. That requires two hydrogens and an oxygen, and to help keep track of the bonds, I'll attach a bond to each hydrogen atom before putting it into position. I've set things up so that bonds will initially be made along the y axis, after which I can rotate them to any position about the central atom.

#declare Bond_H = union {
 object {Hydrogen translate <0,StickLength,0>}
 object {Bond}
 }

#declare Water = union {
 object {Oxygen}
 object {Bond_H}
 object {Bond_H rotate z*105}
 }

object {Water}


Here, I've taken each hydrogen atom and set it up so that its center is at the end of one of the bonds, which start at the origin. The bonds have a length of StickLength, and initially extend along the y-axis. In water, the angle between the two O-H bonds is 105 degrees. So, to make water, put an oxygen atom in the middle, and put two hydrogen+bond units on it, rotating one by 105 degrees:

molecules2.jpg

Virtual water.

Let's make some more complicated molecules.

For water, the two O-H bonds lie in the same plane. For ammonia, NH3, the N-H bonds don't -- they form a pyramidal shape. However, since the molecule is symmetric -- the three H atoms lie on the vertices of an equilateral triangle -- it's easy to position them by figuring out the orientation of one N-H bond, then rotating copies of it to those vertices.

In ammonia, the angle the N-H bonds make with the "axis" of the pyramid shape is 107 degrees. Let's make the axis of our pyramid the y-axis, along which the bonds are drawn initially. To position the N-H bonds, first rotate them 107 degrees away from that axis (e.g., by rotating them about x or z), then rotate them to the points of an equilateral triangle centered on the molecule's symmetry axis (in this case, y):

#declare Ammonia = union {
 object {Nitrogen}
 object {Bond_H rotate z*107 rotate y*0}
 object {Bond_H rotate z*107 rotate y*120}
 object {Bond_H rotate z*107 rotate y*240}
 }

object {Ammonia}


Also, I'll change the camera and light source a bit, so all three bonds are visible.

camera {location <4,0,-8> look_at <0,0,0> angle 40}
light_source {<0,50,-50> color White}


Here's the result:

molecules3.jpg

Finally, let's make methane. Methane has four C-H single bonds, all at the classic tetrahedral angle of 109.5 degrees. Making methane is much the same as making ammonia, again because of the symmetry -- the fourth C-H bond goes along the symmetry axis (here, as in ammonia, the y-axis).

#declare Methane = union {
 object {Carbon}
 object {Bond_H rotate z*0 rotate y*0}
 object {Bond_H rotate z*109.5 rotate y*0}
 object {Bond_H rotate z*109.5 rotate y*120}
 object {Bond_H rotate z*109.5 rotate y*240}
 }
object {Methane}


molecules4.jpg

For these examples, I've used symmetry to help make the molecules. Thus, you could easily make something like CO2 and HCN, which are linear; SF6, which is octagonal; and XeF4, which is square planar. Using POV-Ray for chemical models is excellent for illustrating molecular shape in introductory chemistry courses, especially since POV-Ray can scale and rotate the molecules arbitrarily.

For more complex molecules, like those encountered in organic chemistry and biochemistry, it would be necessary to calculate the positions of each atom, put an atom there, and stick a bond in between the atoms. This rapidly becomes tedious, and is outside the scope of this document. Fortunately there are already many molecules with coordinates calculated for each of their atoms. The PDB (Protein Data Bank) is a superb resource for protein and nucleic acid atomic coordinates, for example. Furthermore, several people have written programs that will take files in PDB format and produce models much like the ones I've used above. Many of these programs are free, and extremely useful for molecular display.

A Nuclear Magnetic Resonance Magnet

Nuclear magnetic resonance (NMR) is a powerful analytical technique chemists and physicists use to investigate the structure and dynamics of molecules. Many atomic nuclei act like little magnets, and much as two bar magnets resist being turned so their like poles touch, these atomic magnets resist "turning" when in a magnetic field. By measuring the energies associated with "turning" these miniature atomic magnets, scientists learn a great deal about the molecules containing these atoms.

As you might imagine, the heart of an NMR instrument is a large magnet. Permanent magnets and regular electromagnets are too weak to be useful, so NMR spectroscopists use a superconducting magnet, which holds a strong current with little resistance and can produce extremely high magnetic fields (over 100,000 times as strong as the Earth's natural magnetic field). For example, here's the magnet I used as a graduate student in Illinois, when I was studying protein structure by NMR:

Let's have POV-Ray create a schematic picture of this magnet, something that you might put in a laboratory guidebook to illustrate the various components of the magnet. The dimensions I'll be using are approximate, with one POV-Ray unit corresponding roughly to 0.1 meter.

Here's the source code for the scene. We'll go through it bit by bit.

//Raytracing an NMR lab with magnet...

#include "colors.inc"
#include "shapes.inc"
#include "textures.inc"
#include "finish.inc"
#include "metals.inc"

camera  {location <-35,18,-30>
        look_at <10,12,0> angle 50}

plane {y, 0 pigment {color Tan}}
plane {z, +50 pigment {brick color Gray30, color Gray70}}
plane {z, -100 pigment {brick color Gray30, color Gray70}}
plane {x, +50 pigment {brick color Gray30, color Gray70}}
plane {x, -50 pigment {brick color Gray30, color Gray70}}

light_source { <1, 25, -50> color White}
light_source { <-50, 25, 0> color White}


This sets up a basic, simple room. It starts with our include files, a camera, and a light source, and has a smooth tan floor and brick-patterned walls.

Let's draw the magnet. It's fairly symmetric, and it's easiest to make it out of pieces, starting with the large canister that makes up its center:

#declare Canister = union {

//Main part of magnet
cylinder {<0,0,0>,<0, 10, 0>, 5.0}

//Rounded top part
difference {
  sphere {<0, -2,0>, 13}
   
  box{ <-15,-15,-15>,<15,10,15>}
 
 }
texture{T_Chrome_4B}
} // canister


First, define a cylinder, in this case 10 units high and 10 in diameter. The real magnet is, in fact, roughly 1 meter wide and 1 in diameter. I've arbitrarily set the cylinder to start at the origin; eventually, once I assemble the whole magnet, I'll move it to a better place.

Next comes the smooth top, which is about 0.1 meters high, or 1 POV-Ray unit. A good object for this is a truncated sphere. The hard part here is figuring out how to make the sphere so that the sliced portion has the same radius as the cylinder, 5, while being 1 unit high. For this, it's time to dredge up a relationship from geometry:

chords.jpg

A x B = C x D

In this case, C = D = 5 units (the radius of the cylinder), and A = 1 unit (the height of the top). Also, the radius of the sphere must be (A+B)/2. The result? The sphere needs to have a radius of 13. I create the sphere so that its highest point is 11 POV-Ray units up (i.e., one unit above the top of the cylinder) and then chop off the bottom with a box. The box's top is at y=10, so the bottom of the truncated sphere will be flush with the top of the cylinder. Finally, I made a union from the cylinder and the top piece, and give them a predefined texture from metals.inc, T_Chrome4B, which simulates a moderately reflective chrome (or other uncolored metal) surface.


#declare Magnet = union {
//Bore...
 difference {
   object {Canister}
   cylinder {<0,-1,0>,<0,12,0>, 0.75
   open }
   }
 //protuberances ... first, N2 tubes
 cylinder{<-3,10,-3>,<-3,13,-3>,0.4}
 cylinder{<-3,10,3>,<-3,13,3>,0.4}

 //then He tubes...
 cylinder{<2,10,3>, <2, 17, 3>,0.8}
 cylinder{<2,10,-3>, <2, 17, -3>,0.8}
 
 //then the tube connector thingy
 cylinder {<2,16,3.5>, <2,16,-3.5>, 0.5}

 texture{T_Chrome_4B}}
 // magnet


The magnet itself has a narrow bore running through it, so samples can be loaded into it. This calls for a difference of the canister and an open cylinder along the canister's axis, but slightly longer and narrower (diameter 1.5 POV-Ray units). This produces a cylindrical hole down the middle of the canister.

Next, there are tubes on the top of the magnet, which are access ports for coolants. To keep the magnet superconducting, liquid helium cools the inside, and liquid nitrogen helps keep the liquid helium from evaporating quickly. The access ports are vertical tubes on top of the magnet, offset from the central bore a little bit.

There are several short cylinders, two representing the liquid nitrogen ports, and two interconnected cylinders representing the liquid helium ports. Note that the cylinders protrude slightly into the top of the sphere, which is at +11 -- this is simply to make sure there are no gaps between the sphere and the cylinders. A smaller value of overlap (say, 0.5 or even 0.01) is fine -- use whatever amount prevents gaps. It's a good idea to have objects overlap slightly; just remember to use merge instead of union if they're transparent, to make sure the overlapping bits aren't visible inside.

Finally, let's make whole thing a union and call it Magnet.

#declare Leg = union {

 cylinder{<3.5,1,0>, <3.5,-10,0>, 1.00}
 cylinder{<3.5,-9.75, 0>, <3.5,-10.5,0>, 1.5}
 texture {
   pigment {color Gray10}
   finish {Dull}} 
 }

#declare Legs = union {
  object {Leg}
  object {Leg rotate <0, 120, 0>}
  object {Leg rotate <0, 240, 0>}
  cylinder {<0, -10.5, 0>, <0,-11,0>, 6
   pigment {color White}
   finish {Dull}}
 }


Here are the legs that support the magnet. Each leg comprises a long cylinder and a short, flat base plate; a union of these makes up Leg. Since the bottom of the canister is at the origin -- y=0 -- the legs extend to negative values of y. Also, as with the coolant ports, the legs extend a little bit into the canister.

Instead of the shiny T_Chrome4B texture we used for the magnet canister, I'll use the finish Dull, which resembles flat paint. To make the triangle of legs, simply take three legs and rotate them around the y-axis to the corners of an equilateral triangle. Finally, I've attached a large, thin cylinder to the legs to make a "baseplate" for the floor, and then made a union of the leg assembly.

 #declare NMR = union {
 object{Magnet}
 object{Legs}
 translate <-15,11,0>
 }

object {NMR}


And the magnet's just about done. This last bit of code combines the magnet and the leg objects, and moves the magnet to its final position -- a bit off to the left, and with the baseplate sitting directly on the floor. Render this at 320x240, and add anti-aliasing, with +A on the command line (or a menu setting in a GUI version). The result:

nmr-demo.jpg

This gives a reasonably good representation. For a more precise rendition, I'd do two things. First, I'd get exact measurements, rather than the somewhat schematic ones I've used. Second, with some more work, I'd add the details -- a slightly ripply outer surface (a good time to use a normal pattern), some more of the attachments like the hoses and the brackets on the legs, and so on.

Congratulations! You now know the general idea behind POV-Ray and how to use it for a variety of purposes. Now, go have some fun with it!

Theme by Danetsoft and Danang Probo Sayekti inspired by Maksimer