WPF 3D - 在复杂几何体上映射渐变画笔

发布于 2024-09-26 08:01:59 字数 111 浏览 4 评论 0原文

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

I wanted to ask if anyone knows how to map gradient brush on complex objects in WPF 3D. The result should look similar to 3D images in matlab (3D function for example). Lets say you have some 3-dimensional data you wish to visualize and you want to diferentiate certain levels of values by color.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

伤感在游骋 2024-10-03 08:01:59

给定一个 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 之间的值分配给相应的纹理坐标。一般来说,对于预先确定大小的点数组,它可能如下所示:

    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 插件,可以将剪贴板上的 VB 代码转换为 C#...)

Given a GradientBrush defined something like this:

        <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>

Fundamentally, you assign the GradientBrush to the DiffuseMaterial of your MeshGeometry3D. When defining the brush, set its ViewportUnits property to "Absolute".

Something like this would work directly in the code-behind of a XAML form (otherwise, create the brush in code (in your ViewModel) using the corresponding properties, or call it from your resource dictionary):

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

Then, for each Point3D in your geometry, assign a value between 0.0 and 1.0 to the corresponding texture coordinate. Generically, for a pre-sized Point array it could look like this:

    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)

If your facets are very long or the values between vertices very far apart, your plotting will look odd. But given the strictures of WPF 3D it's probably the best you can do without a lot of UV Mapping.

(If you need C#, the Roslyn CTP has a VS Add-on which will convert VB code on the clipboard to C#...)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文