Getting an object's x, y, z position rotation and scale?

The search feature of this forum makes it difficult to find such basic info as this (try searching for x, y, z and see what you get).

I just need the classes/methods needed to get the x,y,z pos/rot of an object. I know how to set the rotX(), etc, just now how to read them. I’ve been on a wild goose chase with Matrix4F. No idea what thats about. :stuck_out_tongue:

Cheers,
Dr.E

to get the position you simply call Matrix4f.get(Vector3f) the result is then written into the Vector3f. The same works also for Point3f.
how to get the rotation (you’re talking about euler angles, right?) I’ve no idea. You could try to call Matrix4f.get(Matrix3f) and then you could look if Matrix3f (Matrix3f only saves the rotation) offers you a function to do this.


   public static final void matrixToEuler(Matrix4 mat, Vec3 euler)
   {
      float y = -(float) Math.asin(mat.m02);
      float cy = FastMath.cosRad(y);

      euler.y = (float) Math.toDegrees(y);

      if (Math.abs(cy) > 0.005F)
      {
         euler.x = FastMath.atan2Deg(-mat.m12, mat.m22);
         euler.z = FastMath.atan2Deg(-mat.m01, mat.m00);
      }
      else
      {
         euler.x = 0.0F;
         euler.z = FastMath.atan2Deg(mat.m10, mat.m11);
      }
   }

I’m too lazy to convert this code from my own classes to vecmath classes, so that’s left as an exercise for the reader ::slight_smile: :stuck_out_tongue:

Yikes. I think I can cobble it together from your replies, but I’d love to know what is actually going on. You guys know of a vector math primer site/book?

Cheers,
Dr.E

http://www.flipcode.com/documents/matrfaq.html

Thanks. I’m now printing those pages out for when I either have insomnia or time to try to understand it.

In the short-term, I noticed in Transform3D there’s a setEuler() method: http://xith.org/javadoc/com/xith3d/scenegraph/Transform3D.html#setEuler(javax.vecmath.Vector3f)

Why is there no getEuler() that returns a Vector3f? ??? That’d be so handy! Is there a way around this?

Dr.E

Since you ask, yes there is a way around it :slight_smile:

Here’s a Quaternion->Vector conversion method ported from the code at the link provided in the comment:


    /**
     * <p>Returns the euler representation of the given Quaternion.</p>
     * 
     * <p>@link{http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/}</p>
     * 
     * @param q1 the quaternion
     * @return the euler representation of the quaternion
     */
    public static Vector3f convertToEuler(Quat4f q1) {
        double sqw = q1.w*q1.w;
        double sqx = q1.x*q1.x;
        double sqy = q1.y*q1.y;
        double sqz = q1.z*q1.z;
        
        double heading;
        double attitude;
        double bank;
        
        double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
        double test = q1.x*q1.y + q1.z*q1.w;
        if (test > 0.499*unit) { // singularity at north pole
            heading = 2 * Math.atan2(q1.x,q1.w);
            attitude = Math.PI/2;
            bank = 0;
        }
        if (test < -0.499*unit) { // singularity at south pole
            heading = -2 * Math.atan2(q1.x,q1.w);
            attitude = -Math.PI/2;
            bank = 0;
        }
        heading = Math.atan2(2*q1.y*q1.w-2*q1.x*q1.z , sqx - sqy - sqz + sqw);
        attitude = Math.asin(2*test/unit);
        bank = Math.atan2(2*q1.x*q1.w-2*q1.y*q1.z , -sqx + sqy - sqz + sqw);
    
        return new Vector3f(bank, heading, attitude);
    }

I might add that code into a utility class somewhere.

Edit: The other code posted looks a bit more efficient. Would be interesting to try both and check they give the same answers. I will comment that in my experiance I have found that working in degrees instead of radians is not advised you end up doing so many conversions. Better in my experiance if you need degrees to keep them at the extremities (i.e. just before your output the value or just after you input it).

Will.

well, the ‘more efficient’ code returns values from 0 through -PI / 2 to 0 then through PI / 2 back to 0, so you get two poles basically.

I only tried one example, so no guarantee really. I’ll go with the second longer method, which returns values from -PI through 0 to PI (that’s much more convenient and I agree with the poster above considering degrees/radians).