【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 ...
随机推荐
- Zepto 添加手势判断拓展方法(思路+原理)
一.前言 这几个月事情比较多,写了一些博客都没有来得及整理发布,今天刚好有一位同事在开发前端页面的时候用到了手势判断.所以翻出了之前写的 demo,顺便整理一下作为记录. 手势判断在各种应用中都十分常 ...
- Java数据类型及运算
(一),Java基本类型及运算 注释:可以用于生成API: 命令如:javadoc -d apidoc windowtitle hhh -doctitle aaa -header bbbb -ver ...
- C#网络程序设计(1)网络编程常识与C#常用特性
网络程序设计能够帮我们了解联网应用的底层通信原理! (1)网络编程常识: 1)什么是网络编程 只有主要实现进程(线程)相互通信和基本的网络应用原理性(协议)功能的程序,才能算是真正的网 ...
- JavaScript巧学巧用
关于 微信公众号:前端呼啦圈(Love-FED) 我的博客:劳卜的博客 知乎专栏:前端呼啦圈 前言 由于工作和生活上的一些变化,最近写文章的频率有点下降了,实在不好意思,不过相信不久就会慢慢恢复过来, ...
- 安装node-saas包报错问题
项目中用到一些sass写的样式,但是每次一编译就报错 按照它上面的提醒,npm rebuild node-sass --force,还是一样有错.不过仔细看看他的错误信息我发现了其中这条: gyp v ...
- 【代码学习】PHP中GD库的使用
PHP--GD库 ================================================ 一.支持: 需要php支持GD库 二.作用: 验证码.水印.缩放等 三.绘画步骤: ...
- 蓝桥杯- 奇妙的数字-java
/* (程序头部注释开始) * 程序的版权和版本声明部分 * Copyright (c) 2016, 广州科技贸易职业学院信息工程系学生 * All rights reserved. * 文件名称: ...
- JDK版本不匹配...
Java compiler level does not match the version of the installed Java project facet. 今天从把交通厅的项目,导进来就报 ...
- ASP.NET Core:部署项目到Ubuntu Server
概述 基于上一篇成功安装Ubuntu Server 16.10的基础上,接下来继续我们ASP.NET Core项目的部署之旅! 只是对于这些年整天和Windows打交道的我,初次使用Linux确实有点 ...
- 分针网—IT教育:调皮的JavaScript
JavaScript是一门有趣的语言,不仅有趣而且调皮,不同的内核的浏览器在解析的时候表现会有些差异,今天主要是抛砖引玉,和大家一起讨论一些在实际开发中比较常见但同时可能并没有过于在意的JavaScr ...