以平行于特定线的方式旋转几何体
Rotate a geometry in a way that it would be parallel to a specific line
我有一个像这样的基准 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)
:
现在我想 rotate/transform 我的圆锥体轴平行于我的基准 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);
我不知道如何 assemble 我的变换组件,使我的圆锥轴平行于基准 line
。
我研究过这些,但到目前为止没有运气:
在@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);
具有默认轴的原始圆锥体和具有新轴的变换圆锥体如下所示:
我有一个像这样的基准 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)
:
现在我想 rotate/transform 我的圆锥体轴平行于我的基准 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);
我不知道如何 assemble 我的变换组件,使我的圆锥轴平行于基准 line
。
我研究过这些,但到目前为止没有运气:
在@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);
具有默认轴的原始圆锥体和具有新轴的变换圆锥体如下所示: