This forum has been archived. All content is frozen. Please use KDE Discuss instead.

Transform into a particular coordinate system

Tags: None
(comma "," separated)
s7726
Registered Member
Posts
5
Karma
0
I currently have code which uses a starting point (x, y, z) and a vector from that point that should represent the x-axis of the new coordinate system. Currently the code goes through and figures out Euler angles in order to use prerotate and AngleAxisd to build the rotation portion of the transform.

It seems to me that there should be some method of assembling the transform without going through Euler angles.

So when the point from the "World" coordinates is transferred into the objects coordinates, the vector given should be the new x-axis. The y, and z axis are not important, for the sake of putting them somewhere we have been aligning the local z-axis in the world xz (zdown) plane and then making the y-axis orthogonal to that plane. The result is that the x position in the new coordinate system is the distance the point is from the starting point (right angle distance) and the sqrt(y^2 + z^2) is the shortest distance (again right angle) from the x-axis of the new system. Those two distances are the important numbers.

Let me know if this just doesn't make any sense. Also it appears our world axis might be changing soon, we've been working in a right handed north-east-down (x-y-z) system, we are going to be moving to a left handed system, which will result in positive z being up rather than down. So I need to get the new solution to pass our existing tests, as well as understand it well enough to reconfigure it for the new system.

Thanks
s7726
Registered Member
Posts
5
Karma
0
So this is what i'm currently doing that does the job:
phi, theta, and psi are the output Euler angles
Code: Select all
        const Eigen::Vector3d unitX(Eigen::Vector3d::UnitX());
        const Eigen::Vector3d unitY(Eigen::Vector3d::UnitY());
        //const Eigen::Vector3d unitZ(Eigen::Vector3d::UnitZ());
        Eigen::Vector3d vector(vect_.i(), vect_.j(), vect_.k());

        // Find phi (angle to rotate about x-axis) to align new y-axis to vector
        const Eigen::Vector3d vecYZ(0, vector(1), vector(2));
        const double magYZ(vecYZ.norm());
        const double YZdotY(vecYZ.dot(unitY));
        phi = -((magYZ > 0) ? acos(YZdotY / magYZ) : 0.0);

        // Apply phi rotation
        vector = Eigen::AngleAxisd(phi, unitX) * vector;

        // Find theta (angle to rotate about y-axis) to align new x-axis to vect_
        const Eigen::Vector3d vecXZ(vector(0), 0, vector(2));
        const double magXZ(vecXZ.norm());
        const double XZdotX(vecXZ.dot(unitX));
        theta = -((magXZ > 0) ? acos(XZdotX / magXZ) : 0.0);

        // Apply theta rotation
        vector = Eigen::AngleAxisd(theta, unitY) * vector;

        // Find psi (angle to rotate about z-axis) to align new x-axis to vect_
        const Eigen::Vector3d vecXY(vector(0), vector(1), 0);
        const double magXY(vecXY.norm());
        const double XYdotX(vecXY.dot(unitX));
        psi = -((magXY > 0) ? acos(XYdotX / magXY) : 0.0);

Then...
Code: Select all
        t.prerotate(
            Eigen::AngleAxisd(psi,   Eigen::Vector3d::UnitZ()) *
            Eigen::AngleAxisd(theta, Eigen::Vector3d::UnitY()) *
            Eigen::AngleAxisd(phi,   Eigen::Vector3d::UnitX()));


What I think I would like to do is something like this:
Code: Select all
        Eigen::Vector3d localX(vect_.i(), vect_.j(), vect_.k());
        if(localX.sum())
            localX.normalize();

        const Eigen::Vector3d tempUp(0,0,1);

        Eigen::Vector3d localY(localX.cross(tempUp));
        if(localY.sum())
        {
            localY.normalize();
        }
        else
        {
            //localX is strait up (World) make our Y correspond to world X
            localY(0,0) = 1;
        }

        Eigen::Vector3d localZ(localX.cross(localY));
        localZ.normalize();

        Eigen::Matrix3d rotationMatrix;
        rotationMatrix << localX, localY, localZ;

The rotationMatrix would become the linear portion of an Affine Transform Matrix.

Obviously my matrix method is wrong I just don't understand it enough to figure out how and why? Any help? Is this even slightly doable?
linello
Registered Member
Posts
56
Karma
0
OS
What about using Eigen::Affine3d ? It's one of the most useful thing in Eigen when treating affine transformations (it's included in the Geometry header

For example

Code: Select all
#include <Eigen/Geometry>
// Our starting vector
Eigen::Vector3d a(1,2,3);

double theta=M_PI/3;
Eigen::AngleAxis<double> aa( theta, Vector3d::UnitY() );
 
Eigen::Affine3d M;
M.linear().matrix() = aa.toRotationMatrix();
M.translation() = Vector3d( 0, 5, 0);

Eigen::Vector3d result = M*a;



there are many other methods to do this, but this is simple to read and understand in my opinion.
s7726
Registered Member
Posts
5
Karma
0
The problem I'm trying to address is avoiding the computation of theta, phi, and psi.


Bookmarks



Who is online

Registered users: Bing [Bot], Google [Bot], Yahoo [Bot]