以与特定线平行的方式旋转几何

时间:2018-09-22 12:04:02

标签: qt vector rotation qt3d

我有一个这样的基准line

QVector3D line = QVector3D(38.0572, 29.2247, 35.3996);

我像这样用Qt3D创建一个圆锥体:

Qt3DCore::QEntity *newEntity = new Qt3DCore::QEntity();

Qt3DExtras::QConeMesh *mesh = new Qt3DExtras::QConeMesh();
mesh->setTopRadius(0.2);
mesh->setBottomRadius(1.0);
mesh->setLength(2.0);
for(int i = 0; i < mesh->geometry()->attributes().size(); ++i) {
    mesh->geometry()->attributes().at(i)->buffer()->setSyncData(true);
}

newEntity->addComponent(mesh);

据我检查,默认圆锥轴为QVector3D(0, 1, 0)

Cone


现在,我想以使圆锥轴平行于基准line的方式旋转/变形圆锥。可以使用Qt3DCore::QTransform

// ... previous code lines

Qt3DCore::QTransform *transform = new Qt3DCore::QTransform();
transform->setRotationX(?);
transform->setRotationY(?);
transform->setRotationZ(?);
transform->setRotation(?);
transform->setTranslation(?);
transform->setMatrix(?);

newEntity->addComponent(transform);

我不知道如何以锥轴平行于基准line的方式组装变换组件。


我已经研究了这些,但是到目前为止还没有运气:

https://en.wikipedia.org/wiki/Rotation_%28mathematics%29

https://en.wikipedia.org/wiki/Change_of_basis

1 个答案:

答案 0 :(得分:1)

在@FlorianBlume及其建议的q & a的帮助下,问题得以解决。这是转换矩阵的代码:

Qt3DCore::QEntity *newEntity = new Qt3DCore::QEntity();

Qt3DExtras::QConeMesh *mesh = new Qt3DExtras::QConeMesh();
mesh->setTopRadius(0.2);
mesh->setBottomRadius(1.0);
mesh->setLength(2.0);
for(int i = 0; i < mesh->geometry()->attributes().size(); ++i) {
    mesh->geometry()->attributes().at(i)->buffer()->setSyncData(true);
}

newEntity->addComponent(mesh);

/* 
 * Now transform the cone to change its default axis:
 */

QVector3D k = QVector3D(0, 1, 0);   // Current cone axis
QVector3D n = QVector3D(38.0572, 29.2247, 35.3996); // To-be cone axis
n *= -1; // Inverse cone direction
n.normalize();
float teta = qAcos(QVector3D::dotProduct( k, n ));
QVector3D b = QVector3D::crossProduct( k , n );
b.normalize();

float q0 = qCos( teta / 2.0 );
float q1 = qSin( teta / 2.0 ) * b.x();
float q2 = qSin( teta / 2.0 ) * b.y();
float q3 = qSin( teta / 2.0 ) * b.z();

QMatrix4x4 Q = QMatrix4x4(
            qPow(q0, 2) + qPow(q1, 2) - qPow(q2, 2) - qPow(q3, 2), 2 * ( q1 * q2 - q0 * q3 )                            , 2 * ( q1 * q3 + q0 * q2 )                            , 0,
            2 * ( q2 * q1 + q0 * q3 )                            , qPow(q0, 2) - qPow(q1, 2) + qPow(q2, 2) - qPow(q3, 2), 2 * ( q2 * q3 - q0 * q1 )                            , 0,
            2 * ( q3 * q1 - q0 * q2 )                            , 2 * ( q3 * q2 + q0 * q1 )                            , qPow(q0, 2) - qPow(q1, 2) - qPow(q2, 2) + qPow(q3, 2), 0,
            0                                                    , 0                                                    , 0                                                    , 0
            );

Q.transposed(); // Transpose is needed to be able to employ "Q" matrix with Qt3DCore::QTransform

Q.setColumn(3, QVector4D(QVector3D(18.2066, 38.2821, 42.5333), 1)); // Set translation/move to be equal to QVector3D(18.2066, 38.2821, 42.5333)
                                                         // In addition to rotation, we want to move/translate our cone too!
                                                         // https://www.euclideanspace.com/maths/geometry/affine/matrix4x4/index.htm

Qt3DCore::QTransform *transform = new Qt3DCore::QTransform();
transform->setMatrix(Q);
newEntity->addComponent(transform);

具有默认轴的原始圆锥和具有新轴的变换圆锥如下所示:

Original cone and transformed cone