使用 WPF 和 C# 绘制覆盖有阴影高度图的 3D 表面

此示例使用 C# 和 XAML 绘制覆盖有阴影高度图的 3D 表面。示例释了如何在三维表面上覆盖图像。此示例执行的操作类似。但是,它不是简单地使用包含网格的现有图像,而是生成一个阴影图像以显示表面的高度。

下面的CreateAltitudeMap方法生成纹理位图。

该方法首先计算所绘制区域的表面函数值。它计算将要创建的图像中每个像素的值,在本例中为 512×512 像素图像。然后,代码使用 LINQ Min和Max方法获取数组中的最大值和最小值。

然后,代码会创建一个BitmapPixelMaker对象。它会循环遍历图像中的像素,并使用相应的函数值来确定像素的颜色。代码使用MapRainbowColor方法(稍后介绍)将每个函数值映射到适当的颜色。

该方法最后调用BitmapPixelMaker对象的MakeBitmap方法来创建WriteableBitmap,然后使用位图的Save扩展方法将结果保存到文件中。

MapRainbowColor 方法使用以下代码将给定边界之间的值映射到颜色。

cs 复制代码
// Map a value to a rainbow color.
private void MapRainbowColor(double value,
    double min_value, double max_value,
    out byte red, out byte green, out byte blue)
{
    // Convert into a value between 0 and 1023.
    int int_value = (int)(1023 * (value - min_value) /
        (max_value - min_value));

    // Map different color bands.
    if (int_value < 256)
    {
        // Red to yellow. (255, 0, 0) to (255, 255, 0).
        red = 255;
        green = (byte)int_value;
        blue = 0;
    }
    else if (int_value < 512)
    {
        // Yellow to green. (255, 255, 0) to (0, 255, 0).
        int_value -= 256;
        red = (byte)(255 - int_value);
        green = 255;
        blue = 0;
    }
    else if (int_value < 768)
    {
        // Green to aqua. (0, 255, 0) to (0, 255, 255).
        int_value -= 512;
        red = 0;
        green = 255;
        blue = (byte)int_value;
    }
    else
    {
        // Aqua to blue. (0, 255, 255) to (0, 0, 255).
        int_value -= 768;
        red = 0;
        green = (byte)(255 - int_value);
        blue = 255;
    }
}

代码首先缩放该值,使其范围从 0 到 1023。根据值是 0 - 255、256 - 511、512 - 767 还是 768 - 1023 范围,代码将颜色转换为彩虹的不同部分。

将网格映射到表面上的程序 类似。以下代码显示了此示例如何使用CreateAltitudeMap方法保存的纹理图像来创建表面的材质。

cs 复制代码
// Create the altitude map texture bitmap.
private void CreateAltitudeMap()
{
    // Calculate the function's value over the area.
    const int xwidth = 512;
    const int zwidth = 512;
    const double dx = (xmax - xmin) / xwidth;
    const double dz = (zmax - zmin) / zwidth;
    double[,] values = new double[xwidth, zwidth];
    for (int ix = 0; ix < xwidth; ix++)
    {
        double x = xmin + ix * dx;
        for (int iz = 0; iz < zwidth; iz++)
        {
            double z = zmin + iz * dz;
            values[ix, iz] = F(x, z);
        }
    }

    // Get the upper and lower bounds on the values.
    var get_values =
        from double value in values
        select value;
    double ymin = get_values.Min();
    double ymax = get_values.Max();

    // Make the BitmapPixelMaker.
    BitmapPixelMaker bm_maker =
        new BitmapPixelMaker(xwidth, zwidth);

    // Set the pixel colors.
    for (int ix = 0; ix < xwidth; ix++)
    {
        for (int iz = 0; iz < zwidth; iz++)
        {
            byte red, green, blue;
            MapRainbowColor(values[ix, iz], ymin, ymax,
                out red, out green, out blue);
            bm_maker.SetPixel(ix, iz, red, green, blue, 255);
        }
    }

    // Convert the BitmapPixelMaker into a WriteableBitmap.
    WriteableBitmap wbitmap = bm_maker.MakeBitmap(96, 96);

    // Save the bitmap into a file.
    wbitmap.Save("Texture.png");
}
cs 复制代码
// Make the surface's material using an image brush.
ImageBrush texture_brush = new ImageBrush();
texture_brush.ImageSource =
    new BitmapImage(new Uri("Texture.png", UriKind.Relative));
DiffuseMaterial surface_material =
    new DiffuseMaterial(texture_brush);

源码:

https://download.csdn.net/download/ljygood2/90120994

相关推荐
阿里嘎多学长28 分钟前
2026-09-20 GitHub 热点项目精选
开发语言·程序员·github·代码托管
weixin_307779132 小时前
C++代码实现MATLAB中的ode23tb函数功能
开发语言·c++·算法·matlab
2601_966949652 小时前
为什么量化回测中 for 循环比 DataFrame 慢三个数量级?从向量化原理讲起
开发语言·python·pandas·股票数据·quantdash
边境悍匪4 小时前
蜗牛学苑 Java 智能体学习 Day45|Knife4j+SpringBoot3、书城项目整合 MyBatis 思维导图复盘
java·开发语言·vue.js·学习·spring
我的xiaodoujiao4 小时前
Django 基础知识详细图文教程 9-Django 模板引擎 2
开发语言·数据库·后端·django
菜鸟~noob2334 小时前
【太空电子战】从CCS到Meadowlands:反通信系统的二十年演进史【含matlab代码】
开发语言·matlab
2501_930707785 小时前
使用C#代码使用条件格式为 Excel 隔行设置颜色
c#·excel
quantdash_cc5 小时前
量化策略为什么需要实时行情数据?从信号产生到交易决策的时间差说起
开发语言·python·数据分析·量化交易·股票数据·quantdash
逆向编程7 小时前
QGIS地图投影(CRS坐标参照系)设置
开发语言
free-elcmacom7 小时前
发际线警告!手撕《C陷阱与缺陷》终极 BOSS:signal 函数与 typedef 魔法
c语言·开发语言·visual studio code·visual studio