C# 三维表面着色,带有第四维标记特殊值

C# 三维表面着色,带有第四维标记特殊值,c#,3d,ilnumerics,geometry-surface,C#,3d,Ilnumerics,Geometry Surface,我想创建一个三维曲面图,如图所示。我正在使用ILNumerics。到目前为止,我可以使用以下代码创建曲面(数据仅用于测试): using System; using System.Drawing; using System.Windows.Forms; using ILNumerics; using ILNumerics.Drawing; using ILNumerics.Drawing.Plotting; namespace WindowsFormsApplication1 {

我想创建一个三维曲面图,如图所示。我正在使用ILNumerics。到目前为止,我可以使用以下代码创建曲面(数据仅用于测试):

using System;
using System.Drawing;
using System.Windows.Forms;
using ILNumerics; 
using ILNumerics.Drawing; 
using ILNumerics.Drawing.Plotting; 

namespace WindowsFormsApplication1 {
    public partial class Form1 : Form {
        public Form1() {
            InitializeComponent();
        }

    private void ilPanel1_Load(object sender, EventArgs e) {
        using (ILScope.Enter()) {
            ILArray<float> R = ILMath.linspace<float>(-4, 4, 100);
            ILArray<float> y = 1;
            ILArray<float> x = ILMath.meshgrid(R, R, y);

            ILArray<float> Z = ILMath.zeros<float>(x.S[0], x.S[1], 3); 
            Z[":;:;1"] = x; Z[":;:;2"] = y; 
            Z[":;:;0"] = 0.4f * x * x - 0.2f * y * y * y; 

            ilPanel1.Scene.Add(new ILPlotCube(twoDMode: false) {
                new ILSurface(Z, colormap: Colormaps.Cool) {
                    Colors = 1.4f * x * x * x + 0.13f * y * y,
                    Childs = { new ILColorbar() }
                }
            }); 
        }
    }
    }
}
使用系统;
使用系统图;
使用System.Windows.Forms;
使用数字法;
使用数字。绘图;
使用ILNumerics.Drawing.Plotting;
命名空间Windows窗体应用程序1{
公共部分类Form1:Form{
公共表格1(){
初始化组件();
}
私有无效ilPanel1_加载(对象发送方、事件参数e){
使用(ILScope.Enter()){
ILArray R=ILMath.linspace(-4,4100);
i阵列y=1;
ILArray x=ILMath.meshgrid(R,R,y);
ILArray Z=ILMath.zero(x.S[0],x.S[1],3);
Z[“:;:;1”]=x;Z[“:;:;2”]=y;
Z[“:;:;0”]=0.4f*x*x-0.2f*y*y;
ilPanel1.Scene.Add(新ILPlotCube(twoDMode:false){
新的ILSurface(Z,colormap:Colormaps.Cool){
颜色=1.4f*x*x*x+0.13f*y*y,
Childs={new ILColorbar()}
}
}); 
}
}
}
}


用不同颜色标记数据(颜色)值为0的所有镶嵌面的最佳方法是什么?也许使用颜色条是最好的选择?但这究竟是如何做到的呢?

这可以通过使用自定义颜色贴图来实现。但我们必须小心,才能可靠地做到这一点。简单地把一个新的红色关键点放在色标中间会给出非常不正确的结果……p> 我稍微修改并记录了您的示例。基本上,颜色贴图包含带有位置和颜色的关键点。位置通常(但不一定)在[0..1]之间。颜色始终在[0..1]范围内。这里的挑战是在colormap范围内找到“0”cdata值的正确位置

首先,创建默认的Cool colormap。它有以下两个关键点(以行为单位):

彩色按键
[2,5]

[0]:000000000000100000很棒的东西!但不知怎么的,对我来说它看起来不一样。颜色不像图片中那样平滑。看起来您正在使用mono进行渲染。不同渲染/框架之间的输出是否存在正常差异?否。无论使用OpenGL、GDI还是SVG,所有平台上的输出都非常相似。您可能遇到了错误。这里有一个链接到最新的RC:worksforme。我想知道,如果在单独的颜色模式下也不能这样做?我的意思是如果我给每个网格点一个单独的颜色?真的。这将更加简单。但是有英迪夫。颜色没有色条。从这个问题来看,OP似乎需要一个。因此,操纵颜色贴图是必要的。
colorkeys
<Single> [2,5]
    [0]: 0,00000 0,00000 1,00000 1,00000 1,00000 <- position: 0, color: RGBA
    [1]: 1,00000 1,00000 0,00000 1,00000 1,00000 <- position: 1
colorkeys
<Single> [5,5]
     [0]: 0,00000 0,00000 1,00000 1,00000 1,00000 
     [1]: 1,00000 1,00000 0,00000 1,00000 1,00000 
     [2]: 0,49150 0,49150 0,50850 1,00000 1,00000 
     [3]: 0,49702 0,49702 0,50298 1,00000 1,00000 
     [4]: 0,49426 1,00000 0,00000 0,00000 1,00000 
private void ilPanel1_Load(object sender, EventArgs e) {

    // create some X/Y meshgrid data 
    ILArray<float> y = 1, R = ILMath.linspace<float>(-4, 4, 100);
    ILArray<float> x = ILMath.meshgrid(R, ILMath.linspace<float>(-4, 4, 100), y);

    // precreate the surface data array
    ILArray<float> Z = ILMath.zeros<float>(x.S[0], x.S[1], 3);
    // surface expects Z, X and Y coords (in that order)
    Z[":;:;2"] = y; Z[":;:;1"] = x;
    Z[":;:;0"] = 0.4f * x * x - 0.2f * y * y * y;

    // our color data are based on another function 
    ILArray<float> cdata = 1.4f * x * x * x + 0.13f * y * y;

    // we need cdatas limits for creating a new colormap
    float min, max; cdata.GetLimits(out min, out max);

    // get default 'Cool' colormap
    var colormap = new ILColormap(Colormaps.Cool);
    // get colormap keys as array: [position,R,G,B,A]
    ILArray<float> colorkeys = colormap.Data;
    // helper function to map true values to 0..1 range 
    Func<float, float> map = a => { return (a - min) / (max - min); };

    // the value to mark and +/- tolerance width (to make it a visible strip at least)
    float markValue = 0, tolerance = 0.5f;
    // sample the colormap at the marked edges
    Vector4 key1 = colormap.Map(markValue - tolerance, new Tuple<float, float>(min, max));
    Vector4 key2 = colormap.Map(markValue + tolerance, new Tuple<float, float>(min, max));
    // create new keypoints at the edges of marked area
    colorkeys[ILMath.end + 1, ":"] = ILMath.array(map(markValue - tolerance), key1.X, key1.Y, key1.Z, 1f); 
    colorkeys[ILMath.end + 1, ":"] = ILMath.array(map(markValue + tolerance), key2.X, key2.Y, key2.Z, 1f); 
    // create new keypoint for the marked area itself; color red
    colorkeys[ILMath.end + 1, ":"] = ILMath.array(map(markValue), 1f, 0f, 0f, 1f); // red
    // make a new colormap out of it 
    colormap = new ILColormap(colorkeys);
    // create & add a plot cube 
    ilPanel1.Scene.Add(new ILPlotCube(twoDMode: false) {
        // add surface plot, give custom colormap & colormap data ...
        new ILSurface(Z, colormap: colormap, C: cdata) {
            // add colorbar
            Childs = { new ILColorbar() }
        }
    }); 
}