且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

WPF3D绘图的基础

更新时间:2022-08-17 14:26:46

原文:WPF3D绘图的基础

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

1.二维与三维坐标系区别:
WPF3D绘图的基础
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 属性限制照相机的投影范围
WPF3D绘图的基础
另外一个属性FileldOfView相当于摄像机的缩放透镜——当降低FileldOfView值时,会看到更小场景,会压缩近处与远处物体之间投影距离;反之,看到更大场景,会压缩近处与远处物体之间投影距离。
3.灯光
和现实生活中一样,如果没有光我们将什么也看不到。因此我们需要在我们的场景中至少放置一盏灯来照亮我们场景中的模型。
WPF中支持不同类型的光源,如下:
AmbientLight(环境光) 它所提供的环境光会照亮所有的对象,而不考虑对象的位置或方向。
DirectionalLight(平行光) 像远处的光源那样照亮(如太阳光)。将方向光的 Direction 指定为 Vector3D,但是没有为方向光指定位置。
PointLight(点光源) 像近处的光源那样照亮。 PointLight 具有一个位置并从该位置投射光。 场景中的对象是根据对象相对于光源的位置和距离而被照亮的。 PointLightBase 公开 Range 属性,该属性确定一个距离,超过该距离后模型将无法由光源照亮。 PointLight 还公开了多个衰减属性,这些属性确定光源的亮度如何随距离的增加而减小。 您可以为光源的衰减指定恒定、线性或二次内插算法。
SpotLight(聚光灯) 从 PointLight 继承。 Spotlight 的照亮方式与 PointLight 类似,但是它既具有位置又具有方向。 它们在 InnerConeAngle 和 OuterConeAngle 属性所设置的锥形区域(以度为单位指定)中投射光。
下图展示了各种光源的情况:
WPF3D绘图的基础
光源是 Model3D 对象,因此可以转换光源对象并对光源属性(包括位置、颜色、方向和范围)进行动画处理。

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

4.3D模型
WPF3D绘图的基础
本质上,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.平移物体
WPF3D绘图的基础
如图,将物体从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