Technolithic's picture

Arbitrary Axis Rotations

This is not OpenTK specific, but may be something that someone more gifted than myself could integrate into OpenTK because it is not available in OpenGL nor Direct3D.

It seems like the use of arbitrary axis rotations would be used much of the time with 3D objects and it's a wonder to me why a common library hasn't been created for abstracting the complexities away from the developer. Simple routines for handling quaternion calculations and transformations are available, but how to actually implement them is beyond the capabilities of my last remaining seared brain cell. Through a long pursuit to understand how the use of quaternions apply to rotations about axes and rotations about the newly calculated axes, the journey has lead me wandering in a circle in search for the answer.

To help clarify what I'm trying to accomplish, I'm developing a user interface that needs to rotate a 3D model with the use of a mouse. Rotations can occur in all 3 axes, but only 2 of them at a time, since the mouse has only 2D coordinates. After a rotation occurs, the axis needs to be changed to facilitate an intuitive rotation upon the next call for a rotation. For example, the axis of rotation about the y-axis will change as the other axes are altered. A rotation about the y-axis occurs when the user drags the mouse left or right. When the user rotates about the x-axis, the y-axis needs to be adjusted so that next time the user requests a rotation about the y-axis, the model rotates about the newly-calculated y-axis. As an analogy, if the model in the graphics viewport was a marble, a drag of the mouse would make the marble roll in the direction of the mouse movement. After the user releases the marble, a new rotation axis could be assumed and the user could drag the marble to a new location with an intuitive rolling motion.

I'm open to alternate approaches to using quaternions for accomplishing this; however, I've considered using Euler angles with no interest because of the gimbal lock problem. Any suggestions are appreciated.


Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Kamujin's picture

IMO, that's what an engine is for.

At this level, the difficulty of understanding Quaternions is on par with other topics in the toolkit.

Personally, I am looking for as little interference as possible.

Technolithic's picture

That sounds great, thanks. I bought the newest Harry Potter book in search of the answer. I think Dumbledoor will reveal it to Harry Potter and if I read between the lines I should be able to pick it up before the evil Dimentors come to get me and take all my happy memories away.

Expecto Patrona, Kamujin.

I'll figure it out eventually. Somebody has to create their own engines with as little interference as possible.

archangelwar's picture

There is no need to get snippy with him, as he is totally correct. OpenTK is a wrapper for the OpenGL functionality, and OpenGL is a simple, low-level graphics API. The functionality you are asking for is the domain of a graphics engine, which OpenTK is not. From the "About" page under the Project heading:

Managed OpenGL and OpenAL bindings, with automatic extension loading.
Cross-platform OpenGL Control for Windows.Forms.
Integrated math toolkit (vectors, matrices, quaternions), directly usable by OpenGL and OpenAL.
TrueType/FreeType font support.
CLS compliant. Use OpenTK with C#, VB.Net, IronPython, Boo and any other Mono/.Net language.
Compile once - run everywhere!

I do not see graphics engine written anywhere above. If you want a graphics engine, you should be looking at Torque or Ogre, etc.

Now, if you are willing to listen to an answer to your problem, then read further. Otherwise, throw some more Harry Potter insults into your reply box, as that is sure to get you the help you need.

You pretty much answered your own question in your post. If you want to have true 3D independence of rotation, everytime you perform a rotation, you should create local "axes" for your object that are rotated the same as your model. Then, when you peform the next rotation, you perform it about these local axes instead of world aligned axes.

OpenTK includes a math library with a Quaternion implementation just for this purpose under the OpenTK.Math namespace. To create an arbitrary axis quaternion, you simply create an OpenTK.Math.Quaternion structure, and call the Quaternion.FromAxisAngle(Vector3 axis, float angle). This will correctly initialize your Quaternion structure for an axis angle rotation. Then to create your transformation matrix, just make a matrix and call the Matrix.Rotate(Quaternion q) method, which will use your Quaternion to create a rotation matrix, and then you use it just like normal.

Also, if you know your quaternion math, you can just use a quaternion to always store your rotational series and simply multiply in your new rotations.

But all of this depends on you actually doing a bit of research into the functionality of quaternions. You can ignore most of the math that describes "why" quaternions work and just focus on how to use them. There are millions of examples on the internet, if you simply read the part of your Harry Potter book that details how to use the magic known as "Google." If you want an object abstraction that will perform all of your rotational needs through a simple method call, then I again point you towards a graphics engine implementation. I recommend Ogre. Otherwise, write one yourself.

Technolithic's picture

I found an article using google that mostly explains how to use quaternions; however, the article leaves out some details that had to be filled in by a plethora of other articles I eventually found. None of the articles discussed anything about built-in libraries to handle quaternions, instead they went into the details of coding my own procedures to handle them. Knowledge of the OpenTK math library IS useful to know, since it abstracts this from the tedious intricacies. Column major order along with W,X,Y,Z value orders within each row helped throw me off track even more, since the articles I found use array syntax that fails to explain whether the W is the first or last value in each row.

Sorry about making it appear like I'm an arrogant listener, but 3 lines of text hardly offers even concise help with using quaternions, unless we're talking about mentioning a math library. The magic of google has revealed a lot of information to me about quaternions; however, the implementation of them remains often loosely defined with missing details.

When I started this project I had no idea that I would need a graphics engine. I believe I've gone too far to suddenly shift the entire design of the project because of a single feature the user desires, so I'm pretty well stuck with going forth into manipulating and applying quaternions within my own pseudo-graphics-engine.

I believe I'm well on my way to getting this thing figured out. Thank you for the tip on OpenTK's math library, that helps me get away from some of the gross details. Had I payed attention to the math toolkit features the world would be a better place.