LINUX.ORG.RU

Оптимизация отрисовки кривых


0

2

Есть некий прибор который может выдавать измерения по N каналам с определенной частотой, эти данные программа считывает и накапливает и отображает в виде графиков, причем по оси X может быть как время, так и любой из этих каналов (те получается график зависимости остальных каналов от этого).

Проблема в том, что при опросе 20 каналов с частотой 100 Гц в течении скажем получаса, получается несколько миллионов точек, которые надо нарисовать за приемлемое время. Сигнал каждого канала не совсем идеальный - есть и шумы АЦП и сам измеряемый сигнал имеет свои шумы - например вибрация.

Пример того что надо рисовать на картинке. Пример конечно не совсем реалистичный, но хорошо показывает суть проблемы. Надо максимально сохранить форму кривой и при этом радикально уменьшить количество отрисовываемых линий. Все усугубляется тем, что графики можно увеличивать/уменьшать и скроллить.

Вариант просто брать точки через 1/2/5/10 плох, тем что можно потерять значимые точки. Анализ угла между соседними линиями не даст эффекта из-за шумов. Выполнять фильтрацию/сглаживание данных на данном этапе тоже нельзя.

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


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

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

Да такие линии не рисуются, но на данных, когда шумы больше чем дискретность отображения эффективность метода близка нулю.

CFA
() автор топика

Отрисовывать в растр (с приличным разрешением) по мере сбора точек. А потом трассировать его в вектор.

i-rinat ★★★★★
()

Для тех рисунков что ты привел, начиная с 10000 точек, можно рисовать только точки вместо линий, все-равно ничего кроме их разброса не видно.

А вот при увеличении какого-либо участка отрисовывать попавшие в область зума точки как надо линиями, кол-во линий будет значительно меньше — профит

sdio ★★★★★
()

Что мешает брать среднюю координату за n шагов?

Ну или как тут уже сказали записывать все точки в растр, а потом переводить в вектор. Только нужно векторизовать именно массивы x(t) и y(t), а не x(y), ибо в параметрической кривой x(y) из-за самопересечений возможна неоднозначность, а из-за точек одновременного равенства нулю производных по времени возможны изломы, которые векторизовать будет трудно.

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

Усреднение плохо тем, что кратковременное изменение одного из параметров будет показано до n раз меньше действительного.

Насчет векторизации не совсем понятно. Получается для начала надо нарисовать кривую x(t) с шагом хотя бы 1 пиксел, а потом что?

CFA
() автор топика

Можно попробовать MathGL и установить SetDrawFace(false) или просто взять класс mglGraphPS для отрисовки (может потребовать много памяти). Вроде должно быстро рисовать.

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

>>Насчет векторизации не совсем понятно. Получается для начала надо нарисовать кривую x(t) с шагом хотя бы 1 пиксел, а потом что?

Есть двумерный массив точек в координатах (x,t). Найти кривую x(t) - классическая задача curve fitting. Выбираешь резонный базис функций и ищешь коэффициенты разложения, минимизирующие ошибку. Это и понимается под «векторизацией» - просто термин из области компьютерной графики, тут он не особо к месту.

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

без MathGL в худшем случае миллион точек рисуется примерно за это же время, на более «хороших» данных, на порядок быстрее.

если я правильно понял то «curve fitting» сводится к решению системы из n уравнений или вычислению полинома степени n, где n в моем случае будет очень большим?

CFA
() автор топика
Ответ на: комментарий от CFA

Нашел алгоритм Дугласа-Пьюкера, но судя по всему у него большая вычислительная сложность. В понедельник попробую. Может кто-нибудь пробовал его и может рассказать что нибудь о нем?

CFA
() автор топика

OpenGL должен справиться, я как раз над таким работаю.
Как-то накидал 200000 Vertex3f-точек — могло их двигать в 3Д пространстве,
может с миллионом Vertex2f и справиться.
Ибо QwtPlotWidgets, либо другие инструменты не справляются с большим количеством точек.

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