在WPF中使用PlaneProjection模拟动态3D效果

简介: 原文:在WPF中使用PlaneProjection模拟动态3D效果  虽然在WPF中也集成了3D呈现的功能,在简单的3D应用中,有时候并不需要真实光影的3D场景。毕竟使用3D引擎会消耗很多资源,有时候使用各种变换和假的阴影贴图也能设计出既省资源,又有很好用户体验的“伪”3D界面。
原文: 在WPF中使用PlaneProjection模拟动态3D效果

  虽然在WPF中也集成了3D呈现的功能,在简单的3D应用中,有时候并不需要真实光影的3D场景。毕竟使用3D引擎会消耗很多资源,有时候使用各种变换和假的阴影贴图也能设计出既省资源,又有很好用户体验的“伪”3D界面。

  在Silverlight中,因为性能问题,一般并不使用真3D引擎,微软为Silverlight提供了System.Windows.Media.PlaneProjection 类,用投影变换来模拟3D的效果。

  下面让我们看下一个 Microsoft Expression Blend 4 提供的示例 Wall3D (位于帮助>欢迎屏幕>示例)。

 
 
  大家不要被这个可以流畅滚动的3D图片墙所迷惑,其实这只是一个ListBox控件。MainPage中给ListBox定义了一个ItemsPanelTemplate,使用新的控件来作为ListBox中Items的布局控件,这个
控件就是这个项目最核心的类:CircularPanel3D。
 
  CircularPanel3D类继承自System.Windows.Controls.Panel,它实现了一种新的布局方式,效果大家在上一张图片中都看到了。这种华丽的效果实际上都是由这个最重要的类中的最重要的方法:
private void Refresh() 完成的。
1 private void Refresh()
2 {
3 // 几个计数器,看名字就功能很明了
4   int count = 0 ;
5 int col = 0 ;
6 int row = 0 ;
7 int zLevel = 0 ;
8
9 // 开始遍历子元素
10   foreach (FrameworkElement childElement in this .Children)
11 {
12 // AngleItem是指单个元素的旋转角度,算法是360除以列数
13 // 这个方法的布局方式是先布满一圈,再下一环的,角度总是可以取模的
14 // 所以这边直接AngleItem和count相乘了
15 // InitialAngle这个属性是用来确定整个圆环的偏转角度的,每次这个依赖属性变化就会重新计算布局(调用这个方法)
16 double angle = ( this .AngleItem * count ++ ) - this .InitialAngle;
17 // 下面两个变量用来确定元素在屏幕上的位置,用到了三角函数,数学不好的请问高中数学老师
18 double x = this .Radius * Math.Cos(Math.PI * angle / 180 );
19 double z = this .Radius * Math.Sin(Math.PI * angle / 180 );
20 // 创建个PlaneProjection对象,并赋值
21 PlaneProjection projection = new PlaneProjection();
22 if (projection != null )
23 {
24 projection.CenterOfRotationX = 0.5 ;
25 projection.CenterOfRotationY = 0.5 ;
26 projection.CenterOfRotationZ = 0.5 ;
27 projection.RotationY = angle + 90 ;
28 projection.GlobalOffsetX = x;
29 // Distance实际上就是模拟的镜头距离
30 projection.GlobalOffsetZ = z - this .Distance;
31 // -330。。。坑爹的硬编码,实际上就是两行元素的间距,OffsetY是纵向的偏移量,用于调整环在屏幕上的位置
32 projection.GlobalOffsetY = row * ( - 330 ) + this .OffsetY;
33 }
34 // 实际上是让double数变成int数,但是又不会丧失区别性,下面要用到
35 int depth = ( int )(z * 100 );
36
37 double pDist = ( this .Distance - 1000 ) / 2000 ;
38 double pZ = ((z + 1000 ) / 2000 ) + 0.5 ;
39
40 // 让太远的和太近的变透明
41 double opacity = (pZ - pDist) + 0.4 ;
42 if (opacity >= 1 )
43 {
44 childElement.Opacity = ( 2 - opacity);
45 }
46 else if (opacity < 0 )
47 {
48 childElement.Opacity = 0 ;
49 }
50 else
51 {
52 childElement.Opacity = opacity;
53 }
54
55 // 嗯这边有原版的英文注释,不解释
56 // Variable zLevel changes value of ZIndex for each item in the ListBox.
57 // This way the reflex of elements at the top will be placed behind the item below it.
58 Canvas.SetZIndex(childElement, depth - ( ++ zLevel * 10 ));
59
60 // 根据Align属性设置对齐方式,不是很重要
61 double alignX = 0 ;
62 double alignY = 0 ;
63 switch ( this .Align)
64 {
65 case AlignmentOptions.Left:
66 alignX = 0 ;
67 alignY = 0 ;
68 break ;
69 case AlignmentOptions.Center:
70 alignX = childElement.DesiredSize.Width / 2 ;
71 alignY = childElement.DesiredSize.Height / 2 ;
72 break ;
73 case AlignmentOptions.Right:
74 alignX = childElement.DesiredSize.Width;
75 alignY = childElement.DesiredSize.Height;
76 break ;
77 }
78 // 将PlaneProjection对象赋给子元素的Projection属性
79 childElement.Projection = projection;
80 // 定位子元素
81 childElement.Arrange( new Rect( this .Width / 2 - alignX , this .Height / 2 - alignY, childElement.DesiredSize.Width, childElement.DesiredSize.Height));
82
83 // 换行,又见坑爹的硬编码14。。这个代表有十四列
84 col ++ ;
85 if (col > 14 )
86 {
87 col = 0 ;
88 row ++ ;
89 }
90 }
91 }
 
 
 

 
 
目录
相关文章
|
C# 数据格式 XML
WPF 资源(StaticResource 静态资源、DynamicResource 动态资源、添加二进制资源、绑定资源树)
原文:WPF 资源(StaticResource 静态资源、DynamicResource 动态资源、添加二进制资源、绑定资源树) 一、WPF对象级(Window对象)资源的定义与查找 实例一: StaticR...
8086 0
|
10月前
|
移动开发 开发框架 网络协议
WPF+ASP.NET SignalR实现动态折线图
WPF+ASP.NET SignalR实现动态折线图
86 0
|
IDE 编译器 C#
WPF实现强大的动态公式计算
数据库可以定义表不同列之间的计算公式,进行自动公式计算,但如何实现行上的动态公式计算呢?行由于可以动态扩展,在某些应用场景下将能很好的解决实际问题。本文就探讨一下如何在WPF中实现一种基于行字段的动态公式计算。
999 0
WPF实现强大的动态公式计算
|
C# C++
3ds Max建模,Blend设计,VS2008控制WPF的3D模型例子
原文:3ds Max建模,Blend设计,VS2008控制WPF的3D模型例子 3ds Max建模,Blend设计,VS2008控制WPF的3D模型例子   所用的软件 3ds Max 9.
1201 0
|
算法 C# 图形学
WPF绘制深度不同颜色的3D模型填充图和线框图
原文:WPF绘制深度不同颜色的3D模型填充图和线框图 在机械测量过程中,测量的数据需要进行软件处理。通常测量一个零件之后,需要重建零件的3D模型,便于观察测量结果是否与所测工件一致。
2871 0
|
C# 图形学 传感器
WPF在3D Cad模型中利用TextureCoordinates实现颜色渐变显示偏差值的变化
原文:WPF在3D Cad模型中利用TextureCoordinates实现颜色渐变显示偏差值的变化 注:最近在做3D机械模型重建方面的软件,需要根据光栅传感器采集的数据绘制3D图形,并显示出色差以及填充和线框图。
1023 0
|
C# 索引
好玩的WPF第四弹:用Viewport2DVisual3D实现3D旋转效果
原文:好玩的WPF第四弹:用Viewport2DVisual3D实现3D旋转效果 版权声明:转载请联系本人,感谢配合!本站地址:http://blog.csdn.net/nomasp https://blog.csdn.net/NoMasp/article/details/46567895 效果呢就是这么个效果,但是大家要发挥想象力,比如做成一个可以旋转的按钮等等。
896 0
|
C# Windows 图形学
优化WPF 3D性能
原文:优化WPF 3D性能 Maximize WPF 3D Performance .NET Framework 4.5   As you use the Windows Presentation Foundation (WPF) to build 3D contr...
1319 0
|
C# 小程序
WPF 3D变换应用
原文:WPF 3D变换应用  WPF可以提供的3D模型使我们可以轻松地创建3D实体,虽然目前来看还很有一些性能上的问题,不过对于一些简单的3D应用应该是可取的,毕竟其开发效率高,而且也容易上手。         下面给大家演示的是使用在WPF 3D上实现视角变换,通过鼠标拖动来变换观察视角,通过滚轮来放缩视距。
704 0
|
C#
WPF特效-实现3D足球效果
原文:WPF特效-实现3D足球效果 WPF 实现 3D足球效果,效果图如下:  每个面加载不同贴图。                                                          ...
863 0