Java-Gaming.org    
Featured games (78)
games approved by the League of Dukes
Games in Showcase (427)
Games in Android Showcase (89)
games submitted by our members
Games in WIP (466)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  3D rotation  (Read 2773 times)
0 Members and 1 Guest are viewing this topic.
Offline gmseed

Senior Newbie





« Posted 2008-07-29 21:43:55 »

Hi

I have the following method that draws a cylinder using gluCylinder().

The GL quadric is oriented so that its axis is along the z-axis (0,0,1). Since my Cylinder object can be arbitrarily oriented it is necessary to correctly rotate the cylinder. This is done using the method directionAngles(), which computes the direction angles between the rotated cylinder z-axis and the fixed global axes (1,0,0), (0,1,0) and (0,0,1).

For cylinder axes (1,0,0) and (0,1,0) the cylinder is correctly oriented. However, if I set the axis to lie along th z-axis (0,0,1) then it incorrectly points in the x-direction.

Can anyone see what I'm doing wrong?

Thanks

Graham

    public void toOpenGL(final javax.media.opengl.GLAutoDrawable gLDrawable)
    {
        javax.media.opengl.GL       gl  = gLDrawable.getGL();
        javax.media.opengl.glu.GLU  glu = new javax.media.opengl.glu.GLU();
       
        // cylinder base circle 1 centre and axis
        Point3D                 base1Centre  = getEndCircle1Centre();
        Vector3D                cylinderAxis = getAxisVector();
        double                  baseCircle1Radius = getEndCircle1Radius();
        double                  baseCircle2Radius = getEndCircle2Radius();
        double                  axisLength = axisLength();
        Double  alpha = new Double();
        Double  beta  = new Double();
        Double  gamma = new Double();
        cylinderAxis.directionAngles(alpha,beta,gamma,true);
       
   gl.glTranslated(base1Centre.getX(),base1Centre.getY(),base1Centre.getZ());  // translate wrt base circle 1
   gl.glRotated(alpha.getValue(),1.0,0.0,0.0);                                 // rotate the cylinder on the x axis
   gl.glRotated(beta.getValue(),0.0,1.0,0.0);                                  // rotate the cylinder on the y axis
   gl.glRotated(gamma.getValue(),0.0,0.0,1.0);                                 // rotate the cylinder on the z axis

        javax.media.opengl.glu.GLUquadric   quadric = glu.gluNewQuadric();          // create a pointer to the quadric object
        glu.gluQuadricNormals(quadric,javax.media.opengl.glu.GLU.GLU_SMOOTH);       // create smooth normals
        glu.gluQuadricTexture(quadric,true);                                        // Create Texture Coords
        glu.gluQuadricOrientation(quadric,javax.media.opengl.glu.GLU.GLU_OUTSIDE);  // normals acting outwards
        if (joglObject.getIsWireframe())
            glu.gluQuadricDrawStyle(quadric,javax.media.opengl.glu.GLU.GLU_LINE);
        else
            glu.gluQuadricDrawStyle(quadric,javax.media.opengl.glu.GLU.GLU_FILL);
        glu.gluCylinder(quadric,baseCircle1Radius,baseCircle2Radius,axisLength,25,15);    // quadric - base1 radius - base2 radius - axis length - circ div - axis div

        glu.gluDeleteQuadric(quadric);                                              // free up quadric memory
    }

public void directionAngles(Double alpha, Double beta, Double gamma, final boolean degrees)
{
    double n = norm();
    if (Functions.abs(n) > Tolerances.TOLERANCE)
    {
        if (!degrees)
        {
            alpha.setValue(Functions.acos(ma/n));
            beta.setValue(Functions.acos(mb/n));
            gamma.setValue(Functions.acos(mc/n));
        }
        else
        {
            alpha.setValue(Functions.radiansToDegrees(Functions.acos(ma/n)));
            beta.setValue(Functions.radiansToDegrees(Functions.acos(mb/n)));
            gamma.setValue(Functions.radiansToDegrees(Functions.acos(mc/n)));
        }
    }
}

Offline lhkbob

JGO Knight


Medals: 32



« Reply #1 - Posted 2008-07-30 06:30:43 »

Just off of the top of my head, I believe that this is referred to as gimbal lock (experienced when trying to represent every rotation as a sequence of x,y,z angle rotations).  You may want to switch to arbitrary axis angles or using quaternions.  openmali and javax have a vecmath package that provides good support for these math objects.

BTW I didn't check your code, it's just the problem you described seemed to fit gimbal lock very well.

Offline gmseed

Senior Newbie





« Reply #2 - Posted 2008-07-30 10:23:45 »

Hi

Thanks for your reply.

An object such as a cylinder is stored as:

public class Cylinder3D
{
   
    /** End cap 1. */
    protected PlanarCircle3D mEndCircle1;
    /** End cap 2. */
    protected PlanarCircle3D mEndCircle2;
    /** Cylinder axis. */
    protected Curve3D mAxis;
    /** Specifies whether or not the cylinder is open. */
    protected boolean mIsOpen;
//...
}

It's then the mapping of this object to the opengl representation that I'm not clear about.

It's one thing using glRotate() to rotate an object about an arbitrary vector but it's another thing to map an object from one orthogonal coordinate system to another.

Thanks for suggesting gimbal lock. I found a useful description at: http://en.wikipedia.org/wiki/Gimbal_lock

Graham
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline gouessej

« In padded room »



TUER


« Reply #3 - Posted 2008-07-30 13:38:25 »

Quaternions are not enough to solve the problem of gimbal lock. You need to use non eulerian transforms to avoid gimbal lock and it is easier to use this kind of transform with quaternions. A lot of people use quaternions + eulerian transforms, that leads to gimbal lock, I proved it, I worked on gimbal lock during 6 months in 2006. I can show you the formula (given by Pascal Mignot, teacher and researcher at the University of Reims, France) if you want, I need to have a look at my report.

Offline gmseed

Senior Newbie





« Reply #4 - Posted 2008-07-30 17:00:54 »

Hi gouessej

I'd be very interested in seeing the equations.

I've spent all day trying all sorts of coordinate transformations between local and global axes, using quaternions, euler  angles, etc. and still can't get it to work. Any rotation can be reducd to an angular rotation about an arbitrary axis but this is an unnatural way of thinking of mapping one orthogonal coordinate system to another. I also tried converting an orthogonal 3x3 rotation matrix to axis-angle form which I then fed into glRotate(angle,(axis)) but still can't get it to work!!

My email address is gmseed@gmail.com.

Thanks for your assistance as this is driving me crazy!!

Graham

Offline lhkbob

JGO Knight


Medals: 32



« Reply #5 - Posted 2008-07-30 19:59:37 »

I've had good success using 3x3 rotation matrices, you just have to make sure that the angle you give opengl is in degrees.  If I'm starting with the identity as my transform, or I'm pushing relative rotation transforms, it's helpful to create the 3x3 matrix by envisioning the axis of the desired basis.  Then the columns of the rotation are those axis, if you want to convert a local coordinate system into a world or parent system.

Offline gouessej

« In padded room »



TUER


« Reply #6 - Posted 2008-07-31 10:22:40 »

I've had good success using 3x3 rotation matrices, you just have to make sure that the angle you give opengl is in degrees.  If I'm starting with the identity as my transform, or I'm pushing relative rotation transforms, it's helpful to create the 3x3 matrix by envisioning the axis of the desired basis.  Then the columns of the rotation are those axis, if you want to convert a local coordinate system into a world or parent system.
It reduces the risk of gimbal lock as it decreases the accumulation of errors (you start with the identity) but it doesn't solve the problem completely. It is not so simple. I'm going to post the formula today, I'm at work, I need to find the report.

Offline gouessej

« In padded room »



TUER


« Reply #7 - Posted 2008-08-01 13:22:10 »

http://www.univie.ac.at/cga/faq/angles.html

The answer is here:


The current rotations must respect the previous rotations to avoid gimbal lock to prevent any alignment of rotation axis which causes this problem. This problem doesn't depend on the mathematical way you choose to express rotations, it depends on the way to combine rotations. The problem comes from Euler's classical transform: R=Rx.Ry.Rz

Implicitely or explicitly you use it with matrices, quaternions, Euler or Cardan angles, ...

You should correct this transform and it works whatever you used to express your rotations:

R=R[R[R[Ox,a]Oy,b]R[Ox,a]Oz,c] . R[R[Ox,a]Oy,b] .R[Ox,a].

Contributed by Julien Gouesse

Offline lhkbob

JGO Knight


Medals: 32



« Reply #8 - Posted 2008-08-01 18:32:23 »

Interesting, but could you explain the notation when you wrote the equation:
Specifically, what math operations are you doing when you say R[Ox, a], or R[ R[Ox, a]Oy, b]

Thanks,

Offline gouessej

« In padded room »



TUER


« Reply #9 - Posted 2008-08-06 13:48:34 »

Interesting, but could you explain the notation when you wrote the equation:
Specifically, what math operations are you doing when you say R[Ox, a], or R[ R[Ox, a]Oy, b]

Thanks,
R[Ox,a] is a rotation around the X axis of an angle measuring a. Then you can apply such a tranform on another axis. I have a source code that uses this algorithm but it is very complicated and it is in C++ as I haven't put this in TUER for the moment. If you're interested, let me know.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline gouessej

« In padded room »



TUER


« Reply #10 - Posted 2008-08-06 18:42:15 »

The source code ([size=14pt]under GPL licence[/size]) is here, in C++ unfortunately:

http://membres.lycos.fr/javalution/download/gimballock.zip

Offline lhkbob

JGO Knight


Medals: 32



« Reply #11 - Posted 2008-08-07 06:17:52 »

The link seemed broken, and would eventually redirect to lycos.fr's homepage.  I can't say exactly what happened since I can't speak French.  Is there anyway you could e-mail me the zip?

Offline gouessej

« In padded room »



TUER


« Reply #12 - Posted 2008-08-07 07:07:54 »

The link seemed broken, and would eventually redirect to lycos.fr's homepage.  I can't say exactly what happened since I can't speak French.  Is there anyway you could e-mail me the zip?
Now the link should work. If not, I will transfer the zip onto another server because I want to allow everyone to download the source code.

Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

xsi3rr4x (78 views)
2014-04-15 18:08:23

BurntPizza (70 views)
2014-04-15 03:46:01

UprightPath (81 views)
2014-04-14 17:39:50

UprightPath (66 views)
2014-04-14 17:35:47

Porlus (82 views)
2014-04-14 15:48:38

tom_mai78101 (106 views)
2014-04-10 04:04:31

BurntPizza (166 views)
2014-04-08 23:06:04

tom_mai78101 (262 views)
2014-04-05 13:34:39

trollwarrior1 (212 views)
2014-04-04 12:06:45

CJLetsGame (221 views)
2014-04-01 02:16:10
List of Learning Resources
by SHC
2014-04-18 03:17:39

List of Learning Resources
by Longarmx
2014-04-08 03:14:44

Good Examples
by matheus23
2014-04-05 13:51:37

Good Examples
by Grunnt
2014-04-03 15:48:46

Good Examples
by Grunnt
2014-04-03 15:48:37

Good Examples
by matheus23
2014-04-01 18:40:51

Good Examples
by matheus23
2014-04-01 18:40:34

Anonymous/Local/Inner class gotchas
by Roquen
2014-03-11 15:22:30
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!