首页 技术 正文
技术 2022年11月20日
0 收藏 739 点赞 2,714 浏览 2626 个字

原文:WPF 3D 平移模型+动画(桥梁检测系统)

关于WPF 3D,网上有很多旋转的例子,但是关于平移的例子并不是太多。本文并非WPF 3D扫盲篇,因此需要对WPF 3D有一定了解,至少知道Viewport, PerspectiveCamera, ModelVisual3D等数据结构。需要了解WPF 3D的基础知识,可以参考MSDN: http://msdn.microsoft.com/zh-cn/library/ms747437.aspx

 

1. 摄像机平移OR物体平移:

WPF场景主要是由这两部分构成的:摄像机,物体。可以想象一下,自己拿着台摄像机正对着某个物体进行拍摄。

那么当发生平移的时候有两种方法,第一种是将摄像机平移;第二种是将物体平移。相对来说,摄像机平移实现较复杂,效率较高;物体平移效率较低,实现简单。

本文实现的是物体平移,如果希望做摄像机平移的朋友可以不往下读了。

 

2. 在本项目中平移的操作流程: 

1. 程序启动时可以看到整个3D场景,类似一个沙盘,此时旋转等操作会围绕沙盘中心;

2. 双击沙盘某个地方,将沙盘中心移动到双击的地方,此时旋转等操作会围绕新的沙盘中心。

 

3. 平移的算法:

1.获取双击屏幕后鼠标在3D中相对应的点,主要利用了射线和3D碰撞的一个原理。代码上主要应用的就是VisualTreeHelper.HitTest函数,它会将结果传入一个回调函数中,我们这里是HTResultCenter.

void BridgeVisual_MouseDoubleClick(object sender, MouseButtonEventArgs args){  

     Point mouseposition = args.GetPosition(ViewPort);

   MoveCenter(mouseposition);

}

 

 public void MoveCenter(Point mouseposition) {      PointHitTestParameters pointparams = new PointHitTestParameters(mouseposition);      VisualTreeHelper.HitTest(ViewPort, null, HTResultCenter, pointparams);

 } 

 

 private HitTestResultBehavior HTResultCenter(HitTestResult result) {      RayHitTestResult rayResult = result as RayHitTestResult;      if (rayResult != null)      {           //这就是鼠标点击后在3D中的坐标           var hitPoint = rayResult.PointHit;           …

      }

 } 

 

2.根据相机位置 + 相机的投射方向 = 获取相机在3D上投影的点,camera.Postion就是摄像机在3D世界中的位置了,camera.LookDirection就是摄像机看的方向。那么两者加起来就可以获取这个摄像机投射过后的位置了。 

 

  ////相机位置
  var cameraPostion = Camera.Position;

               

  ////相机看的方向
  var lookDirection = Camera.LookDirection;

  /// 获取相机在3D投影的点 

  var x = cameraPostion.X + lookDirection.X;

  var y = cameraPostion.Y + lookDirection.Y;

  var z = cameraPostion.Z + lookDirection.Z;

 

 

3. 那么利用摄像机投射的位置 – 鼠标双击的位置就可以获取物体应该偏移的量了,WPF中本来就有Transform3D 这个东西进行平移,

此处应用了动画DoubleAnimation,所以代码有点多。

DoubleAnimation doubleAnimationX = new DoubleAnimation();

doubleAnimationX.BeginTime = , , );

doubleAnimationX.Duration = TimeSpan.FromMilliseconds();

doubleAnimationX.From = Transform3D.OffsetX;

doubleAnimationX.To = x – hitPoint.X;

DoubleAnimation doubleAnimationY = new DoubleAnimation();

doubleAnimationY.BeginTime = , , );

doubleAnimationY.Duration = TimeSpan.FromMilliseconds();

doubleAnimationY.From = _Transform3D.OffsetY;

doubleAnimationY.To = y – hitPoint.Y;

DoubleAnimation doubleAnimationZ = new DoubleAnimation();

doubleAnimationZ.BeginTime = , , );

doubleAnimationZ.Duration = TimeSpan.FromMilliseconds();

doubleAnimationZ.From = Transform3D.OffsetZ;

doubleAnimationZ.To = z – hitPoint.Z;

Transform3D.BeginAnimation(TranslateTransform3D.OffsetXProperty, doubleAnimationX);

Transform3D.BeginAnimation(TranslateTransform3D.OffsetYProperty, doubleAnimationY);  

Transform3D.BeginAnimation(TranslateTransform3D.OffsetZProperty, doubleAnimationZ);  

 

 

4. 最终的效果:

1.平移前:

 

 2.平移后:

 

 

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:8,958
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,482
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,328
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,111
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,743
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,777