原文: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.平移后:

 

 

WPF 3D 平移模型+动画(桥梁检测系统)的更多相关文章

  1. WPF 3D 模型旋转

    原文:WPF 3D 模型旋转 WPF 是 Microsoft 在 Framework3.0 中支持的一种技术,它能作出很绚丽的界面,同时它也支持3D的操作.在3D操作主要包括平移(Translate) ...

  2. WPF在3D Cad模型中利用TextureCoordinates实现颜色渐变显示偏差值的变化

    原文:WPF在3D Cad模型中利用TextureCoordinates实现颜色渐变显示偏差值的变化 注:最近在做3D机械模型重建方面的软件,需要根据光栅传感器采集的数据绘制3D图形,并显示出色差以及 ...

  3. WPF 3D模型 3D场景

    1.首先得说明的是这并不是真正的3D,模型被导出为一系列的单个图片,例如一个3D户型图,以某个视角旋转360°,渲染出一系列连续的单个图片文件. 2.在Image.MouseMove事件中添加相应代码 ...

  4. WPF 3D:简单的Point3D和Vector3D动画创造一个旋转的正方体

    原文:WPF 3D:简单的Point3D和Vector3D动画创造一个旋转的正方体 运行结果: 事实上很简单,定义好一个正方体,处理好纹理.关于MeshGeometry3D的正确定义和纹理这里就不多讲 ...

  5. WPF 3D中多个模型如何设置某一个在最前?

    原文:WPF 3D中多个模型如何设置某一个在最前? 问题:我们的模型包括导入的3D solid模型和axis坐标轴模型,当模型旋转的时候,3D会将axis挡住. 期望:axis一直在最前面,不会被3D ...

  6. WPF 3D模型的一个扩展方法

    原文:WPF 3D模型的一个扩展方法 在WPF 3D中,我们常常需要改变一个ModelVisual3D对象的颜色. 先说说ModelVisual3D,本质上3D模型都是由一个个的三角形构成的,并且经过 ...

  7. WPF 3D动态加载模型文件

    原文:WPF 3D动态加载模型文件 这篇文章需要读者对WPF 3D有一个基本了解,至少看过官方的MSDN例子. 一般来说关于WPF使用3D的例子,都是下面的流程: 1.美工用3DMAX做好模型,生成一 ...

  8. WPF 3D 知识点大全以及实例

    引言 现在物联网概念这么火,如果监控的信息能够实时在手机的客服端中以3D形式展示给我们,那种体验大家可以发挥自己的想象. 那生活中我们还有很多地方用到这些,如上图所示的Kinect 在医疗上的应用,当 ...

  9. Qt Creator中的3D绘图及动画教程(参照NeHe)

    Qt Creator中的3D绘图及动画教程(参照NeHe) http://blog.csdn.net/cly116/article/details/47184729 刚刚学习了Qt Creator,发 ...

随机推荐

  1. AE内置Command控件使用

    樱木 原文 AE内置Command控件使用 直接使用AE内置的Command控件来完成功能 1.拉框放大 /// <summary> /// 放大 /// </summary> ...

  2. [Angular2 Form] Reactive Form, show error message for one field

    <form [formGroup]="reactiveForm" novalidate autocomplete="off"> <div cl ...

  3. TensorFlow on Windows: “Couldn't open CUDA library cudnn64_5.dll”

    TensorFlow on Windows: "Couldn't open CUDA library cudnn64_5.dll" 在 windows 下,使用 import te ...

  4. 借助gdb实现pstack

    pstack.sh: #! /bin/sh if [ -z $1 ] then echo "gdb script for print stack" echo "usage ...

  5. [CSS] Reduce Ambiguity in Class Names using a Naming Convention

    A solid naming convention makes it less likely to run into naming conflicts and helps establish a se ...

  6. Android 为开发者准备的最佳 Android 函数库(2016 年版)

    本文是翻译自 CloudRAIL 的官方博客(https://cloudrail.com/best-android-libraries-for-developers/),本文中分享的 Android ...

  7. Error while trying to retrieve text for error ORA-12705

    今天, 按照以前的学习笔记, 配置ProC 但是, 却发生了如题的错误. Google一下, 都是NLS_LANG环境变量设置有问题, 我核一下没有问题. 问题在哪? 原来是ORACLE_HOME环境 ...

  8. [Angular] Auxiliary named router outlets

    Define a auxilliary router: export const ROUTES: Routes = [ { path: 'folder/:name', component: MailF ...

  9. PHP接口类interface使用方法

    PHP同大多数的面向对象语言一样,并不支持多重继承.少数支持多重继承的语言中最著名的就是C++和Smalltalk.如果需要实现多重继承功能,在PHP中,可以通过接口,它是PHP解决多重继承问题的方法 ...

  10. Vagi单点登录1.0

    Vagi是一款基于CAS(CAS v4)的Web应用单点登录系统.(cas web https://github.com/Jasig/cas) 对数据库用户存储支持 加入登录验证码 新浪微博和QQ互联 ...