Повернуть стандартное векторное изображение :: векторкак жесткое преобразование? - PullRequest
0 голосов
/ 23 ноября 2018

У меня есть несколько 3d очков, сохраненных в std::vector<Eigen::Vector3d>.Мне нужно жестко вращать и переводить эти точки, не меняя их отношения друг с другом.Как будто движется облако в целом.

На основании этого вопроса:

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

У меня есть этот код:

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);

}

КогдаЯ рассматриваю точки и сравниваю их с исходными точками, однако получаю следующее: (Белые - это оригиналы, зеленые - трансформированные).

points

Я ожидаю, что облако в целом будет выглядеть одинаково, только в другой позиции и ориентации.То, что я получаю, это перемещенное и повернутое и масштабированное облако, которое отличается от оригинала.Что я делаю неправильно?

РЕДАКТИРОВАТЬ:

Если я применяю обратное преобразование к скорректированным точкам, используя:

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);
}

Это дает мне еще худший результат.(темно-зеленый = исходные точки, белый = преобразованный, светло-зеленый = преобразованный обратный)

enter image description here

1 Ответ

0 голосов
/ 23 ноября 2018

Ваш кватернион не является единичным кватернионом, поэтому вы получите неопределенные результаты.Если вы не уверены, что ваш кватернион нормализован, просто напишите

rotateBy.normalize();

перед его использованием.Кроме того, если вы хотите повернуть более одного вектора, более эффективно преобразовать кватернион в матрицу вращения:

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

Кроме того, вместо .inverse() вы можете использовать .conjugate() для единичных кватернионов и.adjoint() или .transpose() для ортогональных матриц.

...