我们知道,3D模型是用三角形表示的,那一个圆该如何表示呢?其实用的就是割圆法,也就是用一个近似的多边形就表示一个圆。下图展示了10、20、50个顶点的正多边形,可以看出,正50边形看上去跟圆已经很接近了。我们的例子就是用正50边形。
切分之后,圆柱体变成了如下所示的三棱体的组合:
我们需要描述这个三棱体的三个面,共4个三角形(侧面是一个矩形,需要两个三角形)。
这是最重要的一部分。示例代码打算让三个面渲染出不同颜色,所以需要构造三个三角网格。
代码如下:
//底面三角网格
MeshGeometry3D bottom_mesh = new MeshGeometry3D() { Positions = new Point3DCollection(), TriangleIndices = new Int32Collection() };
//顶面三角网格
MeshGeometry3D top_mesh = new MeshGeometry3D() { Positions = new Point3DCollection(), TriangleIndices = new Int32Collection() };
//侧面三角网格
MeshGeometry3D side_mesh = new MeshGeometry3D() { Positions = new Point3DCollection(), TriangleIndices = new Int32Collection() };
Point3D bottom_center = new Point3D(0, 0, 0);//底面中心
Point3D top_center = new Point3D(0, 2, 0);//顶面中心
top_mesh.Positions.Add(top_center);
bottom_mesh.Positions.Add(bottom_center);
int parts = 50;//把圆切成50份
double angle = Math.PI * 2 / parts;
for (int i = 0; i < parts; i++)
{
double x1 = 1 * Math.Cos(angle * i);
double z1 = 1 * Math.Sin(angle * i);
double x2 = 1 * Math.Cos(angle * (i + 1));
double z2 = 1 * Math.Sin(angle * (i + 1));
Point3D bottom1 = new Point3D(x1, 0, z1);//底面
Point3D bottom2 = new Point3D(x2, 0, z2);
Point3D top1 = new Point3D(x1, 2, z1);
Point3D top2 = new Point3D(x2, 2, z2);
//底面
bottom_mesh.Positions.Add(bottom1);
bottom_mesh.Positions.Add(bottom2);
bottom_mesh.TriangleIndices.Add(i * 2 + 1);
bottom_mesh.TriangleIndices.Add(i * 2 + 2);
bottom_mesh.TriangleIndices.Add(0);
//顶面
top_mesh.Positions.Add(top1);
top_mesh.Positions.Add(top2);
top_mesh.TriangleIndices.Add(i * 2 + 2);
top_mesh.TriangleIndices.Add(i * 2 + 1);
top_mesh.TriangleIndices.Add(0);
//侧面
if (i == 0)
{
side_mesh.Positions.Add(bottom1);
side_mesh.Positions.Add(top1);
}
side_mesh.Positions.Add(bottom2);
side_mesh.Positions.Add(top2);
side_mesh.TriangleIndices.Add(i * 2 + 1);
side_mesh.TriangleIndices.Add(i * 2 + 3);
side_mesh.TriangleIndices.Add(i * 2 + 2);
side_mesh.TriangleIndices.Add(i * 2 + 1);
side_mesh.TriangleIndices.Add(i * 2 + 2);
side_mesh.TriangleIndices.Add(i * 2 + 0);
}
DiffuseMaterial bottom_material = new DiffuseMaterial(Brushes.Green);//底面绿色
DiffuseMaterial top_material = new DiffuseMaterial(Brushes.Blue);//顶面蓝色
DiffuseMaterial side_material = new DiffuseMaterial(Brushes.Red);//侧面红色
GeometryModel3D top = new GeometryModel3D(top_mesh, top_material);
GeometryModel3D bottom = new GeometryModel3D(bottom_mesh, bottom_material);
GeometryModel3D side = new GeometryModel3D(side_mesh, side_material);
首先看我们在XAML文件里定义的画布:
代码是非常简单的。然后我们把定义好的圆柱体三角网格、相机、光源都放进画布中:
//相机
Camera camera = new PerspectiveCamera(new Point3D(3, 6, 10), new Vector3D(-3, -6, -10), new Vector3D(0, 1, 0), 45);
//光源
Light light = new AmbientLight(Colors.White);
Model3DGroup group = new Model3DGroup();
group.Children.Add(light);
group.Children.Add(top);
group.Children.Add(bottom);
group.Children.Add(side);
ModelVisual3D model = new ModelVisual3D();
model.Content = group;
view.Children.Add(model);
view.Camera = camera;
如此一来,圆柱体就能正常显示了,如下图所示:
我们把相机的Position和LookDirection改成如下,从下面瞄一眼:
Camera camera = new PerspectiveCamera(new Point3D(3, -6, 10), new Vector3D(-3, 6, -10), new Vector3D(0, 1, 0), 45);
图像是: