WPF 3D 中的裁剪平面





5.00/5 (2投票s)
演示 WPF 3D 中的裁剪平面
引言
我最近需要复习一下 WPF,并有了给 Rod Stephens出色的WPF Menger Sponge 添加裁剪平面的想法。顺便,我还添加了一些其他功能,我将通过以下链接进行描述。
下载并构建
下载 MengerSpongeClipping.zip 文件并解压缩。使用 Visual Studio 打开 MengerSpongeClipping
项目。按 F6 生成项目;项目应成功生成,没有错误。按 F5 以调试模式运行 MengerSpongeClipping
项目。
Using the Code
要裁剪 Menger Sponge,只需单击“裁剪”按钮。您可以使用滑块来定向裁剪平面,如下图所示。上图。您可以使用“旋转平面”滑块围绕 x、y 或 z 轴旋转裁剪平面,并可以使用“平移平面”滑块沿 x、y 或 z 轴平移它。对于此版本,裁剪平面假定在所有方向上都是无限的,因此平移仅用于演示目的,不影响实际裁剪。(在未来版本中,我计划让裁剪算法假定一个有限的裁剪平面,从而考虑裁剪平面的平移,因此 Sponge 外面的部分不会被裁剪。)裁剪平面的正侧是绿色不透明的;负侧是蓝色不透明的。
裁剪平面
我实现的裁剪平面很简单:计算从平面到每个矩形中心的距离,并丢弃距离值小于零(即,在不透明蓝色侧的后面)的矩形。DrawClippingPlane()
方法执行以下步骤:
- 旋转裁剪平面
- 平移裁剪平面
- 获取裁剪平面的变换坐标
- 确定形式为 Ax + By + Cz + D = 0 的裁剪平面方程
DistanceFromPlaneToPoint()
方法使用裁剪平面方程来确定到矩形中心的距离。RemoveClippedRectangles()
方法(下方介绍)计算距离并从 RectanglesMade
中删除被裁剪的矩形。DrawClippedSponge()
方法(下方也介绍)重新绘制 Menger Sponge。
坐标轴
我使用了 Stephens 先生的 WPF 圆柱体代码 来绘制 x、y、z 轴。您可以通过按“A”(Axis Toggle Key)键或使用菜单栏中的“视图”来切换它们。菜单栏。为了标记轴,我使用了 Eric Sink 出色的 CreateTextLabel3D()
方法;我添加了另一个参数 Transform3DGroup transform
。有关详细信息,请参阅 TextLabel3D.cs。
光照
在 WPF(以及 DirectX 和 OpenGL)中,定向光是一种沿指定向量投射其效果的光。Vector3D lightVector1
、Vector3D lightVector2
、Color lightColor1
和 Color lightColor2
是 DirectionalLight()
构造函数的输入。由于有时通过指定向量难以可视化灯光指向何处,我使用了 Stephens 先生的 WPF 圆锥体代码 来绘制“手电筒”(在英国称为 torch),以显示定向光指向何处。有两个定向光,分别命名为 Light 1 和 Light 2。为了清晰起见,手电筒默认是禁用(不显示)的。要启用(显示)它们,请按“F”键(Flashlight Toggle Key)或使用菜单栏中的“视图”。菜单栏。手电筒是否启用不影响实际照明;换句话说,它们仅用于使照明向量更易于可视化。
您可以通过设置方向向量的滑块和颜色的组合框来试验这两个灯。如果从颜色组合框中选择“无”,则相应的 DirectionalLight()
将关闭,并且手电筒将以 Stephens 先生提供的线框代码显示。(我花了些时间尝试使用 3D Tools 线框,但无济于事。)在下面的插图中,我启用了手电筒,稍微缩小白了(使用减号键),并通过按“P”键(Clipping Plane Toggle Key)禁用了裁剪平面(为了清晰)。接下来,我设置了方向向量,将 Light 1(在背景中)设置为蓝色,将 Light 2(在前景中)设置为红色。请注意,红光如何将 Menger Sponge 的 X 和 Z 面照亮为红色,而 Y 面由于蓝色和红色的组合而呈现紫色。
在下一张插图中,在我使用箭头键将场景旋转 195 度(注意 theta 从 60° 变为 255°),并将其倾斜从 phi=30 度变为 phi=40 度后,可以看到 Light 1(现在在前景中的蓝光)将 Menger Sponge 的 -X 和 -Z 面照亮为蓝色。
纹理
您可以通过从“纹理”组合框中选择一个图像文件来为 Menger Sponge 添加纹理,如下图所示。为了使用此功能,您首先需要修改 app.config 以指向图像文件,例如:
<setting name="ImageFileLocation" serializeAs="String"> <value>C:\MyProjects\MengerSponge\MengerSpongeClipping\MengerSpongeClipping\Images\</value> </setting>
这段代码来自 Stephens 先生另一篇关于纹理的有用文章。
WPF 进度条
由于绘制的矩形数量由 SpongeDepth
决定,因此我添加了一个 WPF 进度条来显示重新绘制裁剪后的 Menger Sponge 的进度,如下图所示。代码演示了 BackgroundWorker
对象的使用。如果您在快速机器上运行,为了获得完整效果,您可能希望通过按 F5 以调试模式运行程序,因为在调试模式下有一些控制台输出会稍微减慢进程。
当您单击“裁剪”按钮时,BtnClip_Click()
回调会创建 BackgroundWorker
对象,以便在单独的线程上执行裁剪操作。请注意在 RemoveClippedRectangles()
中使用 Dispatcher.Invoke
,这是必需的,因为 DrawClippedSponge()
方法访问由不同线程拥有的 spongeMesh
对象。RemoveClippedRectangles()
方法计算进度。
菜单栏
菜单栏有“文件”、“视图”和“帮助”菜单项。“文件 -> 另存为...”允许您将设置保存到文本文件,“文件 -> 打开”允许您检索它们。文件 -> 重置将把裁剪平面旋转和平移、相机移动、照明设置和纹理重置为其初始值(按 Escape 键也可以)。“视图”允许您切换轴、裁剪平面、海绵和平面法线。您也可以分别使用“A”、“P”、“S”和“N”切换键。由于平面法线很小(单位向量),您需要关闭海绵(以及轴,如果平面法线与轴对齐)才能看到它。
历史
- 版本 1.0.0.0