【WPF】用三角形网格构建三维图形
虽然WPF只能支持部分三维模型,不过从应用功能开发的角度看,也已经够用了(非游戏开发)。WPF 的三维图形,说得简单一点,也就两种而已。
1、把二维对象放到三维空间中,这个应该较为好办,像 Image 控件,Shape 类型等,或者我们常用的一些控件,都可以放进三维空间中,用这种方式构建模型可能更为实用,也好弄(至少不借助专门的建模工具的前提下)。
2、完全利用坐标建模。实际上是用 N 个三角形来组合成三维模型。
虽然你会看到基类型 Visual3D 派生出了好几个类型,但总体上说也就划分为上述两类。Viewport2DVisual3D 类就是专门把二维对象放入三维空间中的,而 ModelVisual3D 和 UIElement3D 差不多,不同的是,UIElement3D 可以捕捉用户输入行为,如鼠标键盘触控等,如果你的三维模型要与用户交互,那么你可以选用这个类。
本文老周重点介绍第二种建模方法,就是用三角形来组建。为啥要用三角形呢?我们以前都学过几何,你想想,要多少个点才能确定一个面?是三个吧。两个点只能确定一条线,一个点就算了,那是无限射线。正是如此,所以三维图形中的所谓面,至少得要三个点才能确定下来,所以,要使用三角形来作为图形基元。
在介绍三角形坐标设置之前,老周先用废话来各大伙补充一点东东。
在WPF中承载三维模型是这样的:首先,你应该声明一个 Viewport3D 对象,它包含我们要建立的模型,前些天,老周写过一篇文章,介绍过三维型中的照相机,就是 Viewport3D 的 Camera 属性,你必须设置一个照相机,这样才能看到三维模型中的东西,它好比我们透过实体相机的取景器来观察客观事物,具体可以点这里查看。
之后呢,Viewport3D会包含一个子元素集合,每个元素必须是 Visual3D 的子类,由于是集合,你可以在其中添加 N 个。
用坐标来构建模型,应当用 ModelVisual3D 类,这个类很好玩,它自身又公开一个集合,可以再添加 ModelVisual3D 对象。也就是说,ModelVisual3D 对象是可以像树形结构一样嵌套,这样做可以方便你建立复杂的三维图形,并且可以有效分组。很多人会觉得,WPF 的三维模型很复杂很难懂,除了三维空间本身的复杂性外,估计可能是因为这种可视化元素之间的可嵌套性,刚开始接触时容易头晕。不过不用害怕,这世界上没有谁天生就会的,不要急,学习的时候,不要建太复杂的模型,这样思路也容易适应,只要你熟悉了就很轻松了,再复杂的东西,也是由各种简单的元素构成的。
ModelVisual3D 类有个Content属性,这个才是真正用来设置模型坐标的,它的类型是Model3D,它是个抽象类,它的派生类有两大块:一是GeometryModel3D,用来定义构成三维图形的坐标点;再者就是Light,表示用于照亮三维模型的灯光,因为三维图形是模拟现实中的事物的,所以会考虑到灯光照射的问题,它的实现类型有比如环境光(AmbientLight),这个像我们房间里的大灯,它可以照亮屋内所有角落;方向光(DirectionalLight),像手电筒的光吧,具有照射方向……
在GeometryModel3D类,也公开了三个属性:
Geometry:设置三维图形的坐标点集合,不仅只有点,还有索引、法向量、纹理映射等。
Material:图形正面的材质,就像金属表面,反射镜面类似的效果。
BackMaterial:有正面就会有背面,这是指图形背面的材质。
下面就是建立模型的重点了,即 Geometry属性,WPF 框架只公开了一个实现类——MeshGeometry3D,就是使用三角形网络来建立物体的表面。其中也有三个属性比要重要。
Positions:这个很重要,组成图形表面的各个坐标点的集合。
TriangleIndices:这个也很重要,它是一组整数集,从0开始,就是指定哪三个点组成一个三角形。
TextureCoordinates:纹理映射。之个有点像你把某妹子的照片贴在一块玻璃上,照片相当于纹理,经的每个点与玻璃的对应关系。比如,通常,我们会把照片的左上角的点对准玻璃左上角的点,右上角的点对准玻璃右上角的点。如果把照片左上角的点对准玻璃右下角的点,照片左上角的点对准玻璃左下角的点,这样贴出来的照片就是倒过来的。
Normals:构成图形的各个坐标点的法向量,默认全是 0,0,1。这个东西还真不知道怎么解释,一般我们可以不指定,用默认值就可以,大概是指面与面之间的关系吧。
咱们来看看演示吧。
<GeometryModel3D>
<GeometryModel3D.Geometry>
<MeshGeometry3D Positions="-2,2,0 3,-2,2 5,3,3 7,1,-2" TriangleIndices="0,1,2,1,3,2" TextureCoordinates="0,0 1,0 1,0 1,1" Normals="0,0,1 0,0,1 0,0,1 0,0,1"/>
</GeometryModel3D.Geometry>
<GeometryModel3D.Material>
<DiffuseMaterial>
<DiffuseMaterial.Brush>
……
</DiffuseMaterial.Brush>
</DiffuseMaterial>
</GeometryModel3D.Material>
</GeometryModel3D>
上面代码中,定义了四个坐标点,注意 TriangleIndices 属性的值,它有六个值,表明这四个点可以构成两个三角形。即它有两个面组成。
0-1-2 表示第一个点,第二个点和第三个点,这三个点构成了一个三角形。就像这样。
然后是 1-3-2,即第二个点,第四个点,第三个点又组成了一个三角型。
大伙要注意一个法则—— 组成三角形的点,如果是按逆时针排序的(就像上面例子),表示的是物体的正面;如果是顺时针的,表示的则是物体的反面。
再比如,咱们再写成这样,这回有五个点。
<MeshGeometry3D Positions="0,3,0 -3,-2,0 -1,-3,1 1,-3,1 3,-2,0" TriangleIndices="0,1,2,0,2,3,0,3,4" TextureCoordinates="0,0 1,1 1,1 1,1 1,1" />
第一个点在顶部,其余四个在下方,构成三个三角形。
好了,由于剧组严重缺乏资金,老周今天只能说到这里了。为了弄到更多资金来写后面的文章,老周要去玩《狂野撞车》来赚现金。
【WPF】用三角形网格构建三维图形的更多相关文章
- WPF三维图形
原文:WPF三维图形 wpf 三维图形基础生成三维图形的基本思想是能得到一个物体的三维立体模型(model).由于我们的屏幕只有二维,因而我们定义了一个用于给物体拍照的照相机(Camera).拍到的照 ...
- CVPR2020:点云分析中三维图形卷积网络中可变形核的学习
CVPR2020:点云分析中三维图形卷积网络中可变形核的学习 Convolution in the Cloud: Learning Deformable Kernels in 3D Graph Con ...
- matlab绘制三维图形
原文地址:种三维曲面图. 程序如下: [x,y]=meshgrid(-8:0.5:8); z=sin(sqrt(x.^2+y.^2))./sqrt(x.^2+y.^2+eps); subplot(2, ...
- Matlab绘图基础——其他三维图形(绘制填充的五角星)
其他三维图形 %绘制魔方阵的三维条形图 subplot(2,2,1); bar3(magic(4)); %以三维杆图形式绘制曲线y=2sin(x) subplot(2,2,2); y=2*sin( ...
- [Matlab绘图][三维图形][三维曲线基本函数+三维曲面+其他三维图形]
1.绘制三维图形的基本函数 最基本的三维绘图函数为plot3: plot3与plot用法十分相似,调用格式: plot(x1,y1,z1,选项1,x2,y2,z2,选项2,...,xn,yn,zn,选 ...
- World Wind Java开发之七——读取本地栅格文件(影像+高程)构建三维场景(转)
http://blog.csdn.net/giser_whu/article/details/41679515 首先,看下本篇博客要达到的效果图: 下面逐步分析如何加载影像及高程文件. 1.World ...
- matlab中画三维图形
这里主要讲述两个方法用matlab画三维图形: 1.mesh函数 先看一个简单的例子: x = ::; y = ::; [X, Y] = meshgrid(x, y); Z = zeros(,); Z ...
- 使用D3.js构建实时图形
首先你需要在计算机上安装Node和npm. 数据的可视化表示是传递复杂信息的最有效手段之一,D3.js提供了创建这些数据可视化的强大工具和灵活性. D3.js是一个JavaScript库,用于使用SV ...
- openGL实现二维图形和三维图形
openGL是一个强大的底层图形库,其命令最初的时候使用C语言实现的.openGL定义了一个图形程序接口,常用于制作处理三维图像,功能强大,调用方便,在图像处理十分受欢迎. 实现图形主要使用的是ope ...
随机推荐
- virtual box ubuntu 主机和虚拟机实现互相复制粘贴
链接:http://jingyan.baidu.com/article/574c521917db806c8d9dc18c.html 常规高级里共享粘贴板已经选中双向,(我的已经可以了复制粘贴了),如果 ...
- IO流输入 输出流 字符字节流
一.流 1.流的概念 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作. ...
- UITableView grouped样式使用探索
UITableView的style有plain和grouped两种样式,两种样式各有不同的风格和功能,plain样式已经封装好了悬停功能,gouped样式则为我们在区头和区尾在实际项目开发中需要我们选 ...
- Jmeter如何将上一个请求的结果作为下一个请求的参数——使用正则表达式提取器
首先在线程组下添加两个HTTP请求, 添加好两个HTTP请求后,在每个HTTP请求下添加一个查看结果数 在第一个HTTP请求下添加正则表达式提取器 在第一个HTTP请求添加好IP地址,路径,端口号,协 ...
- LeetCode 108: Convert Sorted Array to Binary Search Tree DFS求解
Given an array where elements are sorted in ascending order, convert it to a height balanced BST. 解题 ...
- Linux基础(7)
Linux 基础(7) 一.内存的监控(free) free -m 以单位为MB的方式查看内存的使用情况(free命令读取的文件是/proc/meminfo) total:是指计算机安装的内存总量 u ...
- 忘记了root密码,如何进入系统?
Issue 问题 忘记了root密码不能进入系统 如何进入系统? 环境 红帽企业版Linux所有版本 解决方法 可以进入单用户模式或者援救模式来改变root密码,如何进入单用户模式取决引导加载程序. ...
- 《JavaScript面向对象编程指南(第2版)》读书笔记(二)
<JavaScript面向对象编程指南(第2版)>读书笔记(一) <JavaScript面向对象编程指南(第2版)>读书笔记(二) 目录 一.基本类型 1.1 字符串 1.2 ...
- Git下载、更新、提交使用总结
Git使用总结 1.下载代码到本地 1.1指定存储文件路径 1.运行git-bash.exe 2.指定盘符:cd f:work 1.2下载代码 命令:$ git clone <版本库的网址> ...
- 576. Out of Boundary Paths
Problem statement: There is an m by n grid with a ball. Given the start coordinate (i,j) of the ball ...