我们正在使用Helix Toolkit来处理3D模型。场景是应使用Double up / down值输入以混合顺序平移和旋转对象。
不同轴上的多次旋转工作正常。但是,当对象在其中一个轴上平移时,后续旋转会移动对象,而不是使用现有偏移旋转,因为它是旋转中心。
这是步骤的要点 -
我想知道结合翻译和旋转变换的正确方法是什么。感谢您的帮助。
代码:
Matrix3D CalculateRotationMatrix()
{
Point3D rotationCenter = new Point3D(-1 * MoveX.DataValue, -1 * MoveY.DataValue, -1 * MoveZ.DataValue);
_rotateMatrix = new Matrix3D();
_rotateMatrix.RotateAt(new Quaternion(_xAxisVector3D, RotateX.DataValue), rotationCenter);
_rotateMatrix.RotateAt(new Quaternion(_yAxisVector3D * _rotateMatrix, RotateY.DataValue), rotationCenter);
_rotateMatrix.RotateAt(new Quaternion(_zAxisVector3D * _rotateMatrix, RotateZ.DataValue), rotationCenter);
return _rotateMatrix;
}
Matrix3D CalculateTranslationMatrix() {
_translateMatrix = new Matrix3D();
_translateMatrix.Translate(new Vector3D(MoveX.DataValue, MoveY.DataValue, MoveZ.DataValue));
return _translateMatrix; }
void UpdateTransform(bool isRotate = false)
{
if (ModelTransform.DataValue.Children.Count > 0)
for (int i = 0; i < ModelTransform.DataValue.Children.Count; i++)
{
ModelTransform.DataValue.Children.Remove(ModelTransform.DataValue.Children[i]);
}
Matrix3D newMatrix3D;
if (isRotate)
{
newMatrix3D = CalculateRotationMatrix();
newMatrix3D.Append(_translateMatrix);
}
else
{
newMatrix3D = CalculateTranslationMatrix();
newMatrix3D.Prepend(_rotateMatrix);
}
ModelTransform.DataValue.Children.Add(new MatrixTransform3D(newMatrix3D));
}
ModelTransform.DataValue的类型为Transform3DGroup,并绑定到xaml中的3D模型。
更新的代码:(旋转不会移动模型,但不会围绕新的中心点旋转)
void UpdateTransform(eMove move)
{
if (ModelTransform.DataValue.Children.Count > 0)
for (int i = 0; i < ModelTransform.DataValue.Children.Count; i++)
{
ModelTransform.DataValue.Children.Remove(ModelTransform.DataValue.Children[i]);
}
Matrix3D newMatrix3D = new Matrix3D();
switch (move)
{
case eMove.Translate:
newMatrix3D = CalculateTranslationMatrix();
newMatrix3D.Prepend(_rotateMatrix);
break;
case eMove.Rotate:
// Translate the model
newMatrix3D = _translateMatrix;
double xAfterRotateTranslate = newMatrix3D.OffsetX;
double yAfterRotateTranslate = newMatrix3D.OffsetY;
double zAfterRotateTranslate = newMatrix3D.OffsetZ;
// Rotate the model
newMatrix3D.Append(CalculateRotationMatrix());
_xAfterRotate = newMatrix3D.OffsetX;
_yAfterRotate = newMatrix3D.OffsetY;
_zAfterRotate = newMatrix3D.OffsetZ;
//Translate back the difference after the rotation
Matrix3D negativeTranslate = new Matrix3D();
negativeTranslate.Translate(new Vector3D(xAfterRotateTranslate - _xAfterRotate,
yAfterRotateTranslate - _yAfterRotate, zAfterRotateTranslate * _zAfterRotate));
newMatrix3D.Append(negativeTranslate);
break;
}
ModelTransform.DataValue.Children.Add(new MatrixTransform3D(newMatrix3D));
}
Matrix3D CalculateTranslationMatrix()
{
_translateMatrix = new Matrix3D();
_translateMatrix.Translate(new Vector3D(MoveX.DataValue, MoveY.DataValue, MoveZ.DataValue));
return _translateMatrix;
}
Matrix3D CalculateRotationMatrix()
{
Point3D rotationCenter = new Point3D(-1 * MoveX.DataValue, -1 * MoveY.DataValue, -1 * MoveZ.DataValue);
_rotateMatrix = new Matrix3D();
_rotateMatrix.RotateAt(new Quaternion(_xAxisVector3D, RotateX.DataValue), rotationCenter);
_rotateMatrix.RotateAt(new Quaternion(_yAxisVector3D * _rotateMatrix, RotateY.DataValue), rotationCenter);
_rotateMatrix.RotateAt(new Quaternion(_zAxisVector3D * _rotateMatrix, RotateZ.DataValue), rotationCenter);
return _rotateMatrix;
}