代码之家  ›  专栏  ›  技术社区  ›  Cooper.Wu

如何仅在Z轴上旋转三维对象?

  •  2
  • Cooper.Wu  · 技术社区  · 16 年前

    我们使用了3dtools( http://3dtools.codeplex.com )为了绘制一条三维线,它允许用户用鼠标旋转它。我有个问题,如何限制用户只能在Z轴上旋转?还是只在X轴,Y轴上?

    
    <tool:TrackballDecorator >
        <tool:Interactive3DDecorator 
             ContainsInk="True">
            <Viewport3D>
                <Viewport3D.Camera>
                    <PerspectiveCamera x:Name="camera1" Position="4.89,-11,5" LookDirection="-4.89,11,-5"
                                       FieldOfView="45" UpDirection="-4,9,-1"/>
                </Viewport3D.Camera>
                <ModelVisual3D x:Name="modelVisual3D">
                    <ModelVisual3D.Children>
                        <tool:ScreenSpaceLines3D x:Name="axisX" Color="Cyan"
                            Thickness="2.0"
                            Points="0, 0, 0, 5, 0, 0" />
                        <tool:ScreenSpaceLines3D  Color="LightCyan"
                            Thickness="2.0"
                            Points="-5, 0, 0, 0, 0, 0" />
                        <tool:ScreenSpaceLines3D x:Name="axisY" Color="Green"
                            Thickness="2.0"
                            Points="0,0,0, 0,5,0"/>
                        <tool:ScreenSpaceLines3D  Color="LightGreen"
                            Thickness="2.0"
                            Points="0,-5,0, 0,0,0"/>
    
                        <tool:ScreenSpaceLines3D x:Name="axisZ" Color="Red"
                            Thickness="2.0"
                            Points="0,0,0, 0,0,5"/>
                        <tool:ScreenSpaceLines3D  Color="LightPink"
                            Thickness="2.0"
                            Points="0,0,-5, 0,0,0"/>
                    </ModelVisual3D.Children>
                </ModelVisual3D>
            </Viewport3D>
        </tool:Interactive3DDecorator>
    </tool:TrackballDecorator>
    
    1 回复  |  直到 16 年前
        1
  •  1
  •   SMART_n    16 年前

    将“trackball.cs”中的trackball.track()方法替换为以下方法:

    private void Track(Point currentPosition)
        {
            Vector3D currentPosition3D = ProjectToTrackball(
                EventSource.ActualWidth, EventSource.ActualHeight, currentPosition);
    
            Vector3D axisToRotate = new Vector3D(0, 1, 0); // Rotation around Y only
    
            Vector3D currProjected = Vector3D.CrossProduct(axisToRotate, currentPosition3D);
            Vector3D prevProjected = Vector3D.CrossProduct(axisToRotate, _previousPosition3D);
            double angle = Vector3D.AngleBetween(currProjected, prevProjected);            
    
            int sign = Math.Sign(Vector3D.DotProduct(
                axisToRotate, 
                Vector3D.CrossProduct(_previousPosition3D, currentPosition3D)));
    
            if (sign != 0)
            {
                Quaternion delta = new Quaternion(axisToRotate * sign, -angle);
    
                AxisAngleRotation3D r = _rotation;
                Quaternion q = new Quaternion(_rotation.Axis, _rotation.Angle);
    
                q *= delta;
    
                _rotation.Axis = q.Axis;
                _rotation.Angle = q.Angle;
            }
    
            _previousPosition3D = currentPosition3D;
        }
    
    推荐文章