• WPF 3D MeshGeometry3D类的Positions和TriangleIndices属性研究


    1 MeshGeometry3D 类

    MeshGeometry3D 类,用于生成三维形状的三角形基元;
    类的参考在此;
    https://learn.microsoft.com/zh-cn/dotnet/api/system.windows.media.media3d.meshgeometry3d?view=windowsdesktop-7.0

    写在xaml语法里面是 ,如果写到C#语言里面就要new一个此类的对象;

    Positions属性就是来表示组成3D图形的所有三角形的顶点的;

    TriangleIndices通过将Positions的顶点集合按一定顺序组合起来,组成所需要的三角形;

    就是如果画一个三角形,需要3个顶点;如果画一个面,正方形面,并不是4个顶点;因为基元是三角形,只能由三角形构成其他形状;画一个正方形面,需要六个顶点,指定2个三角形来构成一个正方形面;

    先看基本的三角形;按照这个示意的图来画一个基本三角形;顶点的顺序如下图的0、1、2;

    三角形的三个顶点是:(0,0,0),(1,0,0),(0,1,0);把摄像机放到呈现区域的中心,屏幕外面10个值的地方,往屏幕里边看,如下图;

        这时只有Positions属性,TriangleIndices将按默认;

        如果增加TriangleIndices="0,1,2",加和不加都是一样;如果调整TriangleIndices点的顺序,三角形将不可见;

    此时点的顺序是如下图标记;

     如果画一个正方形面,四个顶点是0,0,0  1,0,0   1,1,0    0,1,0;此时需要6个顶点,画2个三角形,来组成正方形面;但是2个三角形可以共享一条边,有2个顶点是重合的;

    通过给出4个顶点的坐标,然后用TriangleIndices来指定2个三角形的顶点顺序,

         

    TriangleIndices,0,1,2 指定一个三角形,2,3,0 指定另一个三角形,这样来绘出此正方形面;

    1. <Page
    2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    4. <Grid>
    5. <Viewport3D>
    6. <Viewport3D.Camera>
    7. <PerspectiveCamera Position="0,0,10" LookDirection="0,0,-2" UpDirection="0,1,0"/>
    8. Viewport3D.Camera>
    9. <Viewport3D.Children>
    10. <ModelVisual3D x:Name="Light">
    11. <ModelVisual3D.Content>
    12. <AmbientLight/>
    13. ModelVisual3D.Content>
    14. ModelVisual3D>
    15. <ModelVisual3D>
    16. <ModelVisual3D.Content>
    17. <GeometryModel3D>
    18. <GeometryModel3D.Geometry>
    19. <MeshGeometry3D Positions="0,0,0,1,0,0,1,1,0,0,1,0" TriangleIndices="0,1,2 2,3,0"/>
    20. GeometryModel3D.Geometry>
    21. <GeometryModel3D.Material>
    22. <DiffuseMaterial Brush="Yellow" />
    23. GeometryModel3D.Material>
    24. GeometryModel3D>
    25. ModelVisual3D.Content>
    26. ModelVisual3D>
    27. Viewport3D.Children>
    28. Viewport3D>
    29. Grid>
    30. Page>

    2 从C#代码使用MeshGeometry3D类

    前面了解了 MeshGeometry3D 类是生成三维形状的基元;前面的代码是在xaml里;
    下面看一下从C#代码里生成三维场景和图形,以及使用MeshGeometry3D类;

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5. using System.Threading.Tasks;
    6. using System.Windows;
    7. using System.Windows.Controls;
    8. using System.Windows.Data;
    9. using System.Windows.Documents;
    10. using System.Windows.Input;
    11. using System.Windows.Media;
    12. using System.Windows.Media.Media3D;
    13. using System.Windows.Media.Imaging;
    14. using System.Windows.Navigation;
    15. using System.Windows.Shapes;
    16. namespace jiyuan
    17. {
    18. ///
    19. /// MainWindow.xaml 的交互逻辑
    20. ///
    21. public partial class MainWindow : Window
    22. {
    23. public MainWindow()
    24. {
    25. InitializeComponent();
    26. }
    27. private void Window_Loaded(object sender, RoutedEventArgs e)
    28. {
    29. // Declare scene objects.
    30. Viewport3D myViewport3D = new Viewport3D();
    31. Model3DGroup myModel3DGroup = new Model3DGroup();
    32. GeometryModel3D myGeometryModel = new GeometryModel3D();
    33. ModelVisual3D myModelVisual3D = new ModelVisual3D();
    34. PerspectiveCamera myPCamera = new PerspectiveCamera();
    35. myPCamera.Position = new Point3D(0, 0, 2);
    36. myPCamera.LookDirection = new Vector3D(0, 0, -1);
    37. myPCamera.FieldOfView = 60;
    38. myViewport3D.Camera = myPCamera;
    39. DirectionalLight myDirectionalLight = new DirectionalLight();
    40. myDirectionalLight.Color = Colors.White;
    41. myDirectionalLight.Direction = new Vector3D(-0.61, -0.5, -0.61);
    42. myModel3DGroup.Children.Add(myDirectionalLight);
    43. MeshGeometry3D myMeshGeometry3D = new MeshGeometry3D();
    44. Vector3DCollection myNormalCollection = new Vector3DCollection();
    45. myNormalCollection.Add(new Vector3D(0, 0, 1));
    46. myNormalCollection.Add(new Vector3D(0, 0, 1));
    47. myNormalCollection.Add(new Vector3D(0, 0, 1));
    48. myNormalCollection.Add(new Vector3D(0, 0, 1));
    49. myNormalCollection.Add(new Vector3D(0, 0, 1));
    50. myNormalCollection.Add(new Vector3D(0, 0, 1));
    51. myMeshGeometry3D.Normals = myNormalCollection;
    52. Point3DCollection myPositionCollection = new Point3DCollection();
    53. myPositionCollection.Add(new Point3D(-0.5, -0.5, 0.5));
    54. myPositionCollection.Add(new Point3D(0.5, -0.5, 0.5));
    55. myPositionCollection.Add(new Point3D(0.5, 0.5, 0.5));
    56. myPositionCollection.Add(new Point3D(0.5, 0.5, 0.5));
    57. myPositionCollection.Add(new Point3D(-0.5, 0.5, 0.5));
    58. myPositionCollection.Add(new Point3D(-0.5, -0.5, 0.5));
    59. myMeshGeometry3D.Positions = myPositionCollection;
    60. PointCollection myTextureCoordinatesCollection = new PointCollection();
    61. myTextureCoordinatesCollection.Add(new Point(0, 0));
    62. myTextureCoordinatesCollection.Add(new Point(1, 0));
    63. myTextureCoordinatesCollection.Add(new Point(1, 1));
    64. myTextureCoordinatesCollection.Add(new Point(1, 1));
    65. myTextureCoordinatesCollection.Add(new Point(0, 1));
    66. myTextureCoordinatesCollection.Add(new Point(0, 0));
    67. myMeshGeometry3D.TextureCoordinates = myTextureCoordinatesCollection;
    68. Int32Collection myTriangleIndicesCollection = new Int32Collection();
    69. myTriangleIndicesCollection.Add(0);
    70. myTriangleIndicesCollection.Add(1);
    71. myTriangleIndicesCollection.Add(2);
    72. myTriangleIndicesCollection.Add(3);
    73. myTriangleIndicesCollection.Add(4);
    74. myTriangleIndicesCollection.Add(5);
    75. myMeshGeometry3D.TriangleIndices = myTriangleIndicesCollection;
    76. myGeometryModel.Geometry = myMeshGeometry3D;
    77. LinearGradientBrush myHorizontalGradient = new LinearGradientBrush();
    78. myHorizontalGradient.StartPoint = new Point(0, 0.5);
    79. myHorizontalGradient.EndPoint = new Point(1, 0.5);
    80. myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.Yellow, 0.0));
    81. myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.Red, 0.25));
    82. myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.Blue, 0.75));
    83. myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.LimeGreen, 1.0));
    84. DiffuseMaterial myMaterial = new DiffuseMaterial(myHorizontalGradient);
    85. myGeometryModel.Material = myMaterial;
    86. RotateTransform3D myRotateTransform3D = new RotateTransform3D();
    87. AxisAngleRotation3D myAxisAngleRotation3d = new AxisAngleRotation3D();
    88. myAxisAngleRotation3d.Axis = new Vector3D(0, 3, 0);
    89. myAxisAngleRotation3d.Angle = 40;
    90. myRotateTransform3D.Rotation = myAxisAngleRotation3d;
    91. myGeometryModel.Transform = myRotateTransform3D;
    92. myModel3DGroup.Children.Add(myGeometryModel);
    93. myModelVisual3D.Content = myModel3DGroup;
    94. myViewport3D.Children.Add(myModelVisual3D);
    95. this.Content = myViewport3D;
    96. }
    97. }
    98. }

    首先生成几个wpf元素,和xaml里的对应;
    然后生成一个摄像机,赋值一些参数;把摄像机加入场景;
    然后把光源也加入;

    然后生成一个MeshGeometry3D类的对象;
    然后生成向量来设置此对象的法线;
    然后生成一些Point3D点来赋值给此对象的Positions属性;前面是在xaml里赋值的;
    然后设置此对象的纹理坐标;
    然后设置此对象的TriangleIndices属性;前面是在xaml里赋值的;
    把此对象加入场景;

    然后添加画刷和材质,添加一个变换;

    运行,

  • 相关阅读:
    day20--Java集合03
    程序员必修课:阿里开源SpringBoot全栈小册
    6种常见分布式唯一ID生成策略及它们的优缺点对比
    Mathorcup数学建模竞赛第三届-【妈妈杯】C题:语音识别技术的应用(附带赛题解析&获奖论文&MATLAB代码)(一)
    上周热点回顾(4.8-4.14)
    操作系统简介(上)
    机器学习笔记之线性分类——感知机算法
    微信阅读小程序设计与实现-计算机毕业设计源码+LW文档
    Windows Server 2012服务器无法识别ADB Interface的解决办法
    【预测模型-SVM分类】基于算术优化算法优化支持向量机SVM实现数据分类附matlab代码
  • 原文地址:https://blog.csdn.net/bcbobo21cn/article/details/128141408