WPF 3D。将3D坐标转换为2D坐标时的奇怪行为

时间:2014-07-24 09:19:25

标签: c# wpf 3d transformation projection

出于某种原因,从3D到2D的对话失败了我的相机的一些旋转状态。

我写了一个小示例应用程序来演示我的问题。当您按下示例应用程序左下角的“旋转摄像头”小按钮时,会出现错误的计算。在此旋转之后,看起来其中一个线框(红线)是以某种方式镜像的。

这是我的例子。

的Xaml:

<Window x:Class="Projection2D3D.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="600" Width="800">
<Grid>
    <Viewport3D x:Name="Viewport">
        <Viewport3D.Camera>
            <PerspectiveCamera x:Name="Cam" Position="-.9,-.9,-.5" LookDirection="0,0,1" UpDirection="0,-1,0"
                    FieldOfView="90" />
        </Viewport3D.Camera>
        <ModelVisual3D>
            <ModelVisual3D.Content>
                <AmbientLight />
            </ModelVisual3D.Content>
        </ModelVisual3D>
        <ModelVisual3D x:Name="ModelVisual3D">
            <ModelVisual3D.Content>
                <GeometryModel3D>
                    <GeometryModel3D.Geometry>
                        <MeshGeometry3D
                                Positions="-1,-1,0 1,-1,0 -1,1,0 1,1,0"
                                TriangleIndices="0 1 2  1 3 2" />
                    </GeometryModel3D.Geometry>
                    <GeometryModel3D.BackMaterial>
                        <DiffuseMaterial Brush="Blue"/>
                    </GeometryModel3D.BackMaterial>
                </GeometryModel3D>
            </ModelVisual3D.Content>
        </ModelVisual3D>
    </Viewport3D>
    <Canvas x:Name="CnvOverlay"></Canvas>
    <Button VerticalAlignment="Bottom" HorizontalAlignment="Left" Content="Rotate Camera" Margin="10" Click="BtnRotate_OnClick"/>
    <TextBlock x:Name="TextBlock" Text="Wireframe correct!" FontWeight="Bold" FontSize="20" IsHitTestVisible="False"/>
</Grid>

C#:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        CompositionTarget.Rendering +=CompositionTarget_Rendering;
    }

    void CompositionTarget_Rendering(object sender, EventArgs e)
    {
        UpdateWireframe();
    }

    void UpdateWireframe()
    {
        GeometryModel3D model = ModelVisual3D.Content as GeometryModel3D;

        CnvOverlay.Children.Clear();

        if (model != null)
        {
            GeneralTransform3DTo2D transform = ModelVisual3D.TransformToAncestor(Viewport);
            MeshGeometry3D geometry = model.Geometry as MeshGeometry3D;

            for (int i = 0; i < geometry.TriangleIndices.Count; )
            {
                Polygon p = new Polygon();
                p.Stroke = Brushes.Red;
                p.StrokeThickness = 1;
                p.Points.Add(transform.Transform(geometry.Positions[geometry.TriangleIndices[i++]]));
                p.Points.Add(transform.Transform(geometry.Positions[geometry.TriangleIndices[i++]]));
                p.Points.Add(transform.Transform(geometry.Positions[geometry.TriangleIndices[i++]]));
                CnvOverlay.Children.Add(p);
            }
        }
    }

    private void BtnRotate_OnClick(object sender, RoutedEventArgs e)
    {
        (sender as UIElement).IsEnabled = false;
        this.TextBlock.Text = "Wireframe incorrect!";

        var rotation = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(1, 0, 0), 40), new Point3D(-1, -1, 0));
        UpdateCamera(rotation);
    }

    private void UpdateCamera(Transform3D transform3D)
    {
        Cam.Position = transform3D.Transform(Cam.Position);
        Cam.UpDirection = transform3D.Transform(Cam.UpDirection);
        Cam.LookDirection = transform3D.Transform(Cam.LookDirection);
    }
}

希望有人可以帮助我。提前谢谢。

1 个答案:

答案 0 :(得分:0)

http://www.neoaxis.com/forum/viewtopic.php?f=2&t=6692。这里也讨论了这个问题。