Rotate a std::vector as a rigid transformation?












1















I have a few 3d points, stored in a std::vector<Eigen::Vector3d>. I need to rigidly rotate and translate these points, without changing their relationship to one another. As if moving the cloud as a whole.



Based on this question:



https://stackoverflow.com/questions/50507665/eigen-rotate-a-vector3d-with-a-quaternion



I have this code:



std::vector<Eigen::Vector3d> pts, ptsMoved;


Eigen::Quaterniond rotateBy = Eigen::Quaterniond(0.1,0.5,0.08,0.02);
Eigen::Vector3d translateBy(1, 2.5, 1.5);


for (int i = 0; i < pts.size(); i++)
{
//transform point
Vector3d rot = rotateBy * (pts[i] + translateBy);
ptsMoved.push_back(rot);

}


When i view the points and compare them to the original points, however, I get this: (White are the original, green are the transformed).



points



What i expect, is the cloud as a whole to look the same, just in a different position and orientation. What i get, is a moved and rotated and scaled cloud, that looks different to the original. What am i doing wrong?



EDIT:



If i apply the inverse transform to the adjusted points, using:



std::vector<Eigen::Vector3d> pntsBack;
for (int i = 0; i < ptsMoved.size(); i++)
{
//transform point
Vector3d rot = rotateBy.inverse() * (ptsMoved[i] - translateBy);
pntsBack.push_back(rot);
}


It gives me an even worse result. (dark green = original points, white = transformed, light green = transformed inverse)



enter image description here










share|improve this question

























  • If you apply the inverse transform to the transformed points, do you get back to where you started?

    – Caleth
    Nov 23 '18 at 12:49











  • Or even better, apply the inverse transform to the camera, and compare those pictures

    – Caleth
    Nov 23 '18 at 12:55











  • thanks for your reply. using Vector3d rot = rotateBy.inverse() * (ptsMoved[i] -translateBy); to apply the inverse, I get a very incorrect result.

    – anti
    Nov 23 '18 at 12:56













  • that isn't the opposite transformation. Iirc it would be (rotateBy.inverse() * ptsMoved[i]) - translateBy;

    – Caleth
    Nov 23 '18 at 12:57











  • To me, the differences look like parallax

    – Caleth
    Nov 23 '18 at 12:58
















1















I have a few 3d points, stored in a std::vector<Eigen::Vector3d>. I need to rigidly rotate and translate these points, without changing their relationship to one another. As if moving the cloud as a whole.



Based on this question:



https://stackoverflow.com/questions/50507665/eigen-rotate-a-vector3d-with-a-quaternion



I have this code:



std::vector<Eigen::Vector3d> pts, ptsMoved;


Eigen::Quaterniond rotateBy = Eigen::Quaterniond(0.1,0.5,0.08,0.02);
Eigen::Vector3d translateBy(1, 2.5, 1.5);


for (int i = 0; i < pts.size(); i++)
{
//transform point
Vector3d rot = rotateBy * (pts[i] + translateBy);
ptsMoved.push_back(rot);

}


When i view the points and compare them to the original points, however, I get this: (White are the original, green are the transformed).



points



What i expect, is the cloud as a whole to look the same, just in a different position and orientation. What i get, is a moved and rotated and scaled cloud, that looks different to the original. What am i doing wrong?



EDIT:



If i apply the inverse transform to the adjusted points, using:



std::vector<Eigen::Vector3d> pntsBack;
for (int i = 0; i < ptsMoved.size(); i++)
{
//transform point
Vector3d rot = rotateBy.inverse() * (ptsMoved[i] - translateBy);
pntsBack.push_back(rot);
}


It gives me an even worse result. (dark green = original points, white = transformed, light green = transformed inverse)



enter image description here










share|improve this question

























  • If you apply the inverse transform to the transformed points, do you get back to where you started?

    – Caleth
    Nov 23 '18 at 12:49











  • Or even better, apply the inverse transform to the camera, and compare those pictures

    – Caleth
    Nov 23 '18 at 12:55











  • thanks for your reply. using Vector3d rot = rotateBy.inverse() * (ptsMoved[i] -translateBy); to apply the inverse, I get a very incorrect result.

    – anti
    Nov 23 '18 at 12:56













  • that isn't the opposite transformation. Iirc it would be (rotateBy.inverse() * ptsMoved[i]) - translateBy;

    – Caleth
    Nov 23 '18 at 12:57











  • To me, the differences look like parallax

    – Caleth
    Nov 23 '18 at 12:58














1












1








1








I have a few 3d points, stored in a std::vector<Eigen::Vector3d>. I need to rigidly rotate and translate these points, without changing their relationship to one another. As if moving the cloud as a whole.



Based on this question:



https://stackoverflow.com/questions/50507665/eigen-rotate-a-vector3d-with-a-quaternion



I have this code:



std::vector<Eigen::Vector3d> pts, ptsMoved;


Eigen::Quaterniond rotateBy = Eigen::Quaterniond(0.1,0.5,0.08,0.02);
Eigen::Vector3d translateBy(1, 2.5, 1.5);


for (int i = 0; i < pts.size(); i++)
{
//transform point
Vector3d rot = rotateBy * (pts[i] + translateBy);
ptsMoved.push_back(rot);

}


When i view the points and compare them to the original points, however, I get this: (White are the original, green are the transformed).



points



What i expect, is the cloud as a whole to look the same, just in a different position and orientation. What i get, is a moved and rotated and scaled cloud, that looks different to the original. What am i doing wrong?



EDIT:



If i apply the inverse transform to the adjusted points, using:



std::vector<Eigen::Vector3d> pntsBack;
for (int i = 0; i < ptsMoved.size(); i++)
{
//transform point
Vector3d rot = rotateBy.inverse() * (ptsMoved[i] - translateBy);
pntsBack.push_back(rot);
}


It gives me an even worse result. (dark green = original points, white = transformed, light green = transformed inverse)



enter image description here










share|improve this question
















I have a few 3d points, stored in a std::vector<Eigen::Vector3d>. I need to rigidly rotate and translate these points, without changing their relationship to one another. As if moving the cloud as a whole.



Based on this question:



https://stackoverflow.com/questions/50507665/eigen-rotate-a-vector3d-with-a-quaternion



I have this code:



std::vector<Eigen::Vector3d> pts, ptsMoved;


Eigen::Quaterniond rotateBy = Eigen::Quaterniond(0.1,0.5,0.08,0.02);
Eigen::Vector3d translateBy(1, 2.5, 1.5);


for (int i = 0; i < pts.size(); i++)
{
//transform point
Vector3d rot = rotateBy * (pts[i] + translateBy);
ptsMoved.push_back(rot);

}


When i view the points and compare them to the original points, however, I get this: (White are the original, green are the transformed).



points



What i expect, is the cloud as a whole to look the same, just in a different position and orientation. What i get, is a moved and rotated and scaled cloud, that looks different to the original. What am i doing wrong?



EDIT:



If i apply the inverse transform to the adjusted points, using:



std::vector<Eigen::Vector3d> pntsBack;
for (int i = 0; i < ptsMoved.size(); i++)
{
//transform point
Vector3d rot = rotateBy.inverse() * (ptsMoved[i] - translateBy);
pntsBack.push_back(rot);
}


It gives me an even worse result. (dark green = original points, white = transformed, light green = transformed inverse)



enter image description here







c++ eigen point-clouds






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 23 '18 at 13:01







anti

















asked Nov 23 '18 at 12:36









antianti

9571231




9571231













  • If you apply the inverse transform to the transformed points, do you get back to where you started?

    – Caleth
    Nov 23 '18 at 12:49











  • Or even better, apply the inverse transform to the camera, and compare those pictures

    – Caleth
    Nov 23 '18 at 12:55











  • thanks for your reply. using Vector3d rot = rotateBy.inverse() * (ptsMoved[i] -translateBy); to apply the inverse, I get a very incorrect result.

    – anti
    Nov 23 '18 at 12:56













  • that isn't the opposite transformation. Iirc it would be (rotateBy.inverse() * ptsMoved[i]) - translateBy;

    – Caleth
    Nov 23 '18 at 12:57











  • To me, the differences look like parallax

    – Caleth
    Nov 23 '18 at 12:58



















  • If you apply the inverse transform to the transformed points, do you get back to where you started?

    – Caleth
    Nov 23 '18 at 12:49











  • Or even better, apply the inverse transform to the camera, and compare those pictures

    – Caleth
    Nov 23 '18 at 12:55











  • thanks for your reply. using Vector3d rot = rotateBy.inverse() * (ptsMoved[i] -translateBy); to apply the inverse, I get a very incorrect result.

    – anti
    Nov 23 '18 at 12:56













  • that isn't the opposite transformation. Iirc it would be (rotateBy.inverse() * ptsMoved[i]) - translateBy;

    – Caleth
    Nov 23 '18 at 12:57











  • To me, the differences look like parallax

    – Caleth
    Nov 23 '18 at 12:58

















If you apply the inverse transform to the transformed points, do you get back to where you started?

– Caleth
Nov 23 '18 at 12:49





If you apply the inverse transform to the transformed points, do you get back to where you started?

– Caleth
Nov 23 '18 at 12:49













Or even better, apply the inverse transform to the camera, and compare those pictures

– Caleth
Nov 23 '18 at 12:55





Or even better, apply the inverse transform to the camera, and compare those pictures

– Caleth
Nov 23 '18 at 12:55













thanks for your reply. using Vector3d rot = rotateBy.inverse() * (ptsMoved[i] -translateBy); to apply the inverse, I get a very incorrect result.

– anti
Nov 23 '18 at 12:56







thanks for your reply. using Vector3d rot = rotateBy.inverse() * (ptsMoved[i] -translateBy); to apply the inverse, I get a very incorrect result.

– anti
Nov 23 '18 at 12:56















that isn't the opposite transformation. Iirc it would be (rotateBy.inverse() * ptsMoved[i]) - translateBy;

– Caleth
Nov 23 '18 at 12:57





that isn't the opposite transformation. Iirc it would be (rotateBy.inverse() * ptsMoved[i]) - translateBy;

– Caleth
Nov 23 '18 at 12:57













To me, the differences look like parallax

– Caleth
Nov 23 '18 at 12:58





To me, the differences look like parallax

– Caleth
Nov 23 '18 at 12:58












1 Answer
1






active

oldest

votes


















2














Your Quaternion is not a unit-Quaternion, therefore you will get unspecified results.
If you are not sure your quaternion is normalized, just write



rotateBy.normalize();


before using it. Additionally, if you want to rotate more than one vector it is more efficient to convert the Quaternion to a rotation matrix:



Eigen::Matrix3d rotMat = rotateBy.toRotationMatrix();
// ...
// inside for loop:
Vector3d rot = rotMat * (ptsMoved[i] - translateBy);


Also, instead of .inverse() you can use .conjugate() for unit quaternions and .adjoint() or .transpose() for orthogonal Matrices.






share|improve this answer
























  • Thank you! This has indeed fixed my issue. However, when I try to get the points back to where they started, using Vector3d rot = rotateBy.conjugate() * (ptsMoved[i] - translateBy); The rotation looks correct, but the translation is off in one axis.

    – anti
    Nov 23 '18 at 13:55











  • Adjusting teh order of operations has fixed this last part. Vector3d rot = rotateBy.conjugate() * (ptsMoved[i]); rot = rot - translateBy; thank you again for your help!

    – anti
    Nov 23 '18 at 14:19













Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53446831%2frotate-a-stdvectoreigenvector3d-as-a-rigid-transformation%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









2














Your Quaternion is not a unit-Quaternion, therefore you will get unspecified results.
If you are not sure your quaternion is normalized, just write



rotateBy.normalize();


before using it. Additionally, if you want to rotate more than one vector it is more efficient to convert the Quaternion to a rotation matrix:



Eigen::Matrix3d rotMat = rotateBy.toRotationMatrix();
// ...
// inside for loop:
Vector3d rot = rotMat * (ptsMoved[i] - translateBy);


Also, instead of .inverse() you can use .conjugate() for unit quaternions and .adjoint() or .transpose() for orthogonal Matrices.






share|improve this answer
























  • Thank you! This has indeed fixed my issue. However, when I try to get the points back to where they started, using Vector3d rot = rotateBy.conjugate() * (ptsMoved[i] - translateBy); The rotation looks correct, but the translation is off in one axis.

    – anti
    Nov 23 '18 at 13:55











  • Adjusting teh order of operations has fixed this last part. Vector3d rot = rotateBy.conjugate() * (ptsMoved[i]); rot = rot - translateBy; thank you again for your help!

    – anti
    Nov 23 '18 at 14:19


















2














Your Quaternion is not a unit-Quaternion, therefore you will get unspecified results.
If you are not sure your quaternion is normalized, just write



rotateBy.normalize();


before using it. Additionally, if you want to rotate more than one vector it is more efficient to convert the Quaternion to a rotation matrix:



Eigen::Matrix3d rotMat = rotateBy.toRotationMatrix();
// ...
// inside for loop:
Vector3d rot = rotMat * (ptsMoved[i] - translateBy);


Also, instead of .inverse() you can use .conjugate() for unit quaternions and .adjoint() or .transpose() for orthogonal Matrices.






share|improve this answer
























  • Thank you! This has indeed fixed my issue. However, when I try to get the points back to where they started, using Vector3d rot = rotateBy.conjugate() * (ptsMoved[i] - translateBy); The rotation looks correct, but the translation is off in one axis.

    – anti
    Nov 23 '18 at 13:55











  • Adjusting teh order of operations has fixed this last part. Vector3d rot = rotateBy.conjugate() * (ptsMoved[i]); rot = rot - translateBy; thank you again for your help!

    – anti
    Nov 23 '18 at 14:19
















2












2








2







Your Quaternion is not a unit-Quaternion, therefore you will get unspecified results.
If you are not sure your quaternion is normalized, just write



rotateBy.normalize();


before using it. Additionally, if you want to rotate more than one vector it is more efficient to convert the Quaternion to a rotation matrix:



Eigen::Matrix3d rotMat = rotateBy.toRotationMatrix();
// ...
// inside for loop:
Vector3d rot = rotMat * (ptsMoved[i] - translateBy);


Also, instead of .inverse() you can use .conjugate() for unit quaternions and .adjoint() or .transpose() for orthogonal Matrices.






share|improve this answer













Your Quaternion is not a unit-Quaternion, therefore you will get unspecified results.
If you are not sure your quaternion is normalized, just write



rotateBy.normalize();


before using it. Additionally, if you want to rotate more than one vector it is more efficient to convert the Quaternion to a rotation matrix:



Eigen::Matrix3d rotMat = rotateBy.toRotationMatrix();
// ...
// inside for loop:
Vector3d rot = rotMat * (ptsMoved[i] - translateBy);


Also, instead of .inverse() you can use .conjugate() for unit quaternions and .adjoint() or .transpose() for orthogonal Matrices.







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 23 '18 at 13:49









chtzchtz

6,96811232




6,96811232













  • Thank you! This has indeed fixed my issue. However, when I try to get the points back to where they started, using Vector3d rot = rotateBy.conjugate() * (ptsMoved[i] - translateBy); The rotation looks correct, but the translation is off in one axis.

    – anti
    Nov 23 '18 at 13:55











  • Adjusting teh order of operations has fixed this last part. Vector3d rot = rotateBy.conjugate() * (ptsMoved[i]); rot = rot - translateBy; thank you again for your help!

    – anti
    Nov 23 '18 at 14:19





















  • Thank you! This has indeed fixed my issue. However, when I try to get the points back to where they started, using Vector3d rot = rotateBy.conjugate() * (ptsMoved[i] - translateBy); The rotation looks correct, but the translation is off in one axis.

    – anti
    Nov 23 '18 at 13:55











  • Adjusting teh order of operations has fixed this last part. Vector3d rot = rotateBy.conjugate() * (ptsMoved[i]); rot = rot - translateBy; thank you again for your help!

    – anti
    Nov 23 '18 at 14:19



















Thank you! This has indeed fixed my issue. However, when I try to get the points back to where they started, using Vector3d rot = rotateBy.conjugate() * (ptsMoved[i] - translateBy); The rotation looks correct, but the translation is off in one axis.

– anti
Nov 23 '18 at 13:55





Thank you! This has indeed fixed my issue. However, when I try to get the points back to where they started, using Vector3d rot = rotateBy.conjugate() * (ptsMoved[i] - translateBy); The rotation looks correct, but the translation is off in one axis.

– anti
Nov 23 '18 at 13:55













Adjusting teh order of operations has fixed this last part. Vector3d rot = rotateBy.conjugate() * (ptsMoved[i]); rot = rot - translateBy; thank you again for your help!

– anti
Nov 23 '18 at 14:19







Adjusting teh order of operations has fixed this last part. Vector3d rot = rotateBy.conjugate() * (ptsMoved[i]); rot = rot - translateBy; thank you again for your help!

– anti
Nov 23 '18 at 14:19






















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53446831%2frotate-a-stdvectoreigenvector3d-as-a-rigid-transformation%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Tonle Sap (See)

I get strange results when I access the Sqlitedatabase with Unity C# via XAMPP

Guatemaltekische Davis-Cup-Mannschaft