如何组合3D模型的多个变换?

时间:2015-09-21 18:32:18

标签: rotation translate

我们正在使用Helix Toolkit来处理3D模型。场景是应使用Double up / down值输入以混合顺序平移和旋转对象。

不同轴上的多次旋转工作正常。但是,当对象在其中一个轴上平移时,后续旋转会移动对象,而不是使用现有偏移旋转,因为它是旋转中心。

这是步骤的要点 -

  1. 从Transform3DGroup中删除现有的MatrixTransform3D。
  2. 创建新的旋转或平移变换。
  3. 如果旋转模型,则将前一个平移变换添加到新的旋转变换。
  4. 如果要翻译模型,请将之前的旋转变换添加到新的平移变换。
  5. 将新的matrixtransform3D添加到transform3dgroup中,该transform3dgroup被绑定为XAML中的模型转换。
  6. 我想知道结合翻译和旋转变换的正确方法是什么。感谢您的帮助。

    代码:

    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;
            }
    

0 个答案:

没有答案