博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
WPF 3D变换应用
阅读量:5045 次
发布时间:2019-06-12

本文共 4872 字,大约阅读时间需要 16 分钟。

 WPF可以提供的3D模型使我们可以轻松地创建3D实体,虽然目前来看还很有一些性能上的问题,不过对于一些简单的3D应用应该是可取的,毕竟其开发效率高,而且也容易上手。

        下面给大家演示的是使用在WPF 3D上实现视角变换,通过鼠标拖动来变换观察视角,通过滚轮来放缩视距。 

        首先创建一个3D立方体,立方体是由六个面构成(F1, F2 ....F6)其XAML代码如下:

 

         在Viewport中用六个面构成一个立方体, 每一个面都是一个GeometryModel3D。

下面就是如何来实现通过鼠标拖动来变换视角的功能。首先给Window对象添加几个有关的鼠标的事件:MouseMove、MouseLeftButtonDown和MouseWheel。

 

 

说明一下使用到的几个变量:

        

其中MouseLeftButtonDown是用来获取鼠标在进入拖动状态之前的位置,这样我们就可以根据鼠标位置的改变类变换视角。

Point mouseLastPosition;

private void Viewport3D_MouseLeftButtonDown(object sender, MouseButtonEventArgs e){    mouseLastPosition = e.GetPosition(this);}

 

       下面是MouseMove事件,实现视角的变换。首先鼠标在拖动的过程中,可能发生水平方向上的变化和垂直方向上的变化,所以,我们将对不同的变化方向进行不同的变换。这里我将水平变换和垂直变换已经分别封装至两个方法中:HorizontalTransform(水平变换)和VerticalTransform(垂直变换)

private void Viewport3D_MouseMove(object sender, MouseEventArgs e){    if (Mouse.LeftButton == MouseButtonState.Pressed)    {        Point newMousePosition = e.GetPosition(this);         if (mouseLastPosition.X != newMousePosition.X)        {            HorizontalTransform(mouseLastPosition.X < newMousePosition.X, mouseDeltaFactor);//水平变换        }         if (mouseLastPosition.Y != newMousePosition.Y)// change position in the horizontal direction        {             VerticalTransform(mouseLastPosition.Y > newMousePosition.Y, mouseDeltaFactor);//垂直变换        }        mouseLastPosition = newMousePosition;    }}

 

  接下来我们就来看一下这两个变换方法的具体实现:

 

垂直变换:

 
private void VerticalTransform(bool upDown, double angleDeltaFactor)
{
    Vector3D postion = new Vector3D(camera.Position.X, camera.Position.Y, camera.Position.Z);
    Vector3D rotateAxis = Vector3D.CrossProduct(postion, camera.UpDirection);
    RotateTransform3D rt3d = new RotateTransform3D();
    AxisAngleRotation3D rotate = new AxisAngleRotation3D(rotateAxis, angleDeltaFactor * (upDown ? -1 : 1));
    rt3d.Rotation = rotate;
    Matrix3D matrix = rt3d.Value;
    Point3D newPostition = matrix.Transform(camera.Position);
    camera.Position = newPostition;
    camera.LookDirection = new Vector3D(-newPostition.X, -newPostition.Y, -newPostition.Z);
    //update the up direction
    Vector3D newUpDirection = Vector3D.CrossProduct(camera.LookDirection, rotateAxis);
    newUpDirection.Normalize();
    camera.UpDirection = newUpDirection;
}
水平变换:
private void HorizontalTransform(bool leftRight, double angleDeltaFactor)
{
    Vector3D postion = new Vector3D(camera.Position.X, camera.Position.Y, camera.Position.Z);
    Vector3D rotateAxis = camera.UpDirection;
    RotateTransform3D rt3d = new RotateTransform3D();
    AxisAngleRotation3D rotate = new AxisAngleRotation3D(rotateAxis, angleDeltaFactor * (leftRight ? -1 : 1));
    rt3d.Rotation = rotate;
    Matrix3D matrix = rt3d.Value;
    Point3D newPostition = matrix.Transform(camera.Position);
    camera.Position = newPostition;
    camera.LookDirection = new Vector3D(-newPostition.X, -newPostition.Y, -newPostition.Z);
}
 

最后还有一个鼠标滚轮调节视距的变换,如下:

 

 
private void Viewport3D_MouseWheel(object sender, MouseWheelEventArgs e)
{
    double scaleFactor = 3;
    //120 near ,   -120 far
    System.Diagnostics.Debug.WriteLine(e.Delta.ToString());
    Point3D currentPosition = camera.Position;
    Vector3D lookDirection = camera.LookDirection;//new Vector3D(camera.LookDirection.X, camera.LookDirection.Y, camera.LookDirection.Z);
    lookDirection.Normalize();
    lookDirection *= scaleFactor;
    if (e.Delta == 120)//getting near
    {
        if ((currentPosition.X + lookDirection.X) * currentPosition.X > 0)
        {
            currentPosition += lookDirection;
        }
    }
    if (e.Delta == -120)//getting far
    {
        currentPosition -= lookDirection;
    }
    Point3DAnimation positionAnimation = new Point3DAnimation();
    positionAnimation.BeginTime = new TimeSpan(0, 0, 0);
    positionAnimation.Duration = TimeSpan.FromMilliseconds(100);
    positionAnimation.To = currentPosition; 
    positionAnimation.From = camera.Position;
    positionAnimation.Completed += new EventHandler(positionAnimation_Completed);
    camera.BeginAnimation(PerspectiveCamera.PositionProperty, positionAnimation, HandoffBehavior.Compose);
}
 

 

有了这个小程序之后,我们以后如果需要制作WPF 3D实体,也可以通过它来360度全方位地观测构建的3D实体。

 

转载于:https://www.cnblogs.com/DreamRecorder/p/9391485.html

你可能感兴趣的文章
python数据类型及相关操作
查看>>
设计模式之- 代理模式(Proxy Pattern)
查看>>
React Navigation基本用法
查看>>
JQuery_004_触发事件
查看>>
iOS开发(Objective-C)常用库索引
查看>>
[源码和文档分享]基于C#和SQL SERVER的校园知识问答论坛网站的设计与实现
查看>>
面向对象基础项目----图书管理系统(数组)
查看>>
BZOJ 3731 3731: Gty的超级妹子树 [树上size分块 !]
查看>>
BZOJ 2049: [Sdoi2008]Cave 洞穴勘测 [LCT]
查看>>
ubuntu15.10安装搜狗拼音输入法
查看>>
低调发布一个百度谷歌关键字搜索工具
查看>>
js函数的节流与防抖
查看>>
Web系列:网页版超级计算器,仿百度搜索框,仿百度视频选项卡
查看>>
Redis的架构以及有关事务使用场景
查看>>
LeetCode Reverse Words in a String II
查看>>
安卓开发之调用摄像头、相册
查看>>
IT职场人生系列之十四:经验积累
查看>>
01011_怎么打开任务管理器?win7打开任务管理器方法
查看>>
用仿ActionScript的语法来编写html5——终篇,LegendForHtml5Programming1.0开源库件
查看>>
服务器端异步接受SOKCET请求
查看>>