LINUX.ORG.RU

[С++] визуализация поля в реальном поле

 


0

0

Есть двухмерный массив... где-то порядка 20x50. Его содержимое изменяется, допустим, в среднем раз в две секунды. Надо его изображать вот так или так. Ну или вроде того. В реальном времени, т.е. на экране.

Как такое лучше делать?

★★★★★

Последнее исправление: Obey-Kun (всего исправлений: 1)

Возможно «из коробки» openDX поможет? А иначе повесить на inotifywait рисование из R (если табличка в файле лежит).

Или где табличка на самом деле лежит?

psv1967 ★★★★★
()

Решали когда-то аналогичную задачу.

Сначала использовали анимацию в matplotlib+scipy, скрипт написали за час, но тормозило жутко, хотя у нас было более чем 100x100 точек и обновлялись они более 10 раз в секунду. 2 раза в секунду на нормальной машине такой график как у тебя в примере без проблем потянет.

Потом перешли к приложению на Qt+qwt. Всё стало гораздо быстрее, хотя на программу естественно потратили больше времени, чем на скрипт.

Dblmok
()

А в чем проблема в MathGL? Используете класс mglGraphFLTK/mglGraphQT c NULL вместо функции рисования. Сам рисунок строите в отдельном потоке (там где идет расчет) и по мере необходимости вызываете Update() для перерисовки.

abalakin ★★
()

Делал такое. Писал программу визуализации на OpenGL сам. Все летало на гораздо больших разрешениях.

Reset ★★★★★
()

В OpenGL есть glMap2

anonymous
()
Ответ на: комментарий от Dblmok

Потом перешли к приложению на Qt+qwt. Всё стало гораздо быстрее, хотя на программу естественно потратили больше времени, чем на скрипт.

Спасибо за наводку. Интерфейс и так будет на Qt.

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

А в чем проблема в MathGL? Используете класс mglGraphFLTK/mglGraphQT c NULL вместо функции рисования. Сам рисунок строите в отдельном потоке (там где идет расчет) и по мере необходимости вызываете Update() для перерисовки.

Я знаю, просто хочется посмотреть, как ещё люди такое делают.

А для создания потока с рисовалкой OpenMP подойдёт, или там нужн что-то более низкоуровневое?

Obey-Kun ★★★★★
() автор топика

Писали в универе на C++/MFC (да, omg) ручками с нуля, где-то порядка двух ночей занимает. Если руками соберешься делать - могу лекции (описание какого-то простого алгоритма, как рисовать) выложить или поискать свою реализацию.

gizzka ★★
()
Ответ на: комментарий от Obey-Kun

Есть рисовалка, а есть генерилка данных для рисовалки. Рисовалка работает в основном потоке Qt, генерилка собирает данные от числодробильни, строит структуры для рисовалки и делает swap, если рисуем на OpenGL с помощь сложных вещей glBufferData/glCallList, то ставим еще флаг, что на следующем цикле отрисовки надо обновить данные в видео памяти/обновить списки отрисовки. OpenMP тут каким боком?

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

Алгоритм рисования линий уровня примитивен — функция задана на сетке, сетка разбита на полигоны (прямоугольники или треугольники), надо представить это как 3х мерный объект и найти отрезки по которым пересекаются полигоны с плоскостями, лежащими на нужной высоте (уровне). Пишется это дело за час максимум. У меня код занимает 300 строк, но я извращался с nurbs кривыми, если сетка мелкая, то эти извращения ничего не дают, обычная линейная интерполяция хорошо смотрится.

Reset ★★★★★
()
Ответ на: комментарий от Obey-Kun

> А для создания потока с рисовалкой OpenMP подойдёт, или там нужн что-то более низкоуровневое?

Зачем OpenMP? — там же нет циклов для распараллеливания?! Обычный pthread для второго потока. Или можно обработку сообщений окна во второй поток засунуть. Например:

void *mgl_fl_tmp(void *) { mglFlRun(); return 0; }

void mgl_fltk_thread() { static pthread_t tmp; pthread_create(&tmp, 0, mgl_fl_tmp, 0); pthread_detach(tmp); }

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

Все становится чуть сложнее, когда надо вывести контур пунктиром, или текст (подпись) вдоль контура. Но в простейшем случае действительно полчаса работы ;)

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

Раз ее сам туда занес, то сразу по занесении и дерни за рисовалку.

И писать самому вывод графика — бесполезно тратить время, прощее подключить готовое изделие.

anonymous
()
Ответ на: комментарий от Reset

> Есть рисовалка, а есть генерилка данных для рисовалки.

Угу. Но я нуб в распараллеливании, не подскажешь, как быть?

Для генерирования данных мы пробегаемся по (одномерному) vector'у, причём порядок абсолютно не важен, то есть может быть количество потоков, равное количеству элементов этого vector'а (а их там будет от 1000 и более).

Рисовать же надо не на каждом шагу, а в зависимости от выбора пользователя (например, раз в 3 секунды или раз в 200 циклов). Так вот, какие методы распараллеливания тут применять? OpenMP внутри генерилки (с автоматическим выбором количества потоков) и qt threads для отделения генерилки и рисовалки?

Obey-Kun ★★★★★
() автор топика
Ответ на: комментарий от Obey-Kun

У тебя всего два потока — рисовалка и генерилка. Генерилка генерит данные, когда заканчивает кидает сигнал (например дергает updateGL) и в основном потоке Qt начинается отрисовка новых данных. Внутри генерилки извращайся как хочешь, хоть на OpenMP, но я не думаю, что имеет смысл это делать, задача не такая сложная и прожорливая.

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

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

так ты задачу не знаешь, она вполне прожорливая :)

ну в общем ясно, openmp внутри генерилки и разделить треды генерилки и рисовалки с помощью qt threads...

Obey-Kun ★★★★★
() автор топика
Ответ на: комментарий от Obey-Kun

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

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

20x50 ... среднем раз в две секунды.

:)) я понимаю, если 2000х5000 с таким же рэйтом

мои две копейки:
http://root.cern.ch/drupal/category/image-galleries/data-analysis-visualization
http://root.cern.ch/drupal/category/image-galleries/basic-graphics?page=1
http://root.cern.ch/root/html/THistPainter.html

... и многое другое

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

лучше ваще разбить на два процесса:
один производит, другой отображает данные и
передавать оных через shared memory или sockets
(на локальной машине они «почти» то же самое, что и sockets,
но позволяют иметь эти процессы на разных машинах).
Ну, или выкладывать данные http server, а визуализиравоть через web

Valeriy_Onuchin ★★
()

в qwt видел очень похожее, наверно, оно. Раз его и другие участники подсказывают, значит это то, что надо :)

azure ★★
()
Ответ на: комментарий от Obey-Kun

qt threads для отделения генерилки и рисовалки?

Да. Если это все представляет единое приложение, а не клиент-серверную связку, то через qt threads (заодно и кросплатформенно получится), соединения через сигнал-слот механизм. Из гуевого треда запустить числодробильный и с него слать сингалы о каждом обновлении. Как-то так. Впрочем, это не единственный вариант.

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

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

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