原文:WPF3D绘图的基础

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_37591671/article/details/69487096

1.二维与三维坐标系区别:



WPF中二维图形的坐标系将原点定位在呈现区域(通常是屏幕)的左上角。 在二维系统中,x 轴上的正值朝右,y 轴上的正值朝下。而在三维坐标系中,原点位于呈现区域的中心,x 轴上的正值朝右,但是 y 轴上的正值朝上,z 轴上的正值从原点向外朝向观察者。

2.WPF3D绘图的四要素:

1.视口

Viewport3D充当三维场景中的窗口(即视区)。( Viewport3D .ClipToBounds属性设置为False,当渲染一个频繁更新的3D场景时,可以明显提高性能,其内容会显示到相邻元素)

2.相机

创建三维场景时,实际上是要创建三维对象的二维表示形式。 由于三维场景的外观会因观察者的观察位置不同而异,因此必须指定观察位置。而观察位置就是由相机(Camera 类)来为三维场景指定的。

WPF提供三个摄像机类: PerspectiveCamera(近大远小,是三维场景大多数期望的) 、 OrthographicCamera(3D对象保持相同的尺寸)、MatrixCamera(3D场景变换到2D视图的矩阵)。

放置和配置摄像机(1)通过Position属性指定在3D空间中安放摄像机的位置(2)设置摄像机的方向LookDirection:

假定需要聚焦原点(0,0,0),相机安放于(-2,2,2),则LookDirection=(0,0,0)- (-2,2,2)=(2,-2,-2)

(3)摄像机倾斜角度UpDirection,通常将UpDirection属性设置为(0,1,0),意味着向量垂直向上

NearPlaneDistance 和 FarPlaneDistance 属性限制照相机的投影范围



另外一个属性FileldOfView相当于摄像机的缩放透镜——当降低FileldOfView值时,会看到更小场景,会压缩近处与远处物体之间投影距离;反之,看到更大场景,会压缩近处与远处物体之间投影距离。

3.灯光

和现实生活中一样,如果没有光我们将什么也看不到。因此我们需要在我们的场景中至少放置一盏灯来照亮我们场景中的模型。

WPF中支持不同类型的光源,如下:

AmbientLight(环境光) 它所提供的环境光会照亮所有的对象,而不考虑对象的位置或方向。

DirectionalLight(平行光) 像远处的光源那样照亮(如太阳光)。将方向光的 Direction 指定为 Vector3D,但是没有为方向光指定位置。

PointLight(点光源) 像近处的光源那样照亮。 PointLight 具有一个位置并从该位置投射光。 场景中的对象是根据对象相对于光源的位置和距离而被照亮的。 PointLightBase 公开 Range 属性,该属性确定一个距离,超过该距离后模型将无法由光源照亮。 PointLight 还公开了多个衰减属性,这些属性确定光源的亮度如何随距离的增加而减小。 您可以为光源的衰减指定恒定、线性或二次内插算法。

SpotLight(聚光灯) 从 PointLight 继承。 Spotlight 的照亮方式与 PointLight 类似,但是它既具有位置又具有方向。 它们在 InnerConeAngle 和 OuterConeAngle 属性所设置的锥形区域(以度为单位指定)中投射光。

下图展示了各种光源的情况:



光源是 Model3D 对象,因此可以转换光源对象并对光源属性(包括位置、颜色、方向和范围)进行动画处理。

<ModelVisualD>
<ModelVisualD.Content>
<DirectionalLight Color="White" Direction="-1,-1,-1"/>
</ModelVisualD.Content>
</ModelVisualD>

4.3D模型



本质上,Viewport3D包含Visaul3D对象,为了给Visual3D对象添加内容,需要定义Geometry3D描述对象,并将其包装到GeometryModel3D对象中,上图显示了他们 的关系。

<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>

上面演示了如何配置正方形

纹理映射:

映射ImageBrush画刷

<GeometryModel3D.Material>
<DiffuseMaterial.Brush>
<ImageSouce="Tree.jpg" />
</DiffuseMaterial.Brush>
</GeometryModel3D.Material>

TextureCoorddinates集合告诉WPF如何将纹理映射到3D表面,例如映射到z平面,z的维度为零,所以省略。(0,0)告诉画刷左下角,映射到3D空间(0,0,0,),(1,0)画刷右下角映射(0,1,0),(0,1)画刷左上角映射(0,1,0),(1,1)画刷右上角映射(1,1,0)

3.变换

WPF 3D中变换(Transform3D类型)可以应用在如下属性中:

照相机:Camera类型

3D模型定义:Model3D类型

容纳3D模型的Visual3D:ModelVisual3D类型

以旋转 照相机为例说明:

1.平移物体



如图,将物体从A移动到B

private void LayoutRoot_MouseMove(object sender, MouseEventArgs e)
{
{
Point pos = Mouse.GetPosition(viewport);//得到鼠标点击位置
Point actualPos = new Point(pos.X - viewport.ActualWidth / 2, viewport.ActualHeight / 2 - pos.Y);//点击位置相对于中心点坐标位移
double dx = actualPos.X - mLastPos.X, dy = actualPos.Y - mLastPos.Y;
camera.Position = new Point3D(camera.Position.X - dx, camera.Position.Y - dy, camera.Position.Z);//移动相机,使物体相对位置改变
mLastPos = actualPos;//将上次相对位移保留下来与新的位移比较
}
}

2.旋转可以参考3DToolTrackBall

WPF3D绘图的基础的更多相关文章

  1. R 基础绘图体系-基础篇

    1.高水平绘图函数 生成数据 #模拟100位同学学号及三科成绩 num = seq(12340001,12340100) # 形成学号 x1 = round(runif(100,min = 80,ma ...

  2. HTML5之Canvas绘图(一) ——基础篇

    HTML5火的正热,最近有个想法也是要用到HTML的相关功能,所以也要好好学习一把. 好好看了一下Canvas的功能,感觉HTML5在客户端交互的功能性越来越强了,今天看了一下Canvas绘图,下边是 ...

  3. Java绘图技术基础

    public class Demo1 extends JFrame{ MyPanel mp=null; public static void main(String[] args){ Demo1 de ...

  4. 基础R绘图

    前言: 在前面介绍了R的基础入门语法之后,现也将最近整理好的一些R的基础绘图实例提供给需要的朋友参考.(温馨提示:代码慎用!按照本博文实例进行练习的话最好能做到举一反三.代码多敲方为上策,切不可隔岸观 ...

  5. iOS基础 - Quartz 2D绘图

    一.Quartz 2D Quartz 2D是一个二维图形绘制引擎,支持iOS环境和Mac OS X环境. Quartz 2D以PDF的规范为基础的图形库,用来绘制二维文字和图形,允许相同的绘图指令在任 ...

  6. canvas绘图基础

    <canvas>元素是HTML5中的绘图元素,通过定义一个画布区域,然后使用javascript动态地在这个区域里面绘制图形,对于2D和3D图形都可以绘制,我们将其分成2D上下文和WebG ...

  7. canvas API ,通俗的canvas基础知识(四)

    今天要讲的内容是canvas的转换功能,前面的内容没用看的同学可以出门右转,先看看前面的基础知识,废话不多说,开始进入正题吧! 何为转换功能?熟悉css3的同学都知道,css3里面有transform ...

  8. 理解matplotlib绘图

    matplotlib是基于Python语言的开源项目,旨在为Python提供一个数据绘图包.Matplotlib 可能是 Python 2D-绘图领域使用最广泛的套件.它能让使用者很轻松地将数据图形化 ...

  9. 10分钟轻松学会python turtle绘图

     1. 画布(canvas) 1.1 相关函数: 2. 画笔 2.1 画笔的状态 2.2 画笔的属性 2.3 绘图命令 3. 命令详解 4. 绘图举例 4.1 太阳花 4.2 绘制小蟒蛇 4.3 绘 ...

随机推荐

  1. [Swift] Storyboard outlet and action

    To programmaictlly change the content of app, we need to contect storyboard to a view controller. To ...

  2. item.imageInsets =

    直接上代码: item.imageInsets = UIEdgeInsetsMake(6, 0, -6, 0);//设置图片居中 阅读全文 本文已收录于下面专栏: wanglixin1999 +关注 ...

  3. 数据类型总结——Boolean类型(布尔类型)

    相关文章 简书原文:https://www.jianshu.com/p/e5c75d4be636 数据类型总结——概述:https://www.cnblogs.com/shcrk/p/9266015. ...

  4. Cocos2d中的Menu使用

    学习cocos2d-x中的菜单主要须要了解:菜单(CCMenu)和菜单项(CCMenuItem)以及CCMenuItem的详细子类. a. 以下来学习一下相关的类. 1. CCMenu 菜单,是CCL ...

  5. Linux系统编程_8_进程控制之fork_wait_waitpid函数

    fork函数: #include <unistd.h>        pid_t fork(void); fork用来创建一个子进程: 特点: fork调用后会返回两次,子进程返回0,父进 ...

  6. 卡特兰(Catalan)数列

    卡特兰数又称卡塔兰数,英文名 Catalan number,是组合数学中一个常出现在各种计数问题中出现的数列.以比利时的数学家欧仁·查理·卡塔兰 (1814–1894)的名字来命名,其前几项为 : 1 ...

  7. [Angular] Using directive to create a simple Credit card validator

    We will use 'HostListener' and 'HostBinding' to accomplish the task. The HTML: <label> Credit ...

  8. UE4的JSON读写方式<二>

    声明:所有权利保留. 转载必须说明出处:http://blog.csdn.net/cartzhang/article/details/43794409 Json的Writer博客地址: http:// ...

  9. [Ramda] Sort, SortBy, SortWith in Ramda

    The difference between sort, sortBy, sortWith is that: 1. sort: take function as args. 2. sortBy: ta ...

  10. 【t073】&&【t015】魔法物品

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 有两种类型的物品:普通物品和魔法物品.每种普通物品有一个价值P,但每种魔法物品有两种价值:鉴定前的价值 ...