要在 WPF 中渲染 3D 场景,您必须使用名为ViewPort3D. 这有一个Camera,一个集合Visual3D。的具体子类型Visual3D是ModelVisual3D。此视觉效果有助于呈现Model3D. 所有 3D 形状均由GeometryModel3D或更复杂的Model3DGroup(均源自Model3D)表示。我们只关心这里的属性GeometryModel3D.Geometry(类型Geometry3D)。目前,WPF只支持只有1样的的Geometry3D叫MeshGeometry3D。但是这个几何图形由大量的三角形组成。为了定义三角形,它有一组Point3Ds ( Positions) 表示三角形的顶点和一组int( TriangleIndices) 用于指示如何连接顶点(保存在Positions) 来制作实际的三角形。
这意味着你要绘制的曲线应该有某种形状,比如某种圆柱体(如粉条)或者就像一条布条……无论如何这并不容易。下面的演示代码将曲线渲染为细条(不是圆形),但实际上我们将它做得很细,以至于您只能看到它看起来像一条线(取决于我们查看场景的距离)。
正如我前面所说,我们需要建立的曲线是填补信息(Positions和TriangleIndices一个)MeshGeometry3D。我们需要曲线的一些方程,做一些循环来获得 Point3Ds(属于曲线)的集合,同时TriangleIndices适当地填充。
下面是代码细节:
XAML:
<Grid Name="grid">
<Viewport3D>
<Viewport3D.Camera>
<PerspectiveCamera Position="55,55,55" LookDirection="-1,-1,-1"
UpDirection="0,1,0" FieldOfView="20"/>
</Viewport3D.Camera>
<Viewport3D.Children>
<ModelVisual3D>
<ModelVisual3D.Content>
<Model3DGroup>
<DirectionalLight Color="White" Direction="1,0,-1"/>
<AmbientLight Color="Black"/>
<GeometryModel3D>
<GeometryModel3D.Material>
<MaterialGroup>
<DiffuseMaterial Brush="Red"/>
<EmissiveMaterial Brush="#330000ff"/>
</MaterialGroup>
</GeometryModel3D.Material>
<GeometryModel3D.BackMaterial>
<MaterialGroup>
<DiffuseMaterial Brush="Red"/>
<EmissiveMaterial Brush="#330000ff"/>
</MaterialGroup>
</GeometryModel3D.BackMaterial>
<GeometryModel3D.Geometry>
<MeshGeometry3D x:Name="geo"/>
</GeometryModel3D.Geometry>
<GeometryModel3D.Transform>
<RotateTransform3D>
<RotateTransform3D.Rotation>
<AxisAngleRotation3D Axis="0,1,0"
Angle="0" x:Name="rot"/>
</RotateTransform3D.Rotation>
</RotateTransform3D>
</GeometryModel3D.Transform>
</GeometryModel3D>
</Model3DGroup>
</ModelVisual3D.Content>
</ModelVisual3D>
</Viewport3D.Children>
<Viewport3D.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard Storyboard.TargetName="rot">
<DoubleAnimation Storyboard.TargetProperty="Angle" By="360"
RepeatBehavior="Forever" Duration="00:00:10"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Viewport3D.Triggers>
</Viewport3D>
</Grid>
Run Code Online (Sandbox Code Playgroud)
请注意有关Name的的MeshGeometry3D在XAML代码geo,我们需要参考这个使用代码来构建曲线。
背后的代码:
int k = 0;
for (float n = 0f; n < 1; n += 0.01f, k++) {
//calculate the current Point3D based on the equations of the curve
var x = -13 * Math.Pow(n, 3) - 12 * n * n;
var y = 35 * Math.Pow(n, 5) - 13 * n * n + 3 * n + 1;
var z = -30 * Math.Pow(n, 3) + 20 * n * n - n - 1;
//the current Point3D
var p = new Point3D(x, y, z);
//here is where we make it thin,
//you can replace .1 with such as 10 to enlarge the strip
var u = new Point3D(x, y - .1, z);
geo.Positions.Add(p);
geo.Positions.Add(u);
if (k > 0) {
geo.TriangleIndices.Add(k);
geo.TriangleIndices.Add(k - 1);
geo.TriangleIndices.Add(k + 1);
geo.TriangleIndices.Add(k);
}
geo.TriangleIndices.Add(k);
geo.TriangleIndices.Add(k + 1);
k++;
}
Run Code Online (Sandbox Code Playgroud)
注意:我强烈建议您首先阅读 WPF 中的基本 3D 概念,至少您应该了解如何连接点 (in Positions) 以将三角形表面指示为您想要的。一旦理解了这一点,你就可以理解上面的代码了。