2013-05-31 47 views
3

我想創建如圖所示的3D表面圖。我正在使用ILNumerics,recent RC from the website。到目前爲止,我可以創建表面(數據僅用於測試)使用此代碼:用第4維標記特殊值的3D表面着色

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() } 
       } 
      }); 
     } 
    } 
    } 
} 

surface graph without marked values

什麼是標記與數據(彩色)的0值的所有facettes的最佳方式不同的顏色?可能使用顏色條將是要走的路?但是,這到底如何呢?

回答

3

這可以使用自定義色彩映射來實現。但一定要小心,要做到可靠。只需在顏色映射的中間放置一個新的紅色關鍵點就會給出非常不正確的結果......:|

我稍微修改並記錄了您的示例。基本上,色彩地圖包含具有位置和顏色的關鍵點。職位通常(但不一定)範圍從[0..1]。顏色總是在[0..1]的範圍內。這裏面臨的挑戰是在顏色映射範圍內找到'0'cdata值的正確位置。

首先,創建默認酷酷色彩地圖。它具有以下兩個關鍵點(行):

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 

您必須添加至少3個新的關鍵點:在標記區域的邊緣前兩個樣品原來的顏色。第三個標記區域顯示紅色。這是行不通的簡單的添加紅色關鍵點,因爲這將在地圖上影響所有值,不僅數據值0附近

在結束時,關鍵點如下所示:

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 

請注意,關鍵點的順序並不重要。無論如何,他們在創建新的色彩地圖時都進行了排序。新的地圖是簡單地提供給ILSurface:

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() } 
     } 
    }); 
} 

這會產生這樣的輸出: enter image description here

+0

偉大的東西!但不知怎的,它對我來說看起來不同。顏色不像你的照片那樣流暢。看來你正在使用單色進行渲染。這是不同的渲染/框架之間輸出的正常變化嗎? – user492238

+1

不需要。無論使用OpenGL,GDI還是SVG,輸出在所有平臺上*非常相似。你可能遇到了一個錯誤。這是一個鏈接到最新的RC:http://ilnumerics.net/release/EUJJRWPO225PlHDjW09/ILNumerics_v3.0_RCh.zip –

+1

適合我。我想知道,如果在個人色彩模式下也無法完成這項工作?我的意思是如果我給每個網格點個別顏色? –