Цветовые диапазоны в поверхностном графике ILNumerics

Я использую ILNumerics для создания поверхностного графика.

Я хочу использовать плоскую затененную цветовую карту (т.е. цветовые диапазоны) вместо гладкой затененной цветовой карты (т.е. каждый пиксель имеет свой собственный цвет).

Возможно ли это с ILNumerics?

Пример графика плоской поверхности и легенды цветных полос:

Плоский графикПлоская цветовая карта

Пример графика поверхности Smooth-Shaded и легенды цветных полос:

График с гладкой поверхностьюСглаженная цветовая карта


person JRS    schedule 23.07.2014    source источник


Ответы (2)


Вы можете создать палитру, которая демонстрирует поведение плоского затенения. Просто продублируйте ключевые точки, существующие в общей карте цветов, чтобы смоделировать диапазон цветовых данных, получив одинаковый назначенный цвет.

Как работают плоские затененные цветовые карты

Согласно документации, ключевые точки цветовых карт состоят из 5 столбцов: "позиция" и 4 столбца. цветовые значения (RGBA). Чтобы смоделировать «плоскую» затененную карту цветов, поместите две ключевые точки «почти» точно друг над другом, задав первой цвет следующего более низкого диапазона, а второй — цвет следующего более высокого диапазона. Таким образом, цветовой диапазон моделируется двумя ключевыми точками, которым назначен один и тот же цвет.

Я написал «почти» в приведенном выше абзаце, потому что я думал, что вы должны оставить хотя бы крошечный зазор между краями двух диапазонов - надеясь, что никакое фактическое значение данных цвета никогда не попадет в этот зазор. Но кажется, что разрыв вообще не нужен, и обеим ключевым точкам можно присвоить точно одинаковое значение. Но вам нужно быть осторожным при сортировке: не перепутайте цвета (быстрая сортировка в ILMath.sort() нестабильна!)

В следующем примере из Colormaps.Jet создается плоская затененная карта цветов:

Keypoints for Colormaps.Jet (original, interpolating)
<Single> [6,5]
[0]:          0          0          0     0,5625          1 
[1]:     0,1094          0          0     0,9375          1 
[2]:     0,3594          0     0,9375          1          1 
[3]:     0,6094     0,9375          1     0,0625          1 
[4]:     0,8594          1     0,0625          0          1 
[5]:          1     0,5000          0          0          1 

Плоская версия затенения, полученная из него:

Colormaps.Jet - flat shading version
<Single> [11,5]
[0]:          0          0          0     0,5625          1 
[1]:     0,1094          0          0     0,5625          1 
[2]:     0,1094          0          0     0,9375          1 
[3]:     0,3594          0          0     0,9375          1 
[4]:     0,3594          0     0,9375          1          1 
[5]:     0,6094          0     0,9375          1          1 
[6]:     0,6094     0,9375          1     0,0625          1 
[7]:     0,8594     0,9375          1     0,0625          1 
[8]:     0,8594          1     0,0625          0          1 
[9]:     1,0000          1     0,0625          0          1 
[10]:          1     0,5000          0          0          1 

Как видите, я допустил ошибку в CreateFlatShadedColormap(): последняя ключевая точка с (0.5,0,0,1) никогда не будет использоваться. Я оставлю это как упражнение, чтобы исправить это... ;)

Пример полного плоского затенения

private void ilPanel1_Load(object sender, EventArgs e) {
    ILArray<float> A = ILMath.tosingle(ILSpecialData.terrain["0:400;0:400"]);
    // derive a 'flat shaded' colormap from Jet colormap
    var cm = new ILColormap(Colormaps.Jet);
    ILArray<float> cmData = cm.Data;
    cmData.a = Computation.CreateFlatShadedColormap(cmData);
    cm.SetData(cmData); 
    // display interpolating colormap
    ilPanel1.Scene.Add(new ILPlotCube() { 
        Plots = {
            new ILSurface(A, colormap: Colormaps.Jet) {
                Children = { new ILColorbar() },
                Wireframe = { Visible = false }
            }
        }, 
        ScreenRect = new RectangleF(0,-0.05f,1,0.6f)
    }); 

    // display flat shading colormap
    ilPanel1.Scene.Add(new ILPlotCube() {
        Plots = {
            new ILSurface(A, colormap: cm) {
                Children = { new ILColorbar() },
                Wireframe = { Visible = false }
            }
        },
        ScreenRect = new RectangleF(0, 0.40f, 1, 0.6f)
    }); 

}

private class Computation : ILMath {
    public static ILRetArray<float> CreateFlatShadedColormap(ILInArray<float> cm) {
        using (ILScope.Enter(cm)) {
            // create array large enough to hold new colormap
            ILArray<float> ret = zeros<float>(cm.S[0] * 2 - 1, cm.S[1]);
            // copy the original
            ret[r(0, cm.S[0] - 1), full] = cm; 
            // double original keypoints, give small offset (may not even be needed?) 
            ret[r(cm.S[0], end), 0] = cm[r(1, end), 0] - epsf;
            ret[r(cm.S[0], end), r(1, end)] = cm[r(0, end - 1), r(1, end)];
            // reorder to sort keypoints in ascending order
            ILArray<int> I = 1;
            sort(ret[full, 0], Indices: I);
            return ret[I, full];
        }

    }

Результат

Плоские цветовые карты в ILNumerics

person Haymo Kutschbach    schedule 27.07.2014
comment
Хотя я принял этот ответ, сюжет все еще не заштрихован. Это легко увидеть, увеличив масштаб или используя менее плотные наборы данных. Как заметил @user492238, цвета всегда интерполируются (сглаживаются) между точками данных. - person JRS; 29.07.2014
comment
Верно. Если у вас есть плитки, которые выбирают разные цвета для любой из своих вершин, цвет все равно будет интерполирован. Интересно, как ваша плоская затененная поверхность определена для обработки таких случаев? Какой цвет будет использоваться для всей области плитки, чем? Цвет, соответствующий среднему значению? Но чем это может быть полезно? Кроме того, рассмотрите возможность обновления своего вопроса, поскольку он относится к плоской затененной карте цветов. Вот что дает ответ. - person Haymo Kutschbach; 29.07.2014

Это невозможно. Поверхностные графики в ILNumerics всегда интерполируют цвета между точками сетки. Для других моделей затенения необходимо создать собственный класс поверхности.

person user492238    schedule 27.07.2014
comment
ОП просил не ILSurface, а «плоскую затененную цветовую карту». Я думаю, что стоит попробовать создать палитру, которая показывает описанное распределение цветов? - person Haymo Kutschbach; 28.07.2014
comment
Я добавил ответ. Довольно хорошо работает. - person Haymo Kutschbach; 28.07.2014