Subsections

2.1 Surfaces

   In OESpicoli, the surface is presented as a first-class object, ie, an object in its own right, named OESurface. This presentation requires a minimalist definition similar to the way OEChem represents molecules as a collection of atoms and bonds. Basically, both OESurfaces and OEMolBases represent a graph in computer memory.

An OESurface provides two ways of retrieving data. The first is a set of methods that will return a copy of the entire data array. The second are a set of methods with the Element suffix that allow random access directly into the array of data. Basic usage of both will be shown for vertices and triangles.

2.1.1 Vertices

   The simplest datum in a surface is the vertex: a set of (x, y, z) coordinates. Vertices are stored internally as an array of size GetNumVertices() * 3 * sizeof(float). Equivalent dimensions are stored at every third place in the array as shown by Figure 2.1.

Figure 2.1: Vertices Array
 
$x_{1}$ $y_{1}$ $z_{1}$ $x_{2}$ $y_{2}$ $z_{2}$ $x_{3}$ $y_{3}$ $z_{3}$ ...

A copy of this array can be obtained using the code fragment in Listing 2.1, where surf is a OESurface object.

float *coords = new float[surf.GetNumVertices()*3];
surf.GetVertices(coords);

Listing:2.1 Copy of vertices

For direct access to the vertex array use the Element version of GetVertices. Listing 2.2 is a code fragment that shows how to iterate over all the vertex coordinates of a surface.

float x, y, z;
for(unsigned int i=0; i < surf.GetNumVertices(); ++i)
{
  x = surf.GetVerticesElement(i * 3);
  y = surf.GetVerticesElement(i * 3 + 1);
  z = surf.GetVerticesElement(i * 3 + 2);
}

Listing:2.2 Iterating over vertices

2.1.2 Triangles

   A triangle in OESpicoli is a set of three vertices. However, it is important that the order of these vertices be locally consistent. To maintain this consistency vertices of the triangles are defined in a clockwise fashion.

Consider the two triangles in Figure 2.2 defined by the vertices A, B, C, D. The triangle on the left is defined by the set (A, B, C). The triangle on the right is defined by the set (D, B, A). Also notice how the edge AB is defined in both triangles but in opposite order. This reversal of order in the two definitions is a direct consequence of the clockwise ordering rule.

Figure 2.2: Two Triangles in Spicoli
 


\begin{picture}(9,6)\thinlines
\put(1,1){\line(3,4){3}}
\put(4,5){\line(1,-...
...)[t]}
\put(5.5,3.4){\oval(1,1)[bl]}
\put(6,3.4){\vector(0,-1){.2}}
\end{picture}

All the methods of construction described in this document obey this rule. A surface that does not follow this rule can still be operated on by OESpicoli, but it is not considered a canonical surface and some results may be incorrect or ambiguous.

OESpicoli stores triangle vertices as an integer array of size GetNumTriangles() * 3 * sizeof(unsigned int). Each integer is an index into the vertex array explained in Section 2.1.1. Listing 2.3 is a code fragment that will retrieve a copy of the entire triangles array.

unsigned int *triangles = new unsigned int[surf.GetNumTriangles()*3];
surf.GetTriangles(triangles);

Listing:2.3 Copy of triangles

For direct access to the triangle array, use the Element version of GetTriangles. Listing 2.4 is a code fragment that shows how to iterate over all the triangles of a surface.

unsigned int v1, v2, v3;
for(unsigned int i=0; i < surf.GetNumTriangles(); ++i)
{
  v1 = surf.GetTrianglesElement(i * 3);
  v2 = surf.GetTrianglesElement(i * 3 + 1);
  v3 = surf.GetTrianglesElement(i * 3 + 2);
}

Listing:2.4 Iterating over triangles

2.1.3 Normal Vectors

   The emphasis on triangle vertex ordering is to support the notion of the triangle's front and back. The front of the triangle is the side that the vertices appear ordered in a clockwise fashion. Surface normals can then be calculated to point out from the front of the triangle (and conversely from the back of the triangle).

The OESurface also supports vertex normals since vertices are often easier to work with analytically. Vertex normals are calculated by averaging all of the face normals of triangles of which the vertex is a part. Figure 2.3 contrasts the differences between face and vertex normals respectively.

Figure 2.3: Surface Normals
 
[Face Normal]
\begin{picture}(15,12)
\par\thinlines
\par
\put(0,0){\line(2,1){12}}
\put(12...
...ine(-1,0){1}}
\put(5,7){\line(0,-1){1}}
\put(4.5,6){\line(1,0){2}}
\end{picture}
[Vertex Normals]
\begin{picture}(15,12)(15,0)
\par
\put(16,0){\line(2,1){12}}
\put(28,6){\line(-2...
...(0,1){2}}
\put(28,6){\vector(0,1){2}}
\put(20,10){\vector(0,1){2}}
\end{picture}

Vectors in OESpicoli are represented by three floating point values. Normal vectors are always of unit length. They can be calculated and stored on the OESurface object by invoking the free functions OECalculateNormals and OECalculateFaceNormals for vertex and face normals, respectively.

It is important to remember that the size of a normal array is determined by whether it is a face or vertex normal. For example the size of the vertex normal array is GetNumVertices() * 3 * sizeof(float). While the size of the face normal array is GetNumTriangles() * 3 * sizeof(float).

2.1.4 Specific Data

   Specific data is any information that can be derived from the surface alone but not from any specific triangle or vertex. Currently these properties include the following:

Curvature
(float) Solvent accessibility of the vertex
Distance
(float) The Euclidean distance to the vertex from another portion of the surface

Curvature follows a pragmatic computational chemistry definition. It is a property of solvent molecules, represented as spheres, packed onto the surface. Figure 2.4 demonstrates the two dimensional case of how solvent molecules are packed onto a surface. The first sphere is mapped adjacent to the vertex using the vertex's normal. Two more spheres are then packed adjacent to the surface and the starting sphere. The angle between these two spheres is used to calculate the accessibility to solvent of the initial sphere using the following formula:


\begin{displaymath}
100 * \frac{\unit{\theta}{\radian} - \unit{\pi}{\radian}}{\unit{\pi}{\radian}}
\end{displaymath} (2.1)

For this simple case the angle is also a measure of the surface curvature, hence the name. In three dimensions steradians are required to accomplish the same functional form:


\begin{displaymath}
100 * \frac{\unit{\theta}{\steradian} - \unit{2\pi}{\steradian}}{\unit{2\pi}{\steradian}}
\end{displaymath} (2.2)

Therefore, a vertex's ``curvature'' falls into a range with the following bounds:

-100.0
Solvent that is completely secluded within the surface
0.0
Flat portion of the surface
100.0
Solvent that is completely detached from the surface

Figure 2.4: Surface Curvature
 
[Concave (negative value)]
\begin{picture}(50,35)(0, 5)
\par\thinlines
\put(15,25){\circle{14}}
\put(25,...
..., 8.0)(45.0, 33.0)
\par
\qbezier(25.0, 8.0)(11.25, 8.0)(5.0, 33.0)
\end{picture}
[Flat (zero)]
\begin{picture}(50,35)(50, 5)
\par\thinlines
\put(61,20){\circle{14}}
\put(75...
...0711)(65.0, 24.1421)(65.0, 20.0)
\par
\put(52, 13){\line(1,0){46}}
\end{picture}
[Convex (positive value)]
\begin{picture}(50,35)(100, 5)\thinlines
\put(113,17){\circle{14}}
\put(125,2...
...5675)
\par
\qbezier(135.0, 25.0)(135.0, 21.9722)(133.3205, 19.453)
\end{picture}

Distance is listed as specific data because it can be derived as the distance between different portions of the surface. This can be useful for measuring the thickness of a volume that is enclosed by a surface. Distances can also be measured to other arbitrary objects as well, such as molecules and other surfaces.

2.1.5 Associative Data

   Associative data is not inherent from the first-class object definition of a surface. Instead, they are properties mapped onto the surface. OESpicoli provides the following associative data arrays:

Atoms
(unsigned int) Atom index for the vertex
Color
(4 floats or 4 unsigned chars) Color of the vertex
Potential
(float) Electrostatic potential at the vertex

To map chemical properties onto a surface it is useful to know which atoms are responsible for portions of the surface. When a surface is constructed from a molecule, a data array containing the corresponding atom index for each vertex is created. An atom's index can be obtained from the OEAtomBase::GetIdx method and is unique over the molecule. The reader can refer to the OEChem manual for more information about atom indices.

To display chemical properties it is often useful to render them as either discrete colors or a spectrum of colors. The color data array allows the user to set a color for every vertex in the surface. When the surface is then read into a visualizer, such as Vida, the properties can easily be interpreted. Every vertex has the associated values: red, green, blue, and alpha. Alpha is the transparency of the vertex. If any value is retrieved as a float, then that value will range from 0 to 1 inclusive. If retrieved as an unsigned char, the value will range from 0 to 255 inclusive.

Electrostatic potentials can be calculated and displayed on a surface. This can be done with current OpenEye tools such as Zap or another application.

The potentials array is essentially an array of floats the user can use to record analytical data for each vertex.