WFP3D绘图

  • WFP3D绘图已关闭评论
  • 179 次浏览
  • A+
所属分类:.NET技术
摘要

相机标签对象属性  后台关于3D地球的代码  代码实例效果图:这个3D动画地球是可以旋转的

WPF本身不支持直接的3D绘图,但是它提供了一些用于实现3D效果的高级技术。
如果你想要在WPF中进行3D绘图,你可以使用两种主要的方法:
  1. WPF 3D:这是一种在WPF应用程序中创建3D图形的方式。WPF 3D提供了一些基本的3D形状(如立方体、球体和锥体)以及一些用于控制3D场景和对象的工具(如相机、光源和材质)。
 
在WPF中,3D对象模型的材质可以使用以下三种
  1. DiffuseMaterial:漫反射,反射场景光效果
  2. EmissiveMaterial:自发光,类似于电灯 
  3. SpecularMaterial:全反射,可以映射场景 贴图
在WPF中,一个3D模型的材质,就是决定模型看起来是什么样子的一种很重要的元素,如粗糙度、颜色、发光度等
 
WPF 3D对象模型光源如下
AmbientLight:环境光-  提供环境光,会照亮所有的对象,而不考虑对象的位置或方向。
DirectionalLight:平行光  -  它像远处的光源那样照亮(如太阳光),只具有一个Direction属性,没有位置信息,因此不直接投射到任何特定的对象上,而是照亮场景中的所有对象。
PointLight:点光源 -  像近处的光源那样照亮,具有一个位置并从该位置投射光,场景中的对象是根据对象相对于光源的位置和距离而被照亮的。
SpotLight:聚光灯  -  从PointLight继承,它的照亮方式与PointLight类似,但是它既具有位置又具有方向。
相关属性  
 Color:灯光颜色   
Direction:光线方向(平行光、聚光灯)   
Position:光源坐标(点光源、聚光灯)   
Range:灯光范围(点光源)  
 InnerConeAngle:内光柱照射角度(聚光灯)   
OuterConeAngle:外光柱照射角度(聚光灯)
 
属性
说明
备注
MeshGemetry3D
网格标签
 
Positions
呈现3D图形的标签  Positions="0,0,0(x,y,z)     3,0,0      3,2,0      0,2,0" 一个面的4个点
TraiangleIndices
3 角形创建
TriangleIndices ="0,3,2(第一组) 0,1,2(第二组)" 设置Positions的3个点组成一个三角行
OrthographicCamera  
正交相机(远近比例都一样-很少用)
 
PerspectiveCamera    
透视相机(近比例长远比例小,符合我们正常观察事物的视觉-常用)
 
TextureCoordinates
设置平面对象与3D对象的映射关系-用来解决平面设置背景图显示问题-如果不设置这个属性平面设置的背景图不显示
TextureCoordinates="1,1 1,0 0,0 0,1"

相机标签对象属性

属性 说明 备注
Position 相机的空间坐标(X,Y,Z) Position="100,100,100" 设置视角x,y,z
LookDirection 观察方向,向量,相机观察口朝向 LookDirection="-2,-2,-2" 设置相机的观看视角-相机观察的方向
FieldOfView (透视相机属性) / 视野范围,一个值 FieldOfView="90" 设置相机与观看物体的距离,离得远观看物体区域范围大,离得近观看物体区域范围小
Width (正交相机属性)(焦距),视野范围 Width="50"
UpDirection 相机上方方向,控制相机观察口旋转 UpDirection="0,1,0" (x, y,z)设置相机视口的旋转角度,斜着拍还是正着拍
FarPlaneDistance 远景距离,大于这个距离的场景不渲染 FarPlaneDistance="1000" 设置相机远处景色的渲染范围,如果值设置的比较小,远处景色是模糊的
NearPlaneDistance 近景距离,小于这个距离的场景不渲染 NearPlaneDistance="1" 设置相机近处的晶圆渲染范围,如果值越大,近处景色是模糊的
<!--设置三维地球实例旋转动画-->  <Window.Triggers>     <EventTrigger RoutedEvent="Window.Loaded">         <BeginStoryboard>             <!--RepeatBehavior="Forever" 设置旋转动画一直旋转-->             <Storyboard RepeatBehavior="Forever">                 <!--Duration="0:0:7" 设置播放时长-->                 <!--Storyboard.TargetName="aar" 设置要旋转的控件-->                 <!--Storyboard.TargetProperty="Angle" 设置旋转方式-->                 <!--From="0" 设置动画起始值-->                 <!--To="360" 设置旋转角度-->                 <DoubleAnimation Duration="0:0:7"                              Storyboard.TargetName="aar"                              Storyboard.TargetProperty="Angle"                              From="0"                              To="360"/>             </Storyboard>         </BeginStoryboard>     </EventTrigger> </Window.Triggers> <Grid>     <!--画3D图标签-->     <!--点动成线-线动成面-面动成体-->     <Viewport3D>         <!--第一步在3D世界通过相机来观察这个世界,把这个世界呈现在平面图上。-->         <!--相机标签-设置相机的相关参数-->         <Viewport3D.Camera>             <!-- PerspectiveCamera标签-透视相机(近比例长远比例小,符合我们正常观察事物的视觉-常用)-->             <!--Position="100,100,100" 设置视角x,y,z-->             <!--LookDirection="-2,-2,-2" 设置相机的观看视角-相机观察的方向-->             <!--FieldOfView="90" 调整相机焦距 设置相机与观看物体的距离,离得远观看物体区域范围大,离得近观看物体区域范围小 -->             <!--UpDirection="0,1,0" (x, y,z)设置相机视口的旋转角度,斜着拍还是正着拍 -->             <!--FarPlaneDistance="1000" 设置相机远处景色的渲染范围,如果值设置的比较小,远处景色是模糊的-->             <!--NearPlaneDistance="1" 设置相机近处的晶圆渲染范围,如果值越大,近处景色是模糊的-->             <PerspectiveCamera Position="100,100,100"                    LookDirection="-2,-2,-2"                    FieldOfView="90"                    UpDirection="0,1,0"                    FarPlaneDistance="1000"                    NearPlaneDistance="1">             </PerspectiveCamera>             <!--正交相机(远近比例都一样-很少用)-->             <!--Width="50" 相当与透视相机的视野范围属性-->             <!--<OrthographicCamera Position="100,100,100"                     LookDirection="-2,-2,-2"                     Width="50"                     UpDirection="0,1,0"                     FarPlaneDistance="1000"                      NearPlaneDistance="1"/>-->         </Viewport3D.Camera>         <!--第二步在3D世界设置光源进来,没有光源全是黑的呀-->         <!--光源标签-设置光源的相关属性-->         <ModelVisual3D>             <!--光源内容标签-->             <ModelVisual3D.Content>                 <!--多个光源可以组合使用-会出现不同的效果-->                 <Model3DGroup>                     <!--环境光标签    -->                     <!--Color="White"-设置环境光颜色 -->                     <!--<AmbientLight Color="White"/>-->                                             <!--平行光-设置某一个方向上照射的光-平行光不发散 -->                     <!--Direction="-1,-1,-1" (x,y,z)三个方向照射的光 设置平行光的照射方向-->                     <!--<DirectionalLight Color="White" Direction="-1,-1,-1"/>-->                                             <!--点光源-点光源是向四面八方发散的光源 -->                     <!--Position="100,100,100" (x,y,z) 设置光源点-->                     <!--Range="200" 设置光源的照射范围-->                     <!--<PointLight Color="White" Position="100,100,100" Range="200"/>-->                                             <!--射灯光源(聚光灯,手电筒)-某一个方向去发射光源-相当于手电筒有一个中心的光柱(比较亮的)以及两遍发散的光源(相对较暗) -->                     <!--InnerConeAngle="100" 设置中心范围光柱的角度-->                     <!--OuterConeAngle="40" 设置两遍光源的范围角度-->                     <!--Position="50,50,50" 设置光源的中心位置-->                     <!--Direction="-1,-1,-1" (x,y,z)三个方向照射的光 设置光源的照射方向-->                     <SpotLight Color="Orange" InnerConeAngle="100"                OuterConeAngle="40"                Position="50,50,50"                Direction="-1,-1,-1"/>                 </Model3DGroup>             </ModelVisual3D.Content>         </ModelVisual3D>         <!--3D图形的第一个面 可以把所有的面放在一起写-->         <!--3DUIElement标签-固定写法-->         <ModelUIElement3D>             <ModelUIElement3D.Model>                 <!--GeometryModel3D网格标签-->                 <GeometryModel3D>                     <!--第三步物体需要呈现出来需要材质-->                     <!--3D的材质 标签-->                     <GeometryModel3D.Material>                         <MaterialGroup>                             <!--漫反射的一种材质 材质是与网格属性标签组合在一起使用的-->                             <!--DiffuseMaterial 慢反射材质标签-->                             <!--Brush 设置材质颜色或图片-->                             <!--<DiffuseMaterial Brush="Orange"/>-->                             <!--3D面设置背景图-需要在网格标签中设置TextureCoordinates="0,1 0,0 1,0 1,1"属性,背景图显示方向,才能显示出背景图 -->                             <DiffuseMaterial>                                 <DiffuseMaterial.Brush>                                     <ImageBrush ImageSource="Arrow.png"/>                                 </DiffuseMaterial.Brush>                             </DiffuseMaterial>                             <!--自发光-->                             <!--<EmissiveMaterial Brush="Red"/>-->                             <!--<SpecularMaterial Brush="Blue"/>-->                         </MaterialGroup>                     </GeometryModel3D.Material>                     <!--网格标签-->                     <GeometryModel3D.Geometry>                         <!-- 呈现3D图形的标签  Positions="0,0,0(x,y,z)     3,0,0      3,2,0      0,2,0" 一个面的4个点-->                         <!--TriangleIndices ="0,2,3(第一组-这里的坐标点需要逆时针顺序) 0,1,2(第二组)" 设置Positions的3个点组成一个三角行 -->                         <!--这里如果呈现的是三角行而不是四边行的画,是因为TriangleIndices="0,2,3 0,1,2"的画点顺序需要逆时针顺序-->                         <!--TextureCoordinates 设置平面对象与3D对象的映射关系-用来解决平面设置背景图显示问题-如果不设置这个属性平面设置的背景图不显示-->                         <MeshGeometry3D Positions="0,0,0     3,0,0      3,2,0      0,2,0"                                  TriangleIndices="0,2,3 0,1,2"                                         TextureCoordinates="1,1 1,0 0,0 0,1"/>  <!--箭头向下-->                         <!--TextureCoordinates="1,1 0,1 0,0 1,0"/> 箭头向左-->                         <!--TextureCoordinates="0,1 1,1 1,0 0,0"/> 箭头向右-->                         <!--TextureCoordinates="0,1 0,0 1,0 1,1"/>--><!--  箭头向上-->                     </GeometryModel3D.Geometry>                 </GeometryModel3D>             </ModelUIElement3D.Model>         </ModelUIElement3D>         <!--3D图形的第二个面 可以把所有的面放在一起写 这里没有放在一起写是因为可以给每个面设置不同的颜色-->         <!--3DUIElement标签-固定写法-->         <ModelUIElement3D>             <ModelUIElement3D.Model>                 <!--GeometryModel3D网格标签-->                 <GeometryModel3D>                     <!--第三步物体需要呈现出来需要材质-->                     <!--3D的材质 标签-->                     <GeometryModel3D.Material>                         <MaterialGroup>                             <!--漫反射的一种材质 材质是与网格属性标签组合在一起使用的-->                             <!--DiffuseMaterial 慢反射材质标签-->                             <!--Brush 设置材质颜色或图片-->                             <DiffuseMaterial Brush="Red"/>                             <!--<DiffuseMaterial>                      <DiffuseMaterial.Brush>                          <ImageBrush ImageSource="Arrow.png"/>                      </DiffuseMaterial.Brush>                  </DiffuseMaterial>-->                             <!--自发光 标签-用于设置在没有光源的情况下可以看见自发光颜色-在有光源的情况下自发光颜色会影响到材质颜色的显示 -->                             <!--<EmissiveMaterial Brush="Green"/>-->                             <!--全反射标签 目前只是了解一下-->                             <!--<SpecularMaterial Brush="Blue"/>-->                         </MaterialGroup>                     </GeometryModel3D.Material>                     <!--网格标签-->                     <GeometryModel3D.Geometry>                         <!-- 呈现3D图形的标签  Positions="0,0,0(x,y,z)     3,0,0      3,2,0      0,2,0" 一个面的4个点-->                         <!--TriangleIndices ="0,2,3(第一组-这里的坐标点需要逆时针顺序) 0,1,2(第二组)" 设置Positions的3个点组成一个三角行 -->                         <!--这里如果呈现的是三角行而不是四边行的画,是因为TriangleIndices="0,2,3 0,1,2"的画点顺序需要逆时针顺序-->                         <MeshGeometry3D Positions="3,2,1     3,2,0      3,0,0      3,0,1"                       TriangleIndices="0,3,1    1,3,2"/>                     </GeometryModel3D.Geometry>                 </GeometryModel3D>             </ModelUIElement3D.Model>         </ModelUIElement3D>         <!--三维地球实例-->         <!--3DUIElement标签-固定写法-->         <ModelUIElement3D>             <!--3D图像旋转标签-->             <ModelUIElement3D.Transform>                 <!--旋转标签分组-->                 <Transform3DGroup>                     <!--设置旋转中心-->                     <RotateTransform3D CenterX="0" CenterY="0" CenterZ="0">                         <!--设置旋转角度-->                         <RotateTransform3D.Rotation>                             <!--设置沿着x轴旋转 -90度-->                             <AxisAngleRotation3D Axis="1,0,0" Angle="-90"/>                         </RotateTransform3D.Rotation>                     </RotateTransform3D>                     <RotateTransform3D CenterX="0" CenterY="0" CenterZ="0">                         <RotateTransform3D.Rotation>                             <!--沿着Y轴旋转-通过后台可设置地球旋转-->                             <AxisAngleRotation3D Axis="0,1,0" x:Name="aar"/>                         </RotateTransform3D.Rotation>                     </RotateTransform3D>                 </Transform3DGroup>             </ModelUIElement3D.Transform>             <!--3D标签-->             <ModelUIElement3D.Model>                 <!--GeometryModel3D网格标签-->                 <GeometryModel3D x:Name="gm">                     <!--3D的材质 标签-->                     <GeometryModel3D.Material>                         <!--设置3D材质使用图片-->                         <DiffuseMaterial>                             <DiffuseMaterial.Brush>                                 <ImageBrush ImageSource="Earth.jpg"/>                             </DiffuseMaterial.Brush>                         </DiffuseMaterial>                     </GeometryModel3D.Material>                 </GeometryModel3D>             </ModelUIElement3D.Model>         </ModelUIElement3D>     </Viewport3D> </Grid> 

  后台关于3D地球的代码

public MainWindow() {     InitializeComponent();     // 绑定加载事件     this.Loaded += MainWindow_Loaded; } /// <summary> /// 窗体加载 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void MainWindow_Loaded(object sender, RoutedEventArgs e) {     this.gm.Geometry = this.SetEarth(180, 180, 50); } /// <summary> /// 生成三维地球算法 /// 圆弧的计算公式 /// </summary> /// <param name="numx">纬度方向切多少份</param> /// <param name="numz">精度方向切多少份</param> /// <param name="r">地球半径</param> /// <returns></returns> private MeshGeometry3D SetEarth(int numx, int numz, double r = 3) {     MeshGeometry3D mesh = new MeshGeometry3D();     double dTh = 2 * Math.PI / numx;     double dPhi = Math.PI / numz;     double X(double th, double phi) => r * Math.Sin(phi) * Math.Cos(th);     double Y(double th, double phi) => r * Math.Sin(phi) * Math.Sin(th);     double Z(double phi) => r * Math.Cos(phi);     // Make the points.     for (int i = 0; i <= numx; i++)  // 纬度方向循环次数         for (int j = 0; j <= numz; j++) // 精度方向循环次数         {   // 这里使用三角函数进行计算的             var th = i * dTh;             var phi = j * dPhi;             // 坐标点-用于画三角形的坐标点             mesh.Positions.Add(new Point3D(X(th, phi), Y(th, phi), Z(phi)));             // 用于建立与图片的映射关系             mesh.TextureCoordinates.Add(new Point(th, phi));         }     // 生成三角形-每三个坐标点组织一个面出来     for (int i = 0; i < numx; i++)         for (int j = 0; j < numz; j++)         {             int i1 = i * (numz + 1) + j;             int i2 = i1 + 1;             int i3 = i2 + (numz + 1);             int i4 = i3 - 1;             mesh.TriangleIndices.Add(i1);             mesh.TriangleIndices.Add(i2);             mesh.TriangleIndices.Add(i3);             mesh.TriangleIndices.Add(i1);             mesh.TriangleIndices.Add(i3);             mesh.TriangleIndices.Add(i4);         }     return mesh; } 

  代码实例效果图:

WFP3D绘图

这个3D动画地球是可以旋转的

WFP3D绘图

 3D图片用于辅助寻找3d坐标点顺序

WFP3D绘图

 

WFP3D绘图

3D面设置背景图显示方向 
通过TextureCoordinates属性设置箭头的显示方向
TextureCoordinates="1,1 1,0 0,0 0,1"/>  <!--箭头向下-->
<!--TextureCoordinates="1,1 0,1 0,0 1,0"/> 箭头向左-->
<!--TextureCoordinates="0,1 1,1 1,0 0,0"/> 箭头向右-->
<!--TextureCoordinates="0,1 0,0 1,0 1,1"/>--><!--  箭头向上-->

 

WFP3D绘图

 本文章大半部分素材来自于朝夕教育,技术整理的不好。。。