Problems with rotations

Started by
20 comments, last by ma_hty 15 years, 11 months ago
ATM I think your desire is not 100% possible to be realized (but perhaps someone else from the cummunity will contradict). However, I furthur think you've several more-or-less good options to work around:

(a) Make the user clear that s/he is varying an Euler angle like set-up with the 3 sliders. This solution doesn't touch the math, but is IMHO user unfriendly, since the user shouldn't be burdened with such stuff.

(b) Rotate the molecule by the currently dragged slider always as an incremental rotation around the local axis, but decompose the resulting orientation back into its 3 angles, and adapt the sliders accordingly. This allows you to still show the absolute angles (but only w.r.t. the equivalent rotations of a defined order). DCC packages often offer this way.

(c) Don't use absolute angles but relative ones. I.e. remake the GUI so that pulling a slider's knob changes its belonging angle incrementally around the local axis, but releasing the knob lets it snap back to the neutral position. The molecule, on the other hand, is left as is. So at most one slider knob is outside of 0, and that only temporarily. This simulates a kind of turn table but with sliders, so restricting the kinds of rotation axes (see below).

(d) Drop the usage of slides totally, and go with the tool approach (e.g. turn table like). I.e. manipulate the model directly inside the view, not indirectly and beneath it. Besides the tool idea, this is similar to (c), but also allows for more or less arbitrary rotation axes.

(e) One of (b) or (c) above but using global axes.

Other options may exist, too. I personally would prefer the tool approach. But that is the opinion of a programmer of a 3D DCC editor, not of a chemist :)
Advertisement
Quote:Original post by zorro68
...
But I have seen that all of them has a problem, if you rotate the scene with the mouse you can see the rotation of the scene and it seems that is all ok. But you are rotating the scene sometimes around global axis and sometime around local axes.
...


This is a typical defect introduced by mapping Euler angle to the user interface directly. As long as you are using Euler angle honestly, there is no way you can solve this problem.

Why don't you give up Euler angle and use Axis-angle instead? If you are using Axis-angle correctly, there will not be such a problem. Well well, you are probably going to make a lengthy statements to defend your idea (that's what had happened repeatedly whenever there is discussion about Euler angle user interface).

Before you do it, please read the previous discussion about Euler angle user interface first.

I have been participated in those discussions too many times. Therefore, even if you are decided to defend your idea anyway, I am not going to join your discussion. Instead, I give you the source code of what a correctly designed Axis-angle user interface should look like (i.e. almost the ArcBall).
/////////////////////////// glutTest13.cpp//// Created by Gary Ho, ma_hty@hotmail.com, 2007//#include <stdio.h>#include <stdlib.h>#include <math.h>#include <GL/glut.h>#define PI 3.14159265358979323846ffloat v0[3], v1[3];float mo[16] = { 1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 };float clamp( float x, float a, float b );float dot( const float *a, const float *b );float norm( const float *a );void vassign( float *a, float x, float y, float z );void vassign( float *a, const float *b );void cross( float *a, const float *b, const float *c );void normalize( float *a );void display();void mousebutton(int button, int state, int x, int y );void mousemove(int x, int y);void main( int argc, char **argv ){  glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );  glutInitWindowSize( 512, 512 );  glutCreateWindow( "test09" );  glutDisplayFunc( display );  glutMouseFunc( mousebutton );  glutMotionFunc( mousemove );  glutMainLoop();}void display(){  GLint viewport[4];    glGetIntegerv( GL_VIEWPORT, viewport );  glEnable( GL_DEPTH_TEST );  glEnable( GL_LIGHTING );  glEnable( GL_LIGHT0 );  glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );  glMatrixMode(GL_PROJECTION);    glLoadIdentity();    gluPerspective( 45, double(viewport[2])/viewport[3], 0.1, 10 );    glMatrixMode(GL_MODELVIEW);    glLoadIdentity();    gluLookAt( 0,0,3, 0,0,0, 0,1,0 );    glMultMatrixf( mo );    glutSolidTeapot(1);  glutSwapBuffers();}void mousebutton(int button, int state, int x, int y ){  vassign( v0, 2.0*x/512-1, -2.0*y/512+1, 1 );  normalize(v0);}void mousemove(int x, int y){  float axis[3], angle;  vassign( v1, 2.0*x/512-1, -2.0*y/512+1, 1 );  normalize(v1);  if( v0[0]==v1[0] && v0[1]==v1[1] && v0[2]==v1[2] )    return;  cross(axis,v0,v1);  normalize(axis);  angle = acosf( clamp(dot(v0,v1),-1,1) );  vassign( v0, v1 );  glPushMatrix();    glLoadIdentity();    glRotatef( angle*180/PI, axis[0], axis[1], axis[2] );    glMultMatrixf( mo );    glGetFloatv( GL_MODELVIEW_MATRIX, mo );  glPopMatrix();  glutPostRedisplay();}float clamp( float x, float a, float b ){ return x<a ? a : (x<b?x:b); }float dot( const float *a, const float *b ){ return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]; }float norm( const float *a ){ return sqrtf(dot(a,a)); }void vassign( float *a, float x, float y, float z ){ a[0]=x; a[1]=y; a[2]=z; }void vassign( float *a, const float *b ){ a[0]=b[0]; a[1]=b[1]; a[2]=b[2]; }void cross( float *a, const float *b, const float *c ){  a[0] = b[1]*c[2] - c[1]*b[2];  a[1] = -b[0]*c[2] + c[0]*b[2];  a[2] = b[0]*c[1] - c[0]*b[1];}void normalize( float *a ){  float l = norm(a);  a[0]/=l; a[1]/=l; a[2]/=l;}


This user interface is probably the implementation you wanted.

Euler angle? Forget it, it is not going to work. If you insist to use Euler angle, find a rotation matrix in the above program, convert it to Euler angle for storage and then convert the Euler angle to rotation matrix for computation. Just make sure you are not doing any calculation using Euler angle (beside storage), everything will be fine. Is it sound more comforting?

[Edited by - ma_hty on May 9, 2008 3:24:30 PM]

This topic is closed to new replies.

Advertisement