[Kstars-devel] Testing the use of quaternions in KStars

Jason Harris jharris at 30doradus.org
Mon Oct 2 05:02:01 CEST 2006


Hello,

I was excited to see the recently-announced[1] marble Desktop Globe by tackat.  
Looking at the code, it looks like there are concepts in marble that will be 
useful for KStars.

Specifically, marble uses a construct called a quaternion[2] to rotate and 
project the spherical globe in a 2-D widget.  A quaternion is a 4-vector that 
describes a position and direction in 3-dimensional space.  With quaternions, 
rotating a spherical coordinate system is a matrix multiplication, which is 
potentially much faster than the spherical trig that we currently employ in 
KStars.

This evening, I added experimental support for quaternions in KStars.  It was 
surprisingly easy to do.  I copied the Quaternion class from marble, and gave 
SkyPoint a Quaternion member that holds the SkyPoint's position expressed as 
a Quaternion (marble has a GeoPoint class that is analogous to SkyPoint, so 
this was easy).

I then added a Quaternion m_rotAxis member to SkyMap (following marble's 
KAtlasGlobe), that stores the current orientation of the skymap.  I also 
added a slotRotateTo( SkyPoint *p ) function, which uses functions in 
Quaternion to modify m_rotAxis such that point p is the focus point.  I then 
added slotRotateTo(focus()) to  SkyMap::setFocus(), so that the m_rotAxis 
variable remains in sync with focus changes.

All that remains is to modify SkyMap::toScreen() to use the Quaternions in 
SkyPoint and SkyMap.  This is where I expected a significant improvement in 
CPU usage.  I created toScreenQuaternion(), which is really simple:

QPointF SkyMap::toScreenQuaternion( SkyPoint *o, double scale ) {
	QPointF p;
	Quaternion oq = o->quat();
	oq.rotateAroundAxis( m_rotAxis );

	p.setX( 0.5*width()  - scale*oq.v[Q_X] );
	p.setY( 0.5*height() - scale*oq.v[Q_Y] );

	return p;
}

To test it, I added some timing code to time how long it takes to process 
126,000 stars through toScreen(), and through toScreenQuaternion().  The 
results:

toScreen():  22 ms
toScreenQuaternion():  31 ms

So either our spherical-trig method is almost 30% faster than the quaternion 
method, or I've done something wrong.  I don't see what it could be, because 
during timing, only the above function is being called.  In addition, 
additional math will be required to support other projection algorithms  
(quaternions inherently give you the Orthographic projection), so for these 
cases, quaternions will be even slower.

Anyway, if anyone wants to check it out in detail, I can send you the diffs.  
For now I guess we'll stick with what we have.

regards,
Jason

[1]: http://www.kdedevelopers.org/node/2412
[2]: http://en.wikipedia.org/wiki/Quaternion
-- 
Jason Harris
jharris at 30doradus.org


More information about the Kstars-devel mailing list