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>
          <Viewport3D x:Name="Cube">
            </Viewport3D>
       </Grid>
</Window>

 

照相机

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

 

       <Grid>
            <Viewport3D>
               <Viewport3D.Camera>
                    <PerspectiveCamera Position="0,0,8" x:Name="camera"></PerspectiveCamera>
                </Viewport3D.Camera>
           </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 >
                           <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>
            </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>
               <ModelVisual3D x:Name="light">
                    <ModelVisual3D.Content>
                        <AmbientLight></AmbientLight>
                    </ModelVisual3D.Content>
                </ModelVisual3D>
         </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(点击XAML中的ModelVisual3D节点,出现三维坐标),来回转动试试!


上面那个因为每个面的填充色不同,所以分为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>
                           <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>
                   </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-09-18 01:30:52

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

13问13答全面学习Android View绘制_Android

本文通过13问13答学习Android View绘制,供大家参考,具体内容如下 1.View的绘制流程分几步,从哪开始?哪个过程结束以后能看到view? 答:从ViewRoot的performTraversals开始,经过measure,layout,draw 三个流程.draw流程结束以后就可以在屏幕上看到view了.  2.view的测量宽高和实际宽高有区别吗? 答:基本上百分之99的情况下都是可以认为没有区别的.有两种情况,有区别.第一种 就是有的时候会因为某些原因 view会多次测量,那

13问13答全面学习Android View绘制

本文通过13问13答学习Android View绘制,供大家参考,具体内容如下 1.View的绘制流程分几步,从哪开始?哪个过程结束以后能看到view? 答:从ViewRoot的performTraversals开始,经过measure,layout,draw 三个流程.draw流程结束以后就可以在屏幕上看到view了. 2.view的测量宽高和实际宽高有区别吗? 答:基本上百分之99的情况下都是可以认为没有区别的.有两种情况,有区别.第一种 就是有的时候会因为某些原因 view会多次测量,那第

学习产品设计:绘制交互设计流程图

文章描述:绘制交互流程图. 学习产品设计初期肯定会遇到两个问题:第一,如何考虑更全面:第二,如何绘制交互流程图.开始产品设计前先要考虑所有可能性,如何才能以线性流程图的方法组织所需的设计元素.小郑老师的<交互设计表格>中已经介绍了非常实用的表格穷举法,适合初学者使用. 流程图是产品经理和交互设计都必须掌握的技能,一张流程图可以省去需求文档和交互设计文档的很多文字描述,让技术人员一目了然地明白设计意图,便于组织程序的逻辑顺序. 绘制流程图准从简单的原则,流程图是设计师的产出物,体现设计意图,主要

D3D9学习笔记(四) 绘制

1直接使用vertex buffer绘制 使用IDirect3DDevice9::DrawPrimitive绘制 HRESULT DrawPrimitive(   [in]  D3DPRIMITIVETYPE PrimitiveType,--原语类型   [in]  UINT StartVertex,--顶点缓存中第一个顶点的index   [in]  UINT PrimitiveCount --绘制的原语的数量(注意不是顶点的数量)最大值查询D3DCAPS9 );   2. 配合indice绘

AutoCAD绘制复杂图纸的注意事项

相信大家在工作中使用AutoCAD绘制图纸的时候不止是按照书本学习的时候绘制几条线段或是画方画圆那么简单,一个复杂的图纸经常需要制图人员花上几个小时甚至要多于几天的工作量才能完成,相信谁也不是铁打的,难保不会有出错打盹的时候.笔者这里就复杂图纸绘制时应注意的几个问题简单说明一下. 一.养成经常存盘的好习惯 相信不少"过来人"都有过因为断电或者其他原因而导致的把辛辛苦苦做的图纸丢失的悲惨教训.可能不少新学CAD制图的朋友在学习的时候也常常因为是练习用的图纸而没有SAVE的习惯吧?建议这样

IOS开发:Unity3D根据动态的两个轨迹点绘制面详解

 开发:Unity3D根据动态的两个轨迹点绘制面详解-"> 暂时我们先忽略Z轴(这样在平面中看得更清楚),假设Z轴坐标都为0.假设游戏中有两个轨迹点在动态的增加与改变,最后将这两个点改变的轨迹拼接起来就是它们生成的面.如上图所示,第一个点的轨迹是" 3,4,5,6,7" 第二个点的轨迹是"2,1,10,9,8" .这两个点的长度是可变的,前提是他们两个的数量必需完全一样.接着,如下图所示,我们将这些点两两相连起来,目前一共形成了8个三角形面(可根据两

用Photoshop绘制复古风的邮票和邮戳

  目前很流行的复古风绘画,以及各种装饰画和无框画中经常会看到邮票图案,不得不说它的出现为画面增添很多复古味道,已经成为复古画中必不可少的元素.来一起学习一下怎么绘制邮票吧,它会让你的画面变得丰富有趣! 方法/步骤 1.打开Photoshop,新建文件,这里命名为邮票 2.再打开你所想要做成邮票的图片,按住(Ctrl+A)全选图片复制(Ctrl+C),将其粘贴(Ctrl+V)到(邮票)文件中,如图: 3.选中图片图层,点击(Ctrl+T)自由调整图片到适当大小,点击Enter确认. 4.选中图片

在Word中绘制表格的简单方法

  在Word中,如果要绘制简单的表格,其实方法还是挺多的.今天,我们就从工具栏和菜单栏出发,来学习一下如何绘制出简单的表格. Word 方法一:利用菜单栏中工具绘制表格 单击Word2003菜单栏上的"表格"按钮,在弹出的下拉菜单中选择"表格"-->插入-->表格,然后在弹出的"插入表格"对话框中设置好表格的"列数"与"行数"即可. 方法二:使用"常用"工具栏插入表格 点击

如何在Word绘制图形中插入文字

  在制作各种流程图时,通常需要在图形中输入对应的文字.下面就来学习如何在绘制图形中插入文字.以绘制如图1所示的公司招聘流程图为例进行介绍. (1)绘制流程图 第1步,单击"插入"选项卡,单击"形状"按钮,在流程图区域选择圆角矩形形状,如图2所示. 第2步,绘制一个圆角矩形,然后选中该图形,另外复制5个该图形,并调整各个图形的位置关系,效果如图3所示. 第3步,单击"插入"选项卡,单击"形状"按钮,在线条区域选择箭头.绘制箭头