如何在 WPF 中绘制 3D 曲线?

ale*_*555 0 3d wpf draw

是否可以在 WPF 中绘制 3D 曲线?即我需要哪些课程?你能给我这样的代码片段吗?

在此处输入图片说明

Kin*_*ing 6

要在 WPF 中渲染 3D 场景,您必须使用名为ViewPort3D. 这有一个Camera,一个集合Visual3D。的具体子类型Visual3DModelVisual3D。此视觉效果有助于呈现Model3D. 所有 3D 形状均由GeometryModel3D或更复杂的Model3DGroup(均源自Model3D)表示。我们只关心这里的属性GeometryModel3D.Geometry(类型Geometry3D)。目前,WPF只支持只有1样的的Geometry3DMeshGeometry3D。但是这个几何图形由大量的三角形组成。为了定义三角形,它有一组Point3Ds ( Positions) 表示三角形的顶点和一组int( TriangleIndices) 用于指示如何连接顶点(保存在Positions) 来制作实际的三角形。

这意味着你要绘制的曲线应该有某种形状,比如某种圆柱体(如粉条)或者就像一条布条……无论如何这并不容易。下面的演示代码将曲线渲染为细条(不是圆形),但实际上我们将它做得很细,以至于您只能看到它看起来像一条线(取决于我们查看场景的距离)。

正如我前面所说,我们需要建立的曲线是填补信息(PositionsTriangleIndices一个)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) 以将三角形表面指示为您想要的。一旦理解了这一点,你就可以理解上面的代码了。