1
$\begingroup$

I have a test for rotation , and found two rotation behave the same at one point

rot1 = [    0.8736    0.2915   -0.3897;
   -0.4011    0.8848   -0.2373;
    0.2756    0.3636    0.8898]

rot2 = [    0.9874   -0.1420   -0.0700;
    0.0700    0.7880   -0.6117;
    0.1420    0.5991    0.7880]

yet they have same result at rotation

wpt = [200 200 200] 

with result

   cpt = [  155.0812 49.2660 305.8148] 

can anyone could explain this? :)

$\endgroup$
0
$\begingroup$

It is not surprising at all. Let $U_1=wpt$ and $U_2=cpt$.

There is an infinity of such matrices. It is even possible to describe all rotations that send $U_1$ onto $U_2$. Here is how.

Let Let $V=U_1-U_2$ and $(P)$ be the plane orthogonal to $V$.

In particular, this plane is such that $V_1$ and $V_2$ are symmetrical with respect to it.

Then, every $W \neq 0$ vector of $(P)$ can be used as giving an axis of rotation sending (with an appropriate angle) $U_1$ onto $U_2$.

The corresponding matrix is to be found for example by using Rodrigues' formula.

Here is for example a third rotation matrix sending $U_1$ onto $U_2$:

[0.9220   -0.3371    0.1906

 0.3657    0.5957   -0.7151

 0.1275    0.7290    0.6725]
$\endgroup$
  • $\begingroup$ I think I have got it , but how many point matches are needed to constraint the unique rotation ? $\endgroup$ – Mr.Guo May 28 '16 at 4:34
  • 1
    $\begingroup$ Any two points $P$ and $Q$, not scalar multiples of each other, will do. To see this, suppose that two rotation matrices $A_1$ and $A_2$ have $A_1P=A_2P$ and $A_1Q=A_2Q$. Then $A_2^{-1}A_1$ is a rotation leaving both $P$ and $Q$ fixed. But the only rotations leaving $P$ fixed are rotations through the axis spanned by $P$, and likewise for $Q$. But the only rotation which rotates through two distinct axes is the trivial rotation (represented by the identity matrix), so $A_2^{-1}A_1=I$, i.e., $A_1=A_2$. $\endgroup$ – Brent Kerby May 28 '16 at 5:16
  • $\begingroup$ If $R$ is the rotation with center 0 you are looking for. You need two pairs of matching points $RP_1=P_2$ and $RQ_1=Q_2$, with conditions of $\|P_1\|=\|P_2\|$, $\|Q_1\|=\|Q_2\|$ and equal dot products $P_1.P_2=Q_1.Q_2$. The reason is simple with the proof I have given : the first pair of corresponding points determine a plane where axis of rotation has to be taken ; the second pair gives a second plane ; the intersection of these planes is a straight line which the unique axis of rotation possible. $\endgroup$ – Jean Marie May 28 '16 at 5:23
  • $\begingroup$ but for the situation of [0 1 0] -> [0 0 1] and [0 2 0] -> [0 0 2] have two kind of rotaion , from axis[0 0 1] with angle 90 and from axis[1 1 0] with angle 180 $\endgroup$ – Mr.Guo May 28 '16 at 5:40
  • $\begingroup$ The second information is [0 2 0] -> [0 0 2] can not be taken at all as a new information because it can be deduced from [0 1 0] -> [0 0 1] by linearity (here proportionality) ! $\endgroup$ – Jean Marie May 28 '16 at 20:24
0
$\begingroup$

Any two rotation matrices about a point should be distinct when acting on some arbitrary vector. That being said, two distinct rotations could certainly map some specific vector into another specific vector. That's what JeanMarie's answer addresses.

I think your issue, though, may have to do with the limitations of computational science: You don't have true rotation matrices. You're using MATLAB, right? Well, your matrices are stored as floating point arrays. That is, they suffer from limited computational precision. It wouldn't surprise me that two rotations that you might expect to be distinct don't compute that way.

I suspect the matrices in your question have been truncated after you copied and pasted them. If I attempt use the matrices as displayed in your question, I do see a difference:

rot1*wpt'
ans =
  155.0800
   49.2800
  305.8000

rot2*wpt'
ans =
  155.0800
   49.2600
  305.8200

Something you can look into is your machine and software limitations on floating point precision.

$\endgroup$
0
$\begingroup$

I have coded for the testify for the rotation iterated solve with gauss-newton , and found if I have two or more point matches, the rotation could convergence to the right one and so the mapped point , but if I only have one point match , the mapped point is right but the rotation matrix is not correct , so I think two matches should be enough

//now it finally right
void so3fJacobianTestNewton()
{
    SO3f::Tangent v;
    v << 0.34, 0.24, 0.14;

    SO3f::Tangent delta;
    delta << 0.34, -0.24, -0.54;

    SO3f so3f = SO3f::exp(v);
    Matrix3f rot = so3f.matrix();
    SO3f so3f_delta = SO3f::exp(delta)*SO3f::exp(v);
    SO3f::Tangent so3f_v = SO3f::log(so3f_delta);
    Matrix3f rot_delta = so3f_delta.matrix();

    int wpt_n = 2;
    MatrixXf wpt = MatrixXf::Random(3, wpt_n)*100;

    MatrixXf wpt1 = rot*wpt;
    MatrixXf wpt2 = rot_delta*wpt;


    SO3f so3f_iter = so3f;
    MatrixXf wpt_jacobi = wpt1;
    for (int i = 0; i < 100; i++)
    {
        Matrix3f A = Matrix3f::Zero();
        Vector3f b = Vector3f::Zero();
        for (int i = 0; i < wpt_n; i++)
        {
            Matrix3f jacobi = Matrix3f::Zero();
            VectorXf wpt_jacobi_col = wpt_jacobi.col(i);
            VectorXf wpt2_col = wpt2.col(i);
            jacobi(0, 1) = wpt_jacobi_col[2];
            jacobi(1, 0) = -wpt_jacobi_col[2];
            jacobi(0, 2) = -wpt_jacobi_col[1];
            jacobi(2, 0) = wpt_jacobi_col[1];
            jacobi(1, 2) = wpt_jacobi_col[0];
            jacobi(2, 1) = -wpt_jacobi_col[0];

            A += jacobi.transpose()*jacobi;
            b += jacobi.transpose()*(wpt2_col - wpt_jacobi_col);
        }

//      Vector3f delta_step = A.inverse()*(b);
        Vector3f delta_step = A.ldlt().solve(b);

        so3f_iter = SO3f::exp(delta_step)*so3f_iter;
        wpt_jacobi = so3f_iter.matrix()*wpt;

//      cout << so3f_iter.transpose() << endl;
//      cout << so3f_v.transpose() << endl;
//      Vector3f rpt = Vector3f::Random();

        cout << "matrix_iter : " << endl << so3f_iter.matrix() << endl;
        cout << "matrix_right : " << endl << so3f_delta.matrix() << endl;

        cout << "result_wpt_iter : " << endl << wpt_jacobi << endl;
        cout << "result_wpt_right : " << endl << wpt2 << endl;
    }
}
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.