【问题标题】:WPF 3D - mapping gradient brush on complex geometryWPF 3D - 在复杂几何体上映射渐变画笔
【发布时间】:2010-10-07 12:24:01
【问题描述】:

我想问是否有人知道如何在 WPF 3D 中的复杂对象上映射渐变画笔。结果应该类似于 matlab 中的 3D 图像(例如 3D 函数)。假设您有一些想要可视化的 3 维数据,并且想要通过颜色区分某些级别的值。

【问题讨论】:

    标签: wpf 3d geometry gradient


    【解决方案1】:

    鉴于 GradientBrush 定义如下:

            <LinearGradientBrush x:Name="RedYellowGradient">
                <GradientStop Color="Blue" Offset="0.01" />
                <GradientStop Color="Purple" Offset="0.25"/>
                <GradientStop Color="Red" Offset="0.5"/>
                <GradientStop Color="Orange" Offset="0.75"/>
                <GradientStop Color="Yellow" Offset="1.0"/>
            </LinearGradientBrush>
    

    基本上,您将GradientBrush 分配给MeshGeometry3DDiffuseMaterial。定义画笔时,将其ViewportUnits 属性设置为“Absolute”。

    这样的事情可以直接在 XAML 表单的代码隐藏中工作(否则,使用相应的属性在代码中(在您的 ViewModel 中)创建画笔,或从您的资源字典中调用它):

    MyMaterial = New DiffuseMaterial(RedYellowGradient) With {.ViewportUnits = BrushMappingMode.Absolute}
    

    然后,对于几何体中的每个 Point3D,将一个介于 0.0 和 1.0 之间的值分配给相应的纹理坐标。通常,对于预先确定大小的 Point 数组,它可能如下所示:

        Parallel.For(0, positions.Count - 3, Sub(i)
                                                 Dim p = positions(i)
                                                 Dim plotValue = GetYourValue(p.X, p.Y, p.Z)
                                                 Dim t = (plotValue - minPlot) / (maxPlot - minPlot)
                                                 If t < 0 Then t = 0
                                                 If t > 1 Then t = 1                                                
                                                 arr(i) = New Point(t, 0.5)
                                             End Sub)
    

    如果你的刻面很长或者顶点之间的值相距很远,你的绘图会看起来很奇怪。但是考虑到 WPF 3D 的限制,它可能是您在没有大量 UV 映射的情况下可以做到的最好的方法。

    (如果您需要 C#,Roslyn CTP 有一个 VS Add-on,可以将剪贴板上的 VB 代码转换为 C#...)

    【讨论】: