[WPF VTK]三维图形开发基础(一)
前言:
本人在这方面也是了解皮毛,因此里面一些内容可能存在错误;
自己的代码风格不佳,效率不好,如有看不下去的还请见谅。
0.他山之石
学习过程中借鉴下载了很多资源先公布一些(附下载地址):
三维相关一章
http://pan.baidu.com/share/link?shareid=233384&uk=3859191502
共享的所有资源文件夹
(里面有很多电子书籍,说实在的算是盗版,作为IT民工本人盗版狂人版权意识太差,不做推荐,看不下去的请提示我删除,谢谢,对原作者们说声sorry)
(为什么有这么两个链接呢,因为算是初次在这里使用共享,因此将文件上传到了百度yun,一开始也只想到了一个个文件的共享后来发觉可以共享文件夹,然后!没得说啊)
(里面有一个“WPF 3D实例安装程序”强烈推荐安装,安装后里面有许多WPF3D实例可以学习参考,很实用效果可以安装后用浏览器打开!)
http://pan.baidu.com/share/link?shareid=233388&uk=3859191502
1.天地之初
由于程序中需要用到针对序列图像轮廓点进行三维重建,因此学习了一些三维开发的基本概念。
在说了解的图像开发库中,Direct3D、OpenGL是比较成熟、功能强大的,不过相对来说其也拥有一定开发复杂度,
鉴于实验室师兄有用WPF进行过一个三维展示的实验,而本人当时感觉自己说需要的三维功能也是很基础的三维显示功能,
同时WPF三维制作具有这一能力,是基于D3D的封装(D3D本就是微软技术),在此基础上进行了一些简化,因此相对来说
学习、使用的速度较快,于是选择了WPF(当然后来改用VTK,此乃后话)。
WPF中3D绘图可以使用XAML也可以在CS页面中定义或者使用混合设置的方法。
对于XAML方法,网上的例子大多是这种模式,也就是单一的一个xaml页面生成了说要显示的模型、动画等。但这需要事先就把所有该设置的值都求取出来。
如果用CS方式就跟定义变量一样,先定义个变量,再用算法生成值再赋值给她之类。
WPF3D基本要素有(其他三维开发库要素应该也是一致的):
Geometry-Geometry定义了在屏幕中所要显示的物体及其位置。
Camera-就跟人类视野一样,camera决定了你观察物体的位置以及角度。
Lighting-关上灯神马都一样,光明的影响不用多解释。但Light的类型、位置、颜色等在不同的场景下会有迥异的效果。
Materials-物体外观通常由灯光以及物体本身材质Materials说决定,比如说物体本身是白色的,用红色光照射or物体本身是红色的,用白色光照射之类。
2.管中窥豹
对于上面所述基本要素,其中Camera、Lighting、Materials算是便于理解,因为与现实世界互通,相似较大。所以择其重点介绍一番:
Camera属性有三要:
Position-Gives the camera's coordinates in 3D space.
LookDirection-Gives the direction in which the camera should be pointed relative to its current position.也就是说,基于相机本身所处的position
以及相机说看的位置,指示出其镜头的方向。举例说来:camera的位置是“1,1,1”而LookDirection是“1,2,3”,那么相机所pointed at 的位置就是
“1+1,1 + 2,1+ 3”=“2,3,4”
在这里请注意一点:LookDirection、Pointed At Point也就是看的方向以及看的位置。因此如果你看的位置无法观察到你说要展示的物体,那么即使你朝着正确的方向你也无法在屏幕中显示出物体来,而Pointed At Point=Position+LookDirection。所以如果你要观察放置在“0,0,0”上的物体,而相机在“1,1,1”那么lookDirection该如何设置呢?是一个减法吧!
UpDirection-比如说对于屏幕你希望设置成Z轴在上那么可以是UpDirection=(0,0,1),也就是正对屏幕的平面是ZX或ZY而如果设置成(0,1,0),那么就是Y轴朝上,也就是说YX,YZ这种情况,当然还可有其他复杂一些设置,成角度之类,就自己去理解了.
比如下图是UpDirection分别设置成‘‘1 0 0’’、‘“0 1 0”、“0 0 1”
从下图看出貌似是个对称的所以我猜测对于第一个图是X轴指向屏幕上方、Y轴指向屏幕左边;
对于中间图是Y轴指向屏幕上方,X轴指向屏幕右边,因此显示就如此了。
(注意这里只显示出了2个图,第三个不是没上传而是空白!也就是说作为一个xy平面上物体,在ZX\ZY面上就看不出来了)
注意我这里虽然都是设置成“0 1 0” “1 0 0 ” “0 0 1”之类,但并不代表就不可以有其他值比如“1 1 1” “1 5 1” “15 5 1”
FieldOfView-观察的角度,嗯这该如何解释呢,比如说你设置成90或者30度代表你说关注的范围一个大一个小,那么物体所显示的大小或者多少就体现出来了.
下图左右两边其他参数一样,只有FiledOfView左边是90;右边是60
<Viewport3D.Camera><PerspectiveCamera Position="0 0 4" LookDirection="0 0 -1" UpDirection="0 1 0" FieldOfView="90" /></Viewport3D.Camera>
<Viewport3D.Camera><PerspectiveCamera Position="0 0 4" LookDirection="0 0 -1" UpDirection="0 1 0" FieldOfView="60" /></Viewport3D.Camera>
对于Lighting请看下图并对照日常生活中的光源加以区别
Materials请参考
http://www.silverlightchina.net/html/study/WPF/2012/0301/14172_2.html
http://www.cnblogs.com/Clingingboy/archive/2010/12/23/1914745.html
下面是一个完整代码示例,可以进行参数修改以查看对应效果:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="_3DUI.MainWindow"
Title="MainWindow" Height="500" Width="500">
<Grid>
<Viewport3D x:Name="Rectangle">
<ModelVisual3D>
<ModelVisual3D.Content>
<Model3DGroup>
<GeometryModel3D>
<GeometryModel3D.Geometry>
<!--Positions="0 1 -4, 0 0 -4, 0 1 0, 0 0 0"-->
<!-- Rectangle. -->
<MeshGeometry3D
Positions="0 0 0, 2 0 0, 0 2 0, 2 2 0"
TriangleIndices=" 0 1 2" />
</GeometryModel3D.Geometry>
<GeometryModel3D.Material>
<DiffuseMaterial Brush="Cyan" />
</GeometryModel3D.Material>
<GeometryModel3D.BackMaterial>
<DiffuseMaterial Brush="Red" />
</GeometryModel3D.BackMaterial>
</GeometryModel3D>
<GeometryModel3D>
<GeometryModel3D.Geometry>
<!--Positions="0 1 -4, 0 0 -4, 0 1 0, 0 0 0"-->
<!-- Rectangle. -->
<MeshGeometry3D
Positions="-2 -2 -2, 0 -2 -2, -2 0 -2, 0 0 -2"
TriangleIndices=" 0 1 2" />
</GeometryModel3D.Geometry>
<GeometryModel3D.Material>
<DiffuseMaterial Brush="Cyan" />
</GeometryModel3D.Material>
<GeometryModel3D.BackMaterial>
<DiffuseMaterial Brush="Red" />
</GeometryModel3D.BackMaterial>
</GeometryModel3D>
<!-- Light source. -->
<AmbientLight Color="White" />
</Model3DGroup>
</ModelVisual3D.Content>
</ModelVisual3D>
<!-- Camera. -->
<!--Position="-1 0.5 4"
LookDirection="0 0 -1"-->
<Viewport3D.Camera>
<PerspectiveCamera Position="0 0 4"
LookDirection="0 0 -1"
UpDirection="0 1 0"
FieldOfView="60" />
</Viewport3D.Camera>
</Viewport3D>
</Grid>
</Window>