这里有一个代码示例:
这个小的C++程序输出了一个轴向量为
"几乎"可行。问题是,如果你尝试它,你会发现旋转在动画的前半段完全偏离了其预期的旋转轴,但在动画的后半段修正了自己。起始旋转很好,目标旋转也很好,但其中发生的任何事情都不够好。如果我使用较小的角度(如45度)而不是90度,效果会更好;如果我使用较大的角度(如180度)而不是45度会更糟糕,那时它只会在随机方向上旋转,直到达到最终目标。
如何使这种动画在起始旋转和目标旋转之间看起来正确?
------------------- 编辑 -------------------
我再添加一个条件:我所寻找的答案必须完全提供与我上面提供的截图相同的输出结果。
例如,将3个旋转轴分成3个单独的旋转变换并不能给我正确的结果。"
import QtQuick 2.0
Item {
width: 200; height: 200
Rectangle {
width: 100; height: 100
anchors.centerIn: parent
color: "#00FF00"
Rectangle {
color: "#FF0000"
width: 10; height: 10
anchors.top: parent.top
anchors.right: parent.right
}
}
}
将会生成如下输出:
我现在想要从这个绿色矩形的中心应用一个3D旋转。首先,我想通过X轴旋转-45度(向下弯曲),然后通过Y轴旋转-60度(向左转)。
我使用了以下C++代码片段,并结合GLM帮助我计算轴和角度:
// generate rotation matrix from euler in X-Y-Z order
// please note that GLM uses radians, not degrees
glm::mat4 rotationMatrix = glm::eulerAngleXY(glm::radians(-45.0f), glm::radians(-60.0f));
// convert the rotation matrix into a quaternion
glm::quat quaternion = glm::toQuat(rotationMatrix);
// extract the rotation axis from the quaternion
glm::vec3 axis = glm::axis(quaternion);
// extract the rotation angle from the quaternion
// and also convert it back to degrees for QML
double angle = glm::degrees(glm::angle(quaternion));
这个小的C++程序输出了一个轴向量为
{-0.552483, -0.770076, 0.318976}
和角度为73.7201
。因此,我把我的示例代码更新成了这样:import QtQuick 2.0
Item {
width: 200; height: 200
Rectangle {
width: 100; height: 100
anchors.centerIn: parent
color: "#00FF00"
Rectangle {
color: "#FF0000"
width: 10; height: 10
anchors.top: parent.top
anchors.right: parent.right
}
transform: Rotation {
id: rot
origin.x: 50; origin.y: 50
axis: Qt.vector3d(-0.552483, -0.770076, 0.318976)
angle: 73.7201
}
}
}
这给了我想要看到的内容:
到目前为止一切都很好。现在来到了难点。如何实现动画呢?例如,如果我想从{45.0、60.0、0}到{45.0、60.0、90.0}。换句话说,我想从这里进行动画
到这里
我将目标旋转插入到这里
// generate rotation matrix from euler in X-Y-Z order
// please note that GLM uses radians, not degrees
glm::mat4 rotationMatrix = glm::eulerAngleXYZ(glm::radians(-45.0f), glm::radians(-60.0f), glm::radians(90.0f);
// convert the rotation matrix into a quaternion
glm::quat quaternion = glm::toQuat(rotationMatrix);
// extract the rotation axis from the quaternion
glm::vec3 axis = glm::axis(quaternion);
// extract the rotation angle from the quaternion
// and also convert it back to degrees for QML
double angle = glm::degrees(glm::angle(quaternion));
这给了我一个轴向为{-0.621515, -0.102255, 0.7767}
,角度为129.007
的旋转轴。
因此,我将此动画添加到我的示例中。
ParallelAnimation {
running: true
Vector3dAnimation {
target: rot
property: "axis"
from: Qt.vector3d(-0.552483, -0.770076, 0.318976)
to: Qt.vector3d(-0.621515, -0.102255, 0.7767)
duration: 4000
}
NumberAnimation {
target: rot;
property: "angle";
from: 73.7201; to: 129.007;
duration: 4000;
}
}
"几乎"可行。问题是,如果你尝试它,你会发现旋转在动画的前半段完全偏离了其预期的旋转轴,但在动画的后半段修正了自己。起始旋转很好,目标旋转也很好,但其中发生的任何事情都不够好。如果我使用较小的角度(如45度)而不是90度,效果会更好;如果我使用较大的角度(如180度)而不是45度会更糟糕,那时它只会在随机方向上旋转,直到达到最终目标。
如何使这种动画在起始旋转和目标旋转之间看起来正确?
------------------- 编辑 -------------------
我再添加一个条件:我所寻找的答案必须完全提供与我上面提供的截图相同的输出结果。
例如,将3个旋转轴分成3个单独的旋转变换并不能给我正确的结果。"
transform: [
Rotation {
id: zRot
origin.x: 50; origin.y: 50;
angle: 0
},
Rotation {
id: xRot
origin.x: 50; origin.y: 50;
angle: -45
axis { x: 1; y: 0; z: 0 }
},
Rotation {
id: yRot
origin.x: 50; origin.y: 50;
angle: -60
axis { x: 0; y: 1; z: 0 }
}
]
我会收到这个:
这是不正确的。