Dear Robert,
thank you very much for your time.

I still have doubt about the interpretion of the experiment: "...so we'd
expect the scale of the x and y axis to be swapped.". I think that means,
after rotation, the scale is still represented in the original frame,
instead of the rotated one (otherwise the scale would be independent from
the rotation). But when the rotation is, say, 30 degree, then the scale
cannot generally be represented in the original frame without introducing
sheering.

Another argument is that the current Matrixd::getScale() is INconsistent
with Matrixd::decompose( ). The following is the test code, which shows
that the result of getScale() is not the same as decompose(), whereas
getTrans() gives consistent result. This behavior is somewhat confusing for
me.

/**********Test Code**************/
osg::Matrixd S = osg::Matrixd::scale(3.0, 4.0, 5.0);
osg::Matrixd R =
osg::Matrixd::rotate(osg::inDegrees(30.0f),osg::Vec3d(0.0,0.0,1.0));
osg::Matrixd T = osg::Matrixd::translate(7.0, 8.0, 9.0);

osg::Matrixd mat = S*R*T;//combine scale, rotation, and translation

std::cout <<"getScale() = "<< mat.getScale().x() << " "<<
 mat.getScale().y() << " "<< mat.getScale().z() << std::endl;//looks strange

osg::Vec3d x_vec2(mat(0,0), mat(0,1), mat(0,2));
osg::Vec3d y_vec2(mat(1,0), mat(1,1), mat(1,2));
osg::Vec3d z_vec2(mat(2,0), mat(2,1), mat(2,2));
std::cout<< "new_getScale() = " << x_vec2.length() << " "<<
 y_vec2.length() << " " <<  z_vec2.length() << std::endl;//3 4 5

osg::Vec3d trans;
osg::Quat rot;
osg::Vec3d scale;
osg::Quat so;
mat.decompose(trans, rot, scale, so);

osg::Vec3d trans2 = mat.getTrans();

//The result of getTrans() is consistent with decompose()
std::cout << "decomposed Trans "<< trans.x() << " "<<  trans.y() << " " <<
 trans.z() << std::endl;//7 8 9
std::cout << "getTrans() = "<< trans2.x() << " "<<  trans2.y() << " " <<
 trans2.z() << std::endl;//also 7 8 9

//The result of getScale() is INconsistent with decompose(), with is
confusing
std::cout << "decomposed scale "<< scale.x() << " "<<  scale.y() << " " <<
 scale.z() << std::endl;//3 4 5
std::cout << "decomposed so "<< so.x() << " "<<  so.y() << " " <<  so.z()
<< " " << so.w() << std::endl;//zero rotation
/**********End of Test Code*************/

In summary, I think the newly proposed version of getScale() gives (the
correct) rotation-independent scale information, which results in similar
behavior as that of getTrans() and decompose(), and is probably more
intuitive to use.

Thank you again for your precious time.

Best regards,
Tianlan Shao
On Thu, Apr 17, 2014 at 4:26 PM, Robert Osfield <robert.osfi...@gmail.com>wrote:

> Hi Tianlan,
>
> I have done the following test where I provide a non unifom scale
> matrix then rotate it by 90 degrees, and then output the result of
> getScale() and the result of you suggested above:
>
>         osg::Matrixd scale_then_rotated =
>
> osg::Matrixd::scale(3.0,4.0,1.0)*osg::Matrix::rotate(osg::inDegrees(90.0f),osg::Vec3d(0.0,0.0,1.0));
>         OSG_NOTICE<<"Matrixd.getScale() =
> "<<scale_then_rotated.getScale()<<std::endl;
>
>         osg::Matrixd mat(scale_then_rotated);
>
>         osg::Vec3d x_vec2(mat(0,0), mat(0,1), mat(0,2));
>         osg::Vec3d y_vec2(mat(1,0), mat(1,1), mat(1,2));
>         osg::Vec3d z_vec2(mat(2,0), mat(2,1), mat(2,2));
>
>         std::cout << x_vec2.length() << " "<<  y_vec2.length() <<  "
> "<<z_vec2.length() << std::endl; //seems correct
>
> The result  I get on the console is:
>
> Matrixd.getScale() = 4 3 1
> 3 4 1
>
> The getScale() version is correct, your suggestion is wrong as the
> matrix is now rotated 90 degrees so we'd expect the scale of the x and
> y axis to be swapped.
>
> If you were to compute the rotation and then remove this rotation and
> then do the getScale() I believe you'll get the result you are looking
> for with the existing code.
>
> Robert.
>
>
>
> On 17 April 2014 13:53, Tianlan Shao <shaotianlan...@gmail.com> wrote:
> > Dear Robert,
> > thank you for your reply, below is the code to reproduce the bug:
> >
> > /********************************************************/
> > osg::Matrixd S = osg::Matrixd::scale(3.0, 4.0, 5.0);
> > osg::Matrixd R = osg::Matrixd::rotate(osg::Quat(0.1, 0.5, 0.6, 0.7));
> > osg::Matrixd T = osg::Matrixd::translate(7.0, 8.0, 9.0);
> >
> > osg::Matrixd mat = S*R*T;//combine scale, rotation, and translation
> >
> > std::cout << mat.getScale().x() << " "<<  mat.getScale().y() <<
> > mat.getScale().z() << std::endl;//Oops...seems wrong
> >
> >
> > osg::Vec3d x_vec2(mat(0,0), mat(0,1), mat(0,2));
> > osg::Vec3d y_vec2(mat(1,0), mat(1,1), mat(1,2));
> > osg::Vec3d z_vec2(mat(2,0), mat(2,1), mat(2,2));
> >
> > std::cout << x_vec2.length() << " "<<  y_vec2.length() <<
>  z_vec2.length()
> > << std::endl; //seems correct
> > /********************************************************/
> >
> > If the matrix combination above makes sense, then I guess what I found is
> > indeed a bug.
> > Thank you for your time and work.
> >
> > Best regards,
> > Tianlan Shao
> >
> >
> > On Thu, Apr 17, 2014 at 11:36 AM, Robert Osfield <
> robert.osfi...@gmail.com>
> > wrote:
> >>
> >> Hi Tianlan,
> >>
> >> Could you provide a small example that illustrates the problem?
> >>
> >> I did a quick test of:
> >>
> >>         osg::Matrixd matrix = osg::Matrixd::scale(3.0,4.0,1.0);
> >>         OSG_NOTICE<<"Matrixd.getScale() =
> "<<matrix.getScale()<<std::endl;
> >>
> >> And this works.  I will need to have a think about a more complex
> >> scale set up before I can judge what it should be.
> >>
> >> Robert.
> >>
> >> On 15 April 2014 16:43, Tianlan Shao <shaotianlan...@gmail.com> wrote:
> >> > Dear all,
> >> > The following code in the header file MatrixD looks very suspicious to
> >> > me:
> >> >
> >> > inline Vec3d getScale() const {
> >> >           Vec3d x_vec(_mat[0][0],_mat[1][0],_mat[2][0]);
> >> >           Vec3d y_vec(_mat[0][1],_mat[1][1],_mat[2][1]);
> >> >           Vec3d z_vec(_mat[0][2],_mat[1][2],_mat[2][2]);
> >> >           return Vec3d(x_vec.length(), y_vec.length(),
> z_vec.length());
> >> >         }
> >> >
> >> > Shouldn't the index order be the other way around? I mean it should be
> >> >
> >> > inline Vec3d getScale() const {
> >> >           Vec3d x_vec(_mat[0][0],_mat[0][1],_mat[0][2]);
> >> >           Vec3d y_vec(_mat[1][0],_mat[1][1],_mat[1][2]);
> >> >           Vec3d z_vec(_mat[2][0],_mat[2][1],_mat[2][2]);
> >> >           return Vec3d(x_vec.length(), y_vec.length(),
> z_vec.length());
> >> >         }
> >> >
> >> > The behaviour of my program was strange before I fix this problem. I'm
> >> > not
> >> > 100% percent sure, but since it's of fundamental importance, I still
> >> > decided
> >> > to report.
> >> >
> >> > Best regards,
> >> > Tianlan Shao
> >> >
> >> >
> >> > _______________________________________________
> >> > osg-users mailing list
> >> > osg-users@lists.openscenegraph.org
> >> >
> >> >
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
> >> >
> >> _______________________________________________
> >> osg-users mailing list
> >> osg-users@lists.openscenegraph.org
> >>
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
> >
> >
> >
> > _______________________________________________
> > osg-users mailing list
> > osg-users@lists.openscenegraph.org
> >
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
> >
> _______________________________________________
> osg-users mailing list
> osg-users@lists.openscenegraph.org
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>
_______________________________________________
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to