WPF3D学习,立方体的绘制

原文:WPF3D学习,立方体的绘制

以此为一个好的开始吧!一直都太懒,坚持写文章是个不错的开始!碰巧最近在研究WPF3D这块的知识,也为了练练自己的写作水平,整理这篇文章。新手上路,多多关照!

本文先以一个简单的立方体来系统的阐述WPF中三维场景中的各元素。

练练功底,我就简单说下,说不清楚大家可以移步到http://msdn.microsoft.com/zh-cn/library/ms747437.aspx这里,微软说的很清楚。

先来说一些基础的东西。

三位坐标系

在3-D坐标系中,原点位于呈现区域的中心(即容器中心),x 轴上的正值朝右,但是 y 轴上的正值朝上,z 轴上的正值从原点向外朝向观察者。

照相机

在接下来要介绍的示例中,我们用到的是PerspectiveCamera照相机。

PerspectiveCamera 指定3-D模型到2-D可视图面的投影。此投影包括透视缩短。换言之,PerspectiveCamera
描述各个面均聚集到某个水平点的平截体。对象离摄像机越近就显得越大,离得越远则显得越小。

立方体的创建

就此开始我们的示例。

3D场景

创建一个3D场景。

<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="WpfApplication1.MainWindow"
        Title="MainWindow" Height="350" Width="525">
        <Grid>
          <span style="color:#ff0000;">  <Viewport3D x:Name="Cube">
            </Viewport3D>
</span>        </Grid>
</Window>

照相机

既然是3D场景,那当然得有观察的方向了,也就是照相机了。在3D场景中添加照相机。这里我们使用透视相机PerspectiveCamera 。

        <Grid>
            <Viewport3D>
               <span style="color:#ff0000;"> <Viewport3D.Camera>
                    <PerspectiveCamera Position="0,0,8" x:Name="camera"></PerspectiveCamera>
                </Viewport3D.Camera>
</span>            </Viewport3D>
        </Grid>

PerspectiveCamera 有很多属性,常用的有以下几个:

Position 获取或设置以世界坐标表示的摄像机位置。 (继承自ProjectionCamera。)
FieldOfView 获取或设置一个值,该值表示摄像机的水平视角。
LookDirection 获取或设置定义摄像机在世界坐标中的拍摄方向的 Vector3D。(继承自ProjectionCamera。)
NearPlaneDistance 获取或设置一个值,该值指定到摄像机近端剪裁平面的摄像机的距离。(继承自ProjectionCamera。)
FarPlaneDistance 获取或设置一个值,该值指定到摄像机远端剪裁平面的摄像机的距离。
(继承自 ProjectionCamera。)
UpDirection 获取或设置定义摄像机向上方向的 Vector3D。(继承自ProjectionCamera。)

我们现在从基本的做起,只定义了Position的属性。(0,0,8)意思为照相机距离屏幕为8.

模型

照相机也有了,现在就开始定义立方体模型了。大家都知道立方体有6个面,所以我们要定义6个GeometryModel3D。

   <Viewport3D>
            <Viewport3D.Camera>
                <PerspectiveCamera Position="0,0,8" x:Name="camera"></PerspectiveCamera>
            </Viewport3D.Camera>
            <Viewport3D.Children>
              <ModelVisual3D>
                    <ModelVisual3D.Content>
                        <Model3DGroup >
                            <span style="color:#ff0000;"><GeometryModel3D>
                                <GeometryModel3D.Material>
                                    <DiffuseMaterial Brush="Green"/>
                                </GeometryModel3D.Material>
                                <GeometryModel3D.Geometry>
                                    <MeshGeometry3D Positions="0,0,0 2,0,0 2,2,0 0,2,0"
TriangleIndices="0,1,2 0,2,3">
                                    </MeshGeometry3D>
                                </GeometryModel3D.Geometry>
                            </GeometryModel3D>
</span>                        </Model3DGroup>
                    </ModelVisual3D.Content>
                </ModelVisual3D>
            </Viewport3D.Children>
        </Viewport3D>

Material是你要为模型填充的纹理,我们使用了绿色来填充。

MeshGeometry3D 用于生成3-D形状的三角形基元。这个说明太抽象,就是说你该定义你的模型框架了。

Positions="0,0,0 2,0,0 2,2,0 0,2,0" 定义了四个点。

有了这四个点,就应该开始绘制三角形基元,就是要把点串起来。TriangleIndices="0,1,2 0,2,3",意思是将0、1、2这三个顶点连起来组成一个三角形,将0、2、3这三个顶点连起来组成另一个三角。这里有一个技巧,我姑且这样理解,在建立三角形时,如果是逆时针连接顶点,那么建立的三角形就是面向视野的,如果是顺时针连接,就是背向视野的(向外),大家可以试一下TriangleIndices="0,3,2 0,2,1"。这样就绘制出如下图所示的一个面了。

我们定义的是绿色,为什么是黑色的呢。天黑了,当然都是黑色的了!我们缺少光。

        <Viewport3D>
            <Viewport3D.Camera>
                <PerspectiveCamera Position="0,0,8" x:Name="camera"></PerspectiveCamera>
            </Viewport3D.Camera>
            <Viewport3D.Children>
                <ModelVisual3D>
                    <ModelVisual3D.Content>
                        <Model3DGroup >
                            <GeometryModel3D>
                                <GeometryModel3D.Material>
                                    <DiffuseMaterial Brush="Green"/>
                                </GeometryModel3D.Material>
                                <GeometryModel3D.Geometry>
                                    <MeshGeometry3D Positions="0,0,0 2,0,0 2,2,0 0,2,0"
TriangleIndices="0,1,2 0,2,3">
                                    </MeshGeometry3D>
                                </GeometryModel3D.Geometry>
                            </GeometryModel3D>
                        </Model3DGroup>
                    </ModelVisual3D.Content>
                </ModelVisual3D>
               <span style="color:#ff0000;"> <ModelVisual3D x:Name="light">
                    <ModelVisual3D.Content>
                        <AmbientLight></AmbientLight>
                    </ModelVisual3D.Content>
                </ModelVisual3D>
</span>            </Viewport3D.Children>
        </Viewport3D>

加上红色的那段代码,就有光了,有光了,就变绿了。

接下来给大家几种光,具体的大家可以自己试试。

  • AmbientLight:它所提供的环境光以一致的方式照亮所有的对象,而与对象的位置或方向无关。
  • DirectionalLight:像远处的光源那样照亮。 将方向光的 Direction 指定为
    Vector3D,但是没有为方向光指定位置。
  • PointLight:像近处的光源那样照亮。 PointLight
    具有一个位置并从该位置投射光。 场景中的对象是根据对象相对于光源的位置和距离而被照亮的。 PointLightBase 公开Range 属性,该属性确定一个距离,超过该距离后模型将无法由光源照亮。 PointLight
    还公开了多个衰减属性,这些属性确定光源的亮度如何随距离的增加而减小。 您可以为光源的衰减指定恒定、线性或二次内插算法。
  • SpotLight:从 PointLight 继承。 Spotlight
    的照亮方式与 PointLight 类似,但是它既具有位置又具有方向。 它们在 InnerConeAngle 和 OuterConeAngle 属性所设置的锥形区域(以度为单位指定)中投射光。

好了,至此已经做出来一个面了。那接下来重复上述动作,把其他五个面画全。

    <Grid >
        <Viewport3D Margin="10">
            <Viewport3D.Camera>
                <PerspectiveCamera Position="0,0,8" x:Name="camera"></PerspectiveCamera>
            </Viewport3D.Camera>
            <Viewport3D.Children>
                <ModelVisual3D>
                    <ModelVisual3D.Content>
                        <Model3DGroup >
                            <GeometryModel3D x:Name="F1">
                                <GeometryModel3D.Material>
                                    <DiffuseMaterial Brush="Green"/>
                                </GeometryModel3D.Material>
                                <GeometryModel3D.Geometry>
                                    <MeshGeometry3D Positions="0,0,0 2,0,0 2,2,0 0,2,0"
TriangleIndices="0,2,1 0,3,2">
                                    </MeshGeometry3D>
                                </GeometryModel3D.Geometry>
                            </GeometryModel3D>
                            <GeometryModel3D  x:Name="F2">
                                <GeometryModel3D.Material>
                                    <DiffuseMaterial Brush="Blue"/>
                                </GeometryModel3D.Material>
                                <GeometryModel3D.Geometry>
                                    <MeshGeometry3D Positions="0,0,0 0,0,2 0,2,2 0,2,0"
TriangleIndices="0,1,2 0,2,3">
                                    </MeshGeometry3D>
                                </GeometryModel3D.Geometry>
                            </GeometryModel3D>
                            <GeometryModel3D  x:Name="F3">
                                <GeometryModel3D.Material>
                                    <DiffuseMaterial Brush="Gray"/>
                                </GeometryModel3D.Material>
                                <GeometryModel3D.Geometry>
                                    <MeshGeometry3D Positions="0,0,0 0,0,2 2,0,2 2,0,0"
TriangleIndices="0,2,1 0,3,2">
                                    </MeshGeometry3D>
                                </GeometryModel3D.Geometry>
                            </GeometryModel3D>
                            <GeometryModel3D  x:Name="F4">
                                <GeometryModel3D.Material>
                                    <DiffuseMaterial Brush="Bisque"/>
                                </GeometryModel3D.Material>
                                <GeometryModel3D.Geometry>
                                    <MeshGeometry3D Positions="2,0,0 2,2,0 2,2,2 2,0,2"
TriangleIndices="0,1,2 0,2,3">
                                    </MeshGeometry3D>
                                </GeometryModel3D.Geometry>
                            </GeometryModel3D>
                            <GeometryModel3D  x:Name="F5">
                                <GeometryModel3D.Material>
                                    <DiffuseMaterial Brush="Yellow"/>
                                </GeometryModel3D.Material>
                                <GeometryModel3D.Geometry>
                                    <MeshGeometry3D Positions="0,2,2 2,2,2 2,2,0 0,2,0"
TriangleIndices="0,1,2 0,2,3">
                                    </MeshGeometry3D>
                                </GeometryModel3D.Geometry>
                            </GeometryModel3D>
                            <GeometryModel3D  x:Name="F6">
                                <GeometryModel3D.Material>
                                    <DiffuseMaterial Brush="Red"/>
                                </GeometryModel3D.Material>
                                <GeometryModel3D.Geometry>
                                    <MeshGeometry3D Positions="0,2,2 2,2,2 0,0,2 2,0,2"
TriangleIndices="0,2,3 0,3,1">
                                    </MeshGeometry3D>
                                </GeometryModel3D.Geometry>
                            </GeometryModel3D>
                        </Model3DGroup>
                    </ModelVisual3D.Content>
                </ModelVisual3D>
                <ModelVisual3D x:Name="light">
                    <ModelVisual3D.Content>
                        <AmbientLight></AmbientLight>
                    </ModelVisual3D.Content>
                </ModelVisual3D>
            </Viewport3D.Children>
        </Viewport3D>
    </Grid>

至此,立方体模型已经建立。大家可以用blend,来回转动试试!

上面那个因为每个面的填充色不同,所以分为6个面来构造立方体。

那么如果一个所有面都是绿色的立方体如何构建呢,还要那么麻烦吗。我们理解到Position代表顶点,一个立方体有8个顶点。那么从这8个顶点来构建立方体可以吗?

<Grid >
        <Viewport3D Margin="10">
            <Viewport3D.Camera>
                <PerspectiveCamera Position="0,0,8" x:Name="camera"></PerspectiveCamera>
            </Viewport3D.Camera>
            <Viewport3D.Children>
                <ModelVisual3D>
                    <ModelVisual3D.Content>
                           <span style="color:#ff0000;"> <GeometryModel3D x:Name="F1">
                                <GeometryModel3D.Material>
                                    <DiffuseMaterial Brush="Green"/>
                                </GeometryModel3D.Material>
                                <GeometryModel3D.Geometry>
                                    <MeshGeometry3D Positions="0,0,0 2,0,0 2,2,0 0,2,0 0,2,2 0,0,2 2,0,2 2,2,2"
TriangleIndices="0,2,1 0,3,2 0,4,3 0,5,4 0,1,6 0,6,5 3,4,7 3,7,2 4,5,6 4,6,7 7,6,1 7,1,2">
                                    </MeshGeometry3D>
                                </GeometryModel3D.Geometry>
                            </GeometryModel3D>
</span>                    </ModelVisual3D.Content>
                </ModelVisual3D>
                <ModelVisual3D x:Name="light">
                    <ModelVisual3D.Content>
                        <AmbientLight></AmbientLight>
                    </ModelVisual3D.Content>
                </ModelVisual3D>
            </Viewport3D.Children>
        </Viewport3D>
    </Grid>

blend中查看图如下(经过变换的):

好了,立方体的构造到此结束。

p.s 不容易呀,第一次自己写博客,不好了别喷,费了我俩小时!我也是刚学这个WPF的3D的,后续进行动画添加,3D控制了,我也会坚持记录下来!新手上路,大小神莫笑哈!

时间: 2024-12-23 19:17:57

WPF3D学习,立方体的绘制的相关文章

OpenGL学习笔记3 —— 绘制3D物体、鼠标交互、反向变换

/* reference http://nehe.gamedev.net/article/using_gluunproject/16013/ */ #include <windows.h> // windows系统要加这个.因为下面2个头文件的一些宏是在这个文件中定义的 #include <gl/Gl.h> #include <gl/glut.h> //这两个头文件在OpenGL程序中几乎必加. #include <cstdio> //标准输入输出,用来打印

cesium 学习(八) 基础绘制(点线面)

一.前言 对于一个地图GIS场景,绘制点.线.面属于是基础功能,无论是二维地图还是三维地图场景均是如此,尤其对于三维场景来说比二维应该是更加困难了些. 但是基础的简单绘制不用考虑太多,下面我们开始学习在Cesium的三维场景中如何进行基础绘制的实现. 二.使用原始Cesium的Entity方法绘制 Cesium中封装了几何对象的接口,也就是点.线.面.圆柱体.长方体.圆锥体等等,还有特殊的几何对象:corridor.ellipse.ellipsoid:以及billboard和model.但这次主

canvas学习笔记(1)-绘制时钟

html代码: <!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="UTF-8" /> <title>canvas clock</title> <style type="text/css"> div{ text-align: center; margin-top: 150px; } </styl

[html5] 学习笔记-Canvas 绘制渐变图形与绘制变形图形

在 HTML5 中,使用 Canvas API 绘制图形的知识,可以对绘制图形进行处理,包含使用 Canvas API 绘制渐变图形,使用 Canvas API 的坐标轴变换处理功能绘制变形图形.其中,左上方的点,为坐标轴原点(0,0). 1.绘制渐变图形 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title></title> 5 <script> 6 function draw(id){ 7 va

《机器学习实战》学习笔记:绘制树形图&amp;使用决策树预测隐形眼镜类型

上一节实现了决策树,但只是使用包含树结构信息的嵌套字典来实现,其表示形式较难理解,显然,绘制直观的二叉树图是十分必要的.Python没有提供自带的绘制树工具,需要自己编写函数,结合Matplotlib库创建自己的树形图.这一部分的代码多而复杂,涉及二维坐标运算:书里的代码虽然可用,但函数和各种变量非常多,感觉非常凌乱,同时大量使用递归,因此只能反复研究,反反复复用了一天多时间,才差不多搞懂,因此需要备注一下. 一.绘制属性图 这里使用Matplotlib的注解工具annotations实现决策树

css学习任务一:绘制九宫格

今天开始加强实战,第一个任务是用css绘制九宫格. 在完成任务过程中,发现自己又忘了一些很基础的东西,现整理如下: 1.要将多块div放在同一行,用float:left来实现,在排满一行限制的宽度之后紧接着的div会另起一行重新横着排列: 2.一开始我弄完之后,发现块与块之间是连在一起的,原来忘了加margin约束,下次一定要注意: 3.代码虽然完成了,可是还是太冗余了,可以在写css的时候将含有同种属性的id并在一起: 遗憾: 弄出来的效果是方形,后想改成圆角,查阅多篇资料无奈暂时改不了,希望

R语言学习 - 线图绘制

线图是反映趋势变化的一种方式,其输入数据一般也是一个矩阵. 单线图 假设有这么一个矩阵,第一列为转录起始位点及其上下游5 kb的区域,第二列为H3K27ac修饰在这些区域的丰度,想绘制一张线图展示. profile="Pos;H3K27ac -5000;8.7 -4000;8.4 -3000;8.3 -2000;7.2 -1000;3.6 0;3.6 1000;7.1 2000;8.2 3000;8.4 4000;8.5 5000;8.5" 读入数据 profile_text <

Direct-X学习笔记--图元绘制

DX中有6种图元: 顶点集合,线段集合,线段条带,三角形集合,三角形条带,三角扇形. 在渲染时一般采用三角形来构成多边形,三角形三个顶点一定共面,共面的时候,渲染较快. (该图片来自百度) 我们在绘制的时候,使用该函数绘制图元,第一个参数为图元的类型,即上图中的几种类型: 点列集合    D3DPT_POINTLIST   一组点的集合 线列集合    D3DPT_LINELIST      一组线段的集合 线带集合    D3DPT_LINESTRIP    首尾相连的线段的集合 三角形列  

项目学习之图形绘制

一.层次结构图(HIPO): 1.层次图中的一个矩形框代表一个模块,方框间的连线表示调用关系而不像层次方框图那样表示组成关系. 2.层次方框图很适用于在自顶向下设计软件的过程中使用. 3.H图:层次图.为了能使HIPO图具有可追踪性,在H图里除了最顶层方框外,每个方框都加了编号. 如图:图书管理系统 二.流程图 程序流程图又称程序方框图.常用符号有: 开始或结束 处理(没有悬挂的过程,必然要有去处) 选择分支 预先定义的处理 输入输出 2.三种基本的控制结构 a.顺序结构,先执行A再执行B