LINUX.ORG.RU

Визуализация распределения плотности 3D-объекта

 , , , ,


0

1

По мотивам вопроса XVilka мне необходимо (желательно в octave) визуализировать динамически (т.е. можно покрутить) распределение плотности объекта: rho = f(x,y,z).

Т.е. вроде как и 4D, но в тоже время можно и в 3D, если rho будет в виде интенсивности цвета/прозрачности. Т.е. сам объект будет смотреться дискретным. Такие себе жирные полупрозрачные шарики в пространстве. Чем больше rho, тем жирнее/менее прозрачно. x,y,z - целые числа, в частности индексы 3D-матрицы, значения которой - rho.

P.S. Что-то сопровождающий пакета mathgl в дебиане с января больше не обновляет. Разработчик пакета, кстати, вправе его настоятельно попросить так уж откровенно не игнорировать upstream?

★★★★★

может попробуй лучше не поверхности чтобы были, а цветная сетка? Тогда можно будет стандартными методами сделать.

хотя если pm3d умеет прозрачность, то будет и так, как ты хочешь.

глянь сюда http://gnuplot.sourceforge.net/demo/

dikiy ★★☆☆☆ ()

По мотивам вопроса XVilka мне необходимо (желательно в octave) визуализировать динамически (т.е. можно покрутить) распределение плотности объекта: rho = f(x,y,z).

Т.е. вроде как и 4D, но в тоже время можно и в 3D, если rho будет в виде интенсивности цвета/прозрачности.

Есть специальный тип графика Cloud (http://mathgl.sourceforge.net/doc_en/doc_en_73.html#Cloud-sample). Можно также использовать набор из многих (>=10 шт для плавности) Surf3A с cdat=adat (http://mathgl.sourceforge.net/doc_en/doc_en_72.html#Surf3A-sample).

Для быстрого вращения придется скорее всего либо сокращать число граней в Cloud либо уменьшать число поверхностей Surf3A.

Т.е. сам объект будет смотреться дискретным. Такие себе жирные полупрозрачные шарики в пространстве. Чем больше rho, тем жирнее/менее прозрачно. x,y,z - целые числа, в частности индексы 3D-матрицы, значения которой - rho.

Тогда Surf3A лучше. Можно взять cdat = adat для более прозрачных малых значений или cdat = a.max - adat для менее прозрачных малых значений.

P.S. Что-то сопровождающий пакета mathgl в дебиане с января больше не обновляет. Разработчик пакета, кстати, вправе его настоятельно попросить так уж откровенно не игнорировать upstream?

Настоятельно еще не просил, но спрашивал — обещал заняться версией 2.* в августе ...

abalakin ★★ ()

Задай сетку в пространстве и рисуй в узлах сферы с диаметром, пропорциональным f(x,y,z). Cферы будут непрозрачными, но за областями меньшей плотности легко разглядеть более плотные области. В виде статичной картинки видно будет плохо, зато если покрутить, будет хорошо.

i-rinat ★★★★★ ()
Ответ на: комментарий от dikiy

Спасибо, но что-то я с pm3d никак не могу получить желаемого результата. Хотя, может, оно и не возможно.

data.dat

0 0 0 0.5

1 1 1 0.5

2 2 2 0.5

3 3 3 0.5
Ожидаю лесенку из «кирпичиков» цвета 0.5 размерами в одну ячейку.

gag ★★★★★ ()
Ответ на: комментарий от abalakin

Спасибо за совет! Попробовал, но, заполняя массив, как описал выше, при использовании Surf3A тоже не получаю желаемого. Для начала я не обращал внимания на цвет, а хотелось получить «кирпичики» в заданных координатах. Т.е. при

i==0 && j==0 && k==0
i==1 && j==1 && k==1
i==2 && j==2 && k==2
я ставил цвет в 0.5, в противном случае - 0.

gag ★★★★★ ()
Ответ на: комментарий от i-rinat

Спасибо за совет! На одном графике в gnuplot'е можно их совместить или какой небольшой библиотечкой воспользоваться?

gag ★★★★★ ()
Ответ на: комментарий от gag

На одном графике в gnuplot'е можно их совместить или какой небольшой библиотечкой воспользоваться?

Без понятия, можно ли это вообще сделать в gnuplot (без особых усилий). Я просто где-то видел такие картинки и отметил про себя, что этим неплохо распределения плотности визуализировать.

i-rinat ★★★★★ ()
Ответ на: комментарий от gag

Для начала я не обращал внимания на цвет, а хотелось получить «кирпичики» в заданных координатах.

Хмм, кирпичики так конечно вряд ли получатся. Интерполяцию между точками никто не отменял. Насколько я понял пробовалось что-то типа

setsize 1200 600

new a 4 4 4
for $1 0 3
put a 0.5 $1 $1 $1
next

crange 0 1:light on:alpha on
subplot 2 1 0:rotate 40 10:box:cloud a
subplot 2 1 1:rotate 40 10:box:surf3 a 0.3

Тогда уж лучше использовать Cloud(). Или скорее NAN значения в точках, которые не видны (чтобы выключить интерполяцию). Или лучше всего просто идти с двойным шагом

i==0 && j==0 && k==0
i==2 && j==2 && k==2
i==4 && j==4 && k==4
соответствующий код MGL скрипта будет
setsize 1200 600

new a 7 7 7
for $1 0 3
put a 0.5 2*$1 2*$1 2*$1
next

crange 0 1:light on:alpha on

subplot 2 1 0:rotate 40 10:box:cloud a

subplot 2 1 1:rotate 40 10:box:surf3 a 0.3

abalakin ★★ ()
Ответ на: комментарий от abalakin

Оказывается, можно и скриптом...

Я пробовал через c++. С шагом в 2 уже намного лучше, но только для surf3. Cloud и surf3a выглядят всё ещё странно. Да и cloud в плане производительности даже на этом минимальном примере (3x3x3) еле-еле поворачивается.

#include "mgl2/window.h"

const int n = 7;
const int m = 7;
const int t = 7;
        
void mgls_prepare3d(mglData *a, mglData *b)
{
        int i, j, k;
        long i0;
        if (a) a->Create(n,m,t);
        if (b) b->Create(n,m,t);
#ifdef SURF3A
        double color = 0.1;
#endif

        for (i=0; i<n; i+=2)
                for (j=0; j<m; j+=2)
                        for (k=0; k<t; k+=2) {
                                i0 = i+n*(j+m*k);
#ifndef SURF3A
                                a->a[i0] = 0.5;
#else
                                a->a[i0] = color; b->a[i0] = 0.3;
                                color += 0.01;
#endif
                        }
}

int sample_my(mglGraph *gr) {
        mglData c;
#ifndef SURF3A
        mgls_prepare3d(&c, NULL);
        gr->Title("Cloud/Surf3 plot");
#else
        mglData d;
        mgls_prepare3d(&c, &d);
        gr->Title("Cloud/Surf3A plot");
#endif
        gr->Light(true);  gr->Alpha(true);
        gr->SubPlot(2,1,0);
        gr->Rotate(80,-20); gr->Box(); gr->Cloud(c);
        gr->SubPlot(2,1,1);
#ifndef SURF3A
        gr->Rotate(80,-20); gr->Box(); gr->Surf3(c);
#else
        gr->Rotate(80,-20); gr->Box(); gr->Surf3A(c, d);
#endif

        return 0;
}

int main(int argc,char **argv)
{
        mglWindow *gr;
        gr = new mglWindow(sample_my,"My plot",1);
        gr->Run();
        return 0;
}

Остаётся 2 вопроса: в скрипте surf3 рисует, кажется, «плиточки», а в c++ - треугольники, и где ошибка с Surf3A (рисует более 3x3x3 элементов).

gag ★★★★★ ()
Ответ на: комментарий от gag

Остаётся 2 вопроса: в скрипте surf3 рисует, кажется, «плиточки», а в c++ - треугольники, и где ошибка с Surf3A (рисует более 3x3x3 элементов).

В моем варианте рисовалась поверхность при одном значении уровня уровня =0.3 («surf3 a 0.3»). Это уровень между 0 и 0.5, чтобы заведомо «окружить» Ваши точки.

А вы рисуете несколько (по умолчанию 3 при -0.5, 0, 0.5 для цветовой шкалы [-1,1]) поверхностей уровня. В результате, максимум задевается одна из точек и рисуется только один треугольник.

Использование Surf3A в С++ примере не дает ничего нового, кроме изменения прозрачности этих треугольников.

abalakin ★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.