600.660

Assignment 3 Resources

`SphericalGridViewer.exe`

: This executable provides an interactive tool for visualizing spherical functions. Running:

will open up an OpenGL window, visualizing the spherical function by displacing points on the surface of the sphere in proportion to the magnitude of the value of the function at the point. (Points with positive value are drawn in red, points with negative value are drawn in blue.)`% SphericalGridViewer function.sgrid`

You can interact with the visualization by:

- 'q' and 'w': Rotate the model about the
*y*-axis. - 'a' and 'z': Rotate the model about the
*x*-axis. - 's' and 'x': Rotate the model about the
*z*-axis. - sroll-wheel: Zooms in and out.

- 'q' and 'w': Rotate the model about the
`Mesh2SphericalGrid.exe`

: If you have access to 3D models in .ply format, you can use this executable to compute the spherical extent function. Running:

will read in the 3D model from "model.ply" and write out a "res"x"res"`% Mesh2SphericalGrid model.ply res model.sgrid`

`SphericalGrid`

to the file "model.sgrid". (Keep in mind that the implementations of the spherical harmonic transform and Wigner D-transform expect the resolution of the spherical grid to be a power of two.)

- cow1.sgrid and cow2.sgrid: The spherical extent functions of a cow in two different poses.
- dog.sgrid: The spherical extent function of a dog in a random orientation.
- plane.sgrid: The spherical extent function of a 747.
- stool.sgrid: The spherical extent function a bar-stool.
- cyclohexane.sgrid: The spherical extent function of a cyclohexane molecule.

**Indexing Coefficients**

In order to implement the assignment, you will need to represent a function on a sphere in terms of its spherical harmonic coefficients, and you will need to represent a function on the group of rotations in terms of its Wigner D-coefficients. To do this you will use the`FourierKeyS2`

and`FourierKeySO3`

classes respectively. Because it is assumed that the spherical and rotational functions are real-valued, there will be redundancy in these coefficients akin to the redundancy in the Fourier coefficients of real-valued circular functions. As a result, only half of the coefficients are stored, resulting in some tricky indexing:: Up to scaling, the spherical harmonic coefficients of a real-valued function have the property that (**FourierKeyS2***l*,-*m*)-th spherical harmonic coefficient is the complex conjugate of the (*l*,*m*)-th spherical harmonic coefficient. As a result, we only store the spherical harmonic coefficients for non-negative values of*m*.Given an instance of the

`FourierKeyS2`

class, the spherical harmonic coefficients can be accessed as follows:FourierKeyS2< > key;

for ( int i = 0 ; i < key.bandWidth( ) ; i++ )

for ( int j = 0 ; j <= i ; j++ )

{

key( i , j ) =...;

}

: Up to scaling, the Wigner D-coefficients of a real-valued function have the property that (**FourierKeySO3***l*,-*m*,-*m'*)-th coefficient is the complex conjugate of the (*l*,*m*,*m'*)-th coefficient. As a result, we only store the Wigner D-coefficients of the pairs of indices (*m*,*m'*) for which*m*is non-negative.Given an instance of the

`FourierKeySO3`

class, the Wigner D-coefficients can be accessed as follows:FourierKeySO3< > key;

Note that, in the implementation, the key value indexed by (

for ( int i = 0 ; i < key.bandWidth( ) ; i++ )

for ( int j = 0 ; j <= i ; j++ )

for ( int k = -i ; k <= i ; k++ )

{

key( i , j , k ) =...;

}

*i*,*j*,*k*) corresponds to the Wigner-D function*D*(_{i}^{kj}*R*) = <*ρ*(_{R}*Y*),_{i}^{k}*Y*>._{i}^{j}

**Accessing Arrays**

In order to implement the assignment, it may be more convenient to access spherical and rotational functions by explicitly using a 3D point or 3x3 rotation matrix. To help you with this, methods have been implemented to support this type of data look-up.: To access a spherical function you may want to use the coordinates of a 3D point rather than the 2D spherical index. To transition between the 2D(floating point) index and a 3D point, you should use the**SphericalGrid**`SphericalGrid::setCoordinates`

function:`SphericalGrid<Real>::setCoordinates(const Real& i,const Real& j,Real coords[3])`

: This method takes in a 2D index in the spherical array and returns the associated point on the unit sphere.`SphericalGrid<Real>::setCoordinates(const Real coords[3],const Real& i,const Real& j)`

: This method takes in a 3D point and returns the associated 2D index in the spherical array. (Note that the code will normalize the 3D point so that it has norm one, so you do not need to worry about this.)

: To access a rotational function you may want to use the entries of a 3x3 rotation matrix rather than the 3D Euler index. To transition between the 3D (floating point) index a rotation, you should use the**RotationGrid**`RotationGrid::setCoordinates`

function:`RotationGrid<Real>::setCoordinates(const Real& i,const Real& j,const Real& k,Real matrix[3][3])`

: This method takes in a 3D index in the rotational array and returns the 3x3 rotation matrix. (Note that matrix[*i*][*j*] corresponds to the entry in the matrix at column*i*and row*j*.)`Rotation<Real>::setCoordinates(const Real matrix[3][3],const Real& i,const Real& j,const Real& k)`

: This method takes in a rotation matrix and returns the associated 3D index in the rotational function.`Rotation<Real>::SetCoordinates(const Real axis[3],const Real& theta,Real matrix[3][3])`

: Given an axis an angle of rotation, this method will set the entries 3x3 of the matrix corresponding to this rotation.