Optimisation problem

Carl Banks imbosol at vt.edu
Tue Nov 12 16:41:10 EST 2002


"Simon Wittber (Maptek)" wrote:
> I have created a quaternion class which I am using for rotations in
> OpenGL.
> Usage goes something like this:
> 
> q = Quaternion(zRot, 0.0, 0.0, 1.0)
> glMultMatrixf(q.matrix)
> 
> Does anyone have any idea how I can optimise this code? It is going to
> be used in a very tight rendering loop. I would prefer to keep all the
> code in Python, and avoid writing any external modules.

> class Quaternion:
>        def __init__(self, degree, x, y, z):
>                self.matrix = range(16)
>                
>                angle = (degree / 180.0)  *
> 3.1415926535897932384626433832795
>                result = math.sin(angle / 2.0)
> 
>                self.w = math.cos(angle / 2.0)
>                self.x = x * result
>                self.y = y * result
>                self.z = z * result
>                self.__createMatrix()
> 
>        def __createMatrix(self):
>                self.matrix[0] = 1.0 - 2.0 * ( self.y * self.y + self.z
> * self.z )
>                self.matrix[1] = 2.0 * ( self.x * self.y - self.w *
> self.z )
>                self.matrix[2] = 2.0 * ( self.x * self.z + self.w *
> self.y )
>                self.matrix[3] = 0.0
>                
>                self.matrix[4] = 2.0 * ( self.x * self.y + self.w *
> self.z )
>                self.matrix[5] = 1.0 - 2.0 * ( self.x * self.x + self.z
> * self.z )
>                self.matrix[6] = 2.0 * ( self.y * self.z - self.w *
> self.x )
>                self.matrix[7] = 0.0
>                
>                self.matrix[8] = 2.0 * ( self.x * self.z - self.w *
> self.y )
>                self.matrix[9] = 2.0 * ( self.y * self.z + self.w *
> self.x )
>                self.matrix[10] = 1.0 - 2.0 * ( self.x * self.x + self.y
> * self.y )
>                self.matrix[11] = 0.0
>                
>                self.matrix[12] = 0.0
>                self.matrix[13] = 0.0
>                self.matrix[14] = 0.0
>                self.matrix[15] = 1.0



Simon,

First I must ask a question:

Is this the only time you use the Quaternion?  In other words, do you
create the Quaternion from the arguments, use it to create the matrix,
and never use it again?

If so, you don't want to use a class at all.  Just write a function
that takes degree, x, y, and z as arguments and returns the matrix.
(In fact, if the function only appears in your code once, you probably
should not bother with a function at all.)


However, I suspect the Quaternion has all kinds of operations defined,
and that you create the quaternion far from where you use it to create
a matrix in the loop.  Obviously, you can't do away with the
Quaternion class then.

So, concentrating on the create matrix function.  First, think about
using the array module.  It is a standard module that comes from the
Python distribution, and is often much faster than lists for
homogenous numercial arrays.  Arrays appear to be acceptable as
arguments to Python OpenGL.  For this particular use of it, I don't
know if it'll be faster, but it's worth a try.

If you do use a list, it might be faster to just construct the matrix
directly, rather than setting individual elements:

   self.matrix = [ 1.0 - 2.0*(y*y+z*z),
                   2.0*(x*y-w*z), ... ]

And, as others have said, use local variables, and try to save
multiplications by factoring common operations.



-- 
CARL BANKS



More information about the Python-list mailing list