代码之家  ›  专栏  ›  技术社区  ›  Megidd

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

  •  0
  • Megidd  · 技术社区  · 6 年前

    我有一个基准 line 这样地:

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

    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


    现在我想旋转/变换我的圆锥体,使我的圆锥体轴平行于我的基准 线 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);
    

    我不知道如何组装转换组件,使锥轴与基准平行


    我研究过这些,但到目前为止运气不佳:

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

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

    1 回复  |  直到 6 年前
        1
  •  1
  •   Megidd    6 年前

    在@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