WPF 3D开发教程(四)

原文: WPF 3D开发教程(四)

四、实战:展示一个圆柱体

4.1 圆柱体分解

我们知道,3D模型是用三角形表示的,那一个圆该如何表示呢?其实用的就是割圆法,也就是用一个近似的多边形就表示一个圆。下图展示了10、20、50个顶点的正多边形,可以看出,正50边形看上去跟圆已经很接近了。我们的例子就是用正50边形。

切分之后,圆柱体变成了如下所示的三棱体的组合:

我们需要描述这个三棱体的三个面,共4个三角形(侧面是一个矩形,需要两个三角形)。

4.2 三角网格构建

这是最重要的一部分。示例代码打算让三个面渲染出不同颜色,所以需要构造三个三角网格。

代码如下:


  
  
  1. //底面三角网格
  2. MeshGeometry3D bottom_mesh = new MeshGeometry3D() { Positions = new Point3DCollection(), TriangleIndices = new Int32Collection() };
  3. //顶面三角网格
  4. MeshGeometry3D top_mesh = new MeshGeometry3D() { Positions = new Point3DCollection(), TriangleIndices = new Int32Collection() };
  5. //侧面三角网格
  6. MeshGeometry3D side_mesh = new MeshGeometry3D() { Positions = new Point3DCollection(), TriangleIndices = new Int32Collection() };
  7. Point3D bottom_center = new Point3D( 0, 0, 0); //底面中心
  8. Point3D top_center = new Point3D( 0, 2, 0); //顶面中心
  9. top_mesh.Positions.Add(top_center);
  10. bottom_mesh.Positions.Add(bottom_center);
  11. int parts = 50; //把圆切成50份
  12. double angle = Math.PI * 2 / parts;
  13. for ( int i = 0; i < parts; i++)
  14. {
  15. double x1 = 1 * Math.Cos(angle * i);
  16. double z1 = 1 * Math.Sin(angle * i);
  17. double x2 = 1 * Math.Cos(angle * (i + 1));
  18. double z2 = 1 * Math.Sin(angle * (i + 1));
  19. Point3D bottom1 = new Point3D(x1, 0, z1); //底面
  20. Point3D bottom2 = new Point3D(x2, 0, z2);
  21. Point3D top1 = new Point3D(x1, 2, z1);
  22. Point3D top2 = new Point3D(x2, 2, z2);
  23. //底面
  24. bottom_mesh.Positions.Add(bottom1);
  25. bottom_mesh.Positions.Add(bottom2);
  26. bottom_mesh.TriangleIndices.Add(i * 2 + 1);
  27. bottom_mesh.TriangleIndices.Add(i * 2 + 2);
  28. bottom_mesh.TriangleIndices.Add( 0);
  29. //顶面
  30. top_mesh.Positions.Add(top1);
  31. top_mesh.Positions.Add(top2);
  32. top_mesh.TriangleIndices.Add(i * 2 + 2);
  33. top_mesh.TriangleIndices.Add(i * 2 + 1);
  34. top_mesh.TriangleIndices.Add( 0);
  35. //侧面
  36. if (i == 0)
  37. {
  38. side_mesh.Positions.Add(bottom1);
  39. side_mesh.Positions.Add(top1);
  40. }
  41. side_mesh.Positions.Add(bottom2);
  42. side_mesh.Positions.Add(top2);
  43. side_mesh.TriangleIndices.Add(i * 2 + 1);
  44. side_mesh.TriangleIndices.Add(i * 2 + 3);
  45. side_mesh.TriangleIndices.Add(i * 2 + 2);
  46. side_mesh.TriangleIndices.Add(i * 2 + 1);
  47. side_mesh.TriangleIndices.Add(i * 2 + 2);
  48. side_mesh.TriangleIndices.Add(i * 2 + 0);
  49. }
  50. DiffuseMaterial bottom_material = new DiffuseMaterial(Brushes.Green); //底面绿色
  51. DiffuseMaterial top_material = new DiffuseMaterial(Brushes.Blue); //顶面蓝色
  52. DiffuseMaterial side_material = new DiffuseMaterial(Brushes.Red); //侧面红色
  53. GeometryModel3D top = new GeometryModel3D(top_mesh, top_material);
  54. GeometryModel3D bottom = new GeometryModel3D(bottom_mesh, bottom_material);
  55. GeometryModel3D side = new GeometryModel3D(side_mesh, side_material);

4.3 相机、光源和其他代码

首先看我们在XAML文件里定义的画布:


  
  
  1. <Viewport3D Name= "view">
  2. </Viewport3D>

代码是非常简单的。然后我们把定义好的圆柱体三角网格、相机、光源都放进画布中:


  
  
  1. //相机
  2. Camera camera = new PerspectiveCamera( new Point3D( 3, 6, 10), new Vector3D( -3, -6, -10), new Vector3D( 0, 1, 0), 45);
  3. //光源
  4. Light light = new AmbientLight(Colors.White);
  5. Model3DGroup group = new Model3DGroup();
  6. group.Children.Add(light);
  7. group.Children.Add(top);
  8. group.Children.Add(bottom);
  9. group.Children.Add(side);
  10. ModelVisual3D model = new ModelVisual3D();
  11. model.Content = group;
  12. view.Children.Add(model);
  13. view.Camera = camera;

如此一来,圆柱体就能正常显示了,如下图所示:

扫描二维码关注公众号,回复: 11132631 查看本文章

我们把相机的Position和LookDirection改成如下,从下面瞄一眼:

Camera camera = new PerspectiveCamera(new Point3D(3, -6, 10), new Vector3D(-3, 6, -10), new Vector3D(0, 1, 0), 45);
 
 

图像是:

猜你喜欢

转载自www.cnblogs.com/lonelyxmas/p/12783977.html