Russian Qt Forum

Qt => Вопросы новичков => Тема начата: Bepec от Сентябрь 16, 2013, 10:49



Название: Написание собственного графика.
Отправлено: Bepec от Сентябрь 16, 2013, 10:49
Приветствую заглянувших.

Появилась необходимость в отрисовке графиков.

Цель: Написать легкий компонент для отображения и масштабирования графиков и поднатаскать себя в области графического отображения.

Проблема: не могу найти литературу и продумать архитектуру. (т.е. считай знание геометрии за 9 классов есть, не больше :) )

Собственно мне представляется следующая архитектура:
1) класс - полотно. Отображает точечки, рисует оси координат.
2) класс - хранилище данных. Отдаёт данные полотну (или нескольким) посредством сигналов.
3) прокси класс - масштабирующий компонент. Принимает данные от хранилища данных, преобразовывает, отдаёт полотну. Должен как то стыковаться с полотном для получения действий пользователя.

PS посоветуйте литературу по графикам - усреднению и прочему.
PPS ну и на огрехи в архитектуре поругайте :)


Название: Re: Написание собственного графика.
Отправлено: m_ax от Сентябрь 16, 2013, 12:39
Как то писал подобный велосипед) LightPlot2D - вот здесь обсуждение http://www.prog.org.ru/topic_10208_90.html (http://www.prog.org.ru/topic_10208_90.html)

Есть сама библиотека lightplot2d здесь https://code.google.com/p/lightplot2d/ (https://code.google.com/p/lightplot2d/)

И есть отдельно под неё написанный виджет со всеми диалогами и т.д.. (приаттачил пару скриншотов)

Но это уже давно мёртвый проект и сейчас понимаю, как писать не надо было)

 


Название: Re: Написание собственного графика.
Отправлено: m_ax от Сентябрь 16, 2013, 12:41
Приатачиваю сам Plotter (требует lightplot2d)



Название: Re: Написание собственного графика.
Отправлено: Bepec от Сентябрь 16, 2013, 12:46
Ммм... Эт конечно круто :) Но мне б свои навыки прокачать в создании графических велосипедов :) Был бы нужен готовый - использовал бы QWT. ^.^

PS посмотрю код, мож чего надёргаю. Мне теории нехватает.

PPS посмотрел ваш плот - интересно. Но увы. У меня примерно 40 тысяч на 60 тысяч график должен быть по осям. Собственно велосипеды других, в том числе и ваш под это не особо подойдут. Тут нужен свой, оптимизированный. 


Название: Re: Написание собственного графика.
Отправлено: Igors от Сентябрь 16, 2013, 13:27
Цель: Написать легкий компонент для отображения и масштабирования графиков и поднатаскать себя в области графического отображения.
На мой взгляд такая цель/постановка неудачна. Рисование руками саедется к множеству вызовов небольшого числа ф-ций типа MoveTo/LineTo, т.е. рутинной работе - право, задействовать готовую либу здесь гораздо более уместно (даже для такого закоренелого велосипедиста как я  :))

А вот написать компонент "график мини-модулятор" может и есть смысл, в моих задачах он часто нужен. Если интересно, расскажу больше

Edit:
PPS посмотрел ваш плот - интересно. Но увы. У меня примерно 40 тысяч на 60 тысяч график должен быть по осям. Собственно велосипеды других, в том числе и ваш под это не особо подойдут. Тут нужен свой, оптимизированный. 
Не Вы ли неоднократно упоминали про богатырскую силу model-view подхода? Ну так примените. Скармливайте стандартному графику не оригинальные точки (которых слишком много) а их упрощенное представление, на то и модель


Название: Re: Написание собственного графика.
Отправлено: Bepec от Сентябрь 16, 2013, 13:54
Собственно в том и проблема :)
Велосипеды идут в смысле - дайте точек, а мы нарисуем.

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

PS если вы не успели или не читали мою архитектуру, то она подозрительно похожа на model - view.


Название: Re: Написание собственного графика.
Отправлено: m_ax от Сентябрь 16, 2013, 14:06

PPS посмотрел ваш плот - интересно. Но увы. У меня примерно 40 тысяч на 60 тысяч график должен быть по осям.

Что значит 40 на 60 тысяч график? График (кривая) представляется вектором, элементы которого двумерная точка (QPointF, например) - значение x и y, соответственно.

Сейчас ради интереса зарядил две кривых по 100 тысяч точек в каждой. На моём древнем железе особых тормозов не обнаружил..


Название: Re: Написание собственного графика.
Отправлено: m_ax от Сентябрь 16, 2013, 14:08
Да, архитектура Model/View для этого дела - очень хорошо.


Название: Re: Написание собственного графика.
Отправлено: Bepec от Сентябрь 16, 2013, 14:38
Ну так влегкую чуть поменял ваш пример - у меня полграфика черные и думает при ресайзе эм... секунды 3-5. ( i5 )

Мож я что-т не так настроил? :P Не скинете код  в личку, дабы темку не сорить.


Название: Re: Написание собственного графика.
Отправлено: m_ax от Сентябрь 16, 2013, 15:59
Скинул..
Пол графика чёрные - это надо сетку по оси x по разреженней сделать, скорее всего.
Тормоза все - из-за самой отрисовки точек. В архитектуре MVC можно задавать делегату, например, максимальное число точек по "x", н.т. минимальное и максимальное разрешение, а вьюха, основываясь на этих данных делегата, отображала бы уже просеянные данные..
     


Название: Re: Написание собственного графика.
Отправлено: Bepec от Сентябрь 16, 2013, 16:56
Получил, смотрю.

Собственно часть вашего проекта я слямзю и буду разбираться потихоньку :P
Часть отображения меня привлекла. Облечь это в model-view и может что-нить да выйдет полезное для меня )


Название: Re: Написание собственного графика.
Отправлено: Bepec от Сентябрь 17, 2013, 08:39
Up. Никто литературки не посоветует? :(


Название: Re: Написание собственного графика.
Отправлено: Bepec от Сентябрь 17, 2013, 15:27
Up.

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

Я так понимаю, это нормальное поведение, вот только оно мне не нравится :) Нет никаких мыслей по этому поводу?

PS подумал немного - нормальное поведение для точечного графика. Возможно нужно будет добавить несколько вариантов отдачи данных.

PPS что быстрее - drawPoint, drawPolygon или drawPolyline?


Название: Re: Написание собственного графика.
Отправлено: Igors от Сентябрь 17, 2013, 16:45
Добрался до ещё одной проблемы, которая встречается и в вашей библиотеке. При рисовании графика по точкам, если следующая точка не входит в область рисования, то весь отрезок пропадает.

Я так понимаю, это нормальное поведение, вот только оно мне не нравится :) Нет никаких мыслей по этому поводу?
Просто рисовать +1 точку слева и справа, а clip сам отсечет. Из той же оперы: левая часть буквы (напр 30%) красным цветом, правая белым.  Как нарисовать?


Название: Re: Написание собственного графика.
Отправлено: Bepec от Сентябрь 17, 2013, 17:10
Так у меня свой clip :)

Собственно реализовано простейшее model-view.
View запрашивает данные и передаёт размер сцены, модель возвращает точки.

Собственно вопрос который возник - точки разделены большими промежутками. Модель содержит данные об имеющихся точках, которые разнесены где то на 100 тысяч по x/y. Если рисовать всё - умрёт программа :D ну и вопрос - на максимальном удалении видна огибающая - это красиво и понятно.

Начинаешь приближать допустим до 3 точек - получается хорошая огибающая, оканчивающаяся на 1 и 3 точке - терпимо.
Приближаешь, желая увидеть что-то в промежутке между точками - а там пустота, ибо уже ни одна точка в этот промежуток не попадает.

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

Какие предложения есть у вас? 

to Igors: ответ содержится в вопроса, clip отрежет необходимые %.


Название: Re: Написание собственного графика.
Отправлено: m_ax от Сентябрь 17, 2013, 17:14
Цитировать
Собственно вопрос который возник - точки разделены большими промежутками. Модель содержит данные об имеющихся точках, которые разнесены где то на 100 тысяч по x/y. Если рисовать всё - умрёт программа Веселый ну и вопрос - на максимальном удалении видна огибающая - это красиво и понятно.

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


Название: Re: Написание собственного графика.
Отправлено: Bepec от Сентябрь 17, 2013, 17:20
Ну я пока масштабированием не особо занимался, но не особо катит :D При любом приближении если крайняя точка уходит - получается обрубок висящий в воздухе. Идеально, если две точки попадут точно на края :) Но увы.


Название: Re: Написание собственного графика.
Отправлено: Igors от Сентябрь 17, 2013, 17:54
to Igors: ответ содержится в вопроса, clip отрежет необходимые %.
Я ничего у Вас не спрашивал, прочитайте мой ответа  :)  Ось малюнок

 A*---------|-----------------|------------*B
 
Проводите линию начиная с последней слева (за границами отображаемой области) и кончая первой справа. Это гарантирует что отрезок будет нарисован


Название: Re: Написание собственного графика.
Отправлено: Bepec от Сентябрь 17, 2013, 18:58
Ну собственно опишу подробнее проблему.

Модель отдаёт данные в виде массива списков точек. Кривых можно сказать.
В результате получается то, что на картинке, только без линий, одни большие точки. (одна кривая там)

Если модель при приёме данных сгенерит соединительные линии, массив передаваемых данных возрастёт в разы.

9 точек на рисунке. Если провести линии, получается примерно 280 тысяч точек.
Цитировать
280 000 = 8 (кол-во отрезков) * 30000 (среднее по Y) + 40000 (максимум по X)

Собственно проблема :D

Возьмём масштаб аля красный прямоугольник. Модель должна расчитать принадлежность трёх точек к прямоугольнику и так найти и передать дополнительно точки соприкосновения кривых к стенкам прямоугольника.  У меня пока никаких мыслей как это сделать нет.

А так как кривых может быть много (в моём проекте максимум 5), то это серьёзно меня озадачивает.




Название: Re: Написание собственного графика.
Отправлено: Igors от Сентябрь 17, 2013, 19:35
Возьмём масштаб аля красный прямоугольник. Модель должна расчитать принадлежность трёх точек к прямоугольнику и так найти и передать дополнительно точки соприкосновения кривых к стенкам прямоугольника.  У меня пока никаких мыслей как это сделать нет.

А так как кривых может быть много (в моём проекте максимум 5), то это серьёзно меня озадачивает.
Код
C++ (Qt)
void GetDrawIndices( const std::vector <QPointF> & data,
                              float drawMin,     // левое значение X (начало диапазона просмотра)                              
                              float drawMax,    // правое
                              int index[2] )
{
index[0] =  std::lower_bound(data.begin(), data.end(), QPointF(drawMin, -1000)) - data.begin();
index[1] =  std::upper_bound(data.begin(), data.end(), QPointF(drawMax, -1000)) - data.begin();
if (index[0]) --index[0];
if (index[1]) < data.size()) ++index[1];
}  
 
Дальше просто рисуете точки от index[0] до index[1], в цикле for или как нравится


Название: Re: Написание собственного графика.
Отправлено: Bepec от Сентябрь 17, 2013, 19:57
Завтра посмотрю, а на вид всё довольно просто. Хотя чуток и непонятно :)

Я так понимаю мы ищем наименьшее и наибольшее значение в точках. Но ведь мне эти точки неизвестны. У меня в исходных данных только чёрные точки жирные на рисунке.


Название: Re: Написание собственного графика.
Отправлено: _OLEGator_ от Сентябрь 17, 2013, 21:11
Еще надо чтобы корректно отрабатывались такие случаи (черный прямоугольник - область видимости):


Название: Re: Написание собственного графика.
Отправлено: Bepec от Сентябрь 17, 2013, 22:04
offtop: никто не посоветует где и про что почитать для так называемого "сжатия" графика? Что-то типа усреднения?


Название: Re: Написание собственного графика.
Отправлено: Igors от Сентябрь 18, 2013, 05:44
Еще надо чтобы корректно отрабатывались такие случаи (черный прямоугольник - область видимости):
Их не нужно специально отрабатывать - просто установить clip на прямоугольник и тупо рисовать все что попало туда по X + запаска по 1 точке слева/справа

offtop: никто не посоветует где и про что почитать для так называемого "сжатия" графика? Что-то типа усреднения?
Не встречал такой теории, возможно потому что с этим проблем не возникает. Если в пиксель (по X) попадает 2 или более значений, то варианты

- вывести среднее
- вывести случайное (из попавших)
- вывести вертикальную линию  (min - max), можно со своим антиалиасом

Начните с простого среднего а там видно будет


Название: Re: Написание собственного графика.
Отправлено: Bepec от Сентябрь 18, 2013, 06:57
Кхм. Я ж уже расписал почему clip не катит - точки могут быть разделены очень большим расстоянием.
И опять повторюсь - пытаюсь рисование привести к model-View. Возможно у меня проблемы эти из-за архитектуры, но я их и пытаюсь решить. А вы мне молвите - рисуй 100к точек а clip отсечёт всё. (но я попробую ваш совет, хотя это с model-view не канает)

И вопрос про сжатие - как вы поступите, если вот на картинке в 300 на 300 пикселей (мой аттач выше) нужно разместить 60000 точек млиа :D Как их нарисовать, чтобы не тормозило всё?

Если рисовать каждую точку а потом scale - время ожидания равно 3-4 секундам. На каждую перерисовку.

Усреднение как раз и подразумевает под собой взятие среднего. (это я попытаюсь сделать сегодня)

Взятие случайного - что у нас получится при насыщенности 200 точек на пиксель - слишком большая погрешность.

Pixmap в качестве полотна ускоряет примерно на 2 секунды, но это всё равно очень много.



Название: Re: Написание собственного графика.
Отправлено: Old от Сентябрь 18, 2013, 08:02
И вопрос про сжатие - как вы поступите, если вот на картинке в 300 на 300 пикселей (мой аттач выше) нужно разместить 60000 точек млиа :D Как их нарисовать, чтобы не тормозило всё?
Нужно выбрать 300 значений из 60000. :)
Считаем шаг и берем значения из модели с учетом этого шага:
Код
C++ (Qt)
int step = 60000 / 300;
for( int x = 0; x < 300; ++x )
{
   int y = data[ x * step ];
   setPixel( x, y, color);
}
 


Название: Re: Написание собственного графика.
Отправлено: _OLEGator_ от Сентябрь 18, 2013, 08:43
Точки, которые попадут в один пиксель, с учетом масштаба, нужно отсеивать и брать из них одну.


Название: Re: Написание собственного графика.
Отправлено: Igors от Сентябрь 18, 2013, 08:44
Кхм. Я ж уже расписал почему clip не катит - точки могут быть разделены очень большим расстоянием.
И опять повторюсь - пытаюсь рисование привести к model-View. Возможно у меня проблемы эти из-за архитектуры, но я их и пытаюсь решить. А вы мне молвите - рисуй 100к точек а clip отсечёт всё. (но я попробую
Помню Вашему другу Андрюше тоже раз 5 пытался втолковать простейшую вещь - ни в какую, кончилось тем что он мне нахамил :) Поэтому последний раз

Любая "графика" имеет "регион" вывода. Регион делит все множество пикселей на 2 части - тех что в него входят и нет. Если пиксель не принадлежит текущему региону - он не будет изменен текущим рисованием. Вам это и нужно чтобы не возиться с обрезками - просто включить в рисование 2 крайние точки - и все дела. Ну конечно сделать setClipRect

Нужно выбрать 300 значений из 60000. :)
Считаем шаг и берем значения из модели с учетом этого шага:
Код
C++ (Qt)
int step = 60000 / 300;
for( int x = 0; x < 300; ++x )
{
   int y = data[ x * step ];
   setPixel( x, y, color);
}
 
Это если шаг по X одинаков и хранятся только Y. Для 2 координат чуть сложнее - но тоже в рамках 9-го класса. Напр

Код
C++ (Qt)
inline QPointF ScalePt( const QPointF & src, qreal scaleX, qreal scaleY )
{
return QPointF(src.x() * scaleX, src.y() * scaleY);  
}
 
void Draw( QPainter & painter, const QPointF * pt, int count, qreal scaleX, qreal scaleY )
{
QPointF prv = ScalePt(pt[0], scaleX, scaleY);   // всегда тянем линию от первой
for (int i = 1; i < count - 1; ++i) {
 QPointF nxt = ScalePt(pt[i], scaleX, scaleY);  
 if ((nxt - prv).x() < 1.0f) continue;
 painter.drawLine(prv, nxt);
 prv = nxt;
}  
 
painter.drawLine(prv, ScalePt(pt[count - 1], scaleX, scaleY);  // всегда тянем линию к последней
}
 


Название: Re: Написание собственного графика.
Отправлено: Bepec от Сентябрь 18, 2013, 11:39
to Igors:
Во 1 андрюша мне не друг, не враг, а так. Он всем хамил.
Во 2 - я прекрасно понимаю, что если рисовать на обычном виджете в paintEvent, то рисование всех точек с clip'ом вполне вариант. Это НЕ вариант, когда я хочу использовать model-view реализацию.

Проблема в том, что у меня есть только точки. Точки. Не отрезки, которые я хочу показать пользователю, не непрерывная линия точек, а точки. Обыкновенные, разделённые пустотой.


View запрашивает данные
Код:
QList<кривые, хранящих точки>model_->getData(QRect ); //QRect - область видимости View.

Model отдаёт точки кривых, которые принадлежат данному rect.

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

В предложенном вами варианте вы предлагаете отдавать +-1 точку с края и рисовать линии, а их уже отрежет clip. Так?



Название: Re: Написание собственного графика.
Отправлено: m_ax от Сентябрь 18, 2013, 11:53

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

Ну они легко считаются.. Формулу вывести проблема?

(если я правильно понял, что нужно..)


Название: Re: Написание собственного графика.
Отправлено: xokc от Сентябрь 18, 2013, 13:34
PPS что быстрее - drawPoint, drawPolygon или drawPolyline?
См. тут http://www.prog.org.ru/topic_11954_0.html (http://www.prog.org.ru/topic_11954_0.html)


Название: Re: Написание собственного графика.
Отправлено: Igors от Сентябрь 18, 2013, 14:40
Во 2 - я прекрасно понимаю, что если рисовать на обычном виджете в paintEvent, то рисование всех точек с clip'ом вполне вариант.
Да причем тут ВСЕ точки ??? В приведенном выще коде рисуется по 1 точке на пиксель, прореживайте как хотите, просто добавьте края.

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

И тут возникает вопрос - нужны крайние точки (на аттаченном рисунке, это области красного прямоугольника, закрашенные зелёным). Их нет в данных. Вообще нет. Их нужно рассчитать. Вот это у меня и вызывает проблему.
Находите 2 точки (p0, p1) между которыми граница x (см lower_bound выше)
Код
C++ (Qt)
QPointF margin(x, (p1.y() * (x - p0.x()) + p0.y() * (p1.x() - x)) / (p1.x() - p0.x()));
 
Это просто линейная интерполяция, к сожвлению малопонятная из-за дурацкой концептуальности (за private x, y убивать надо)

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

View запрашивает данные
Код:
QList<кривые, хранящих точки>model_->getData(QRect ); //QRect - область видимости View.

Model отдаёт точки кривых, которые принадлежат данному rect.
Нет. Задачи модели - хранение данных, она даже не должна знать что такое QRect. View определяет диапазон X подлежащий отображению и запрашивает у модели напр подмассив (константный) значений которые туда вошли (см пример выше).  Получив этот диапазон View его рисует (др пример выше)


Название: Re: Написание собственного графика.
Отправлено: Bepec от Сентябрь 18, 2013, 16:12
to xokc: спасибо, посмотрю.

to Igors:
1) вы читали сообщение в котором приаттачена картинка?
2) см. п. 1
3) не доходит пока о чем это. Сегодня нет времени пробовать, возможно завтра.
4) View запрашивает данные по индексу. Индексом у меня служит QRect. Это тот же самый диапазон или я вас не понимаю.
В модели хранятся точки (x,y). Модель отдаёт те точки, которые попадают в видимый диапазон, определённый QRect (x, y, width, height).

PS и прочитайте пожалуйста сообщение, которое над картинкой. Там описано какие данные хранятся и "ху из ху" на рисунке.


Название: Re: Написание собственного графика.
Отправлено: Igors от Сентябрь 18, 2013, 17:15
1) вы читали сообщение в котором приаттачена картинка?

PS и прочитайте пожалуйста сообщение, которое над картинкой. Там описано какие данные хранятся и "ху из ху" на рисунке.
Читал, но ход Вашей мысли мне недоступен

Модель отдаёт данные в виде массива списков точек. Кривых можно сказать.
В результате получается то, что на картинке, только без линий, одни большие точки. (одна кривая там)

Если модель при приёме данных сгенерит соединительные линии, массив передаваемых данных возрастёт в разы.

9 точек на рисунке. Если провести линии, получается примерно 280 тысяч точек.
Цитировать
280 000 = 8 (кол-во отрезков) * 30000 (среднее по Y) + 40000 (максимум по X)
Зачем же создавать 280K точек если можно всего 8 точек соединить отрезками  ???



Название: Re: Написание собственного графика.
Отправлено: Bepec от Сентябрь 18, 2013, 20:51
Ещё одна попытка вам объяснить - в начале есть только точки. Нет отрезков. View запрашивает точки, входящие в видимый rect.
И вот тут вопрос - как лучше возвращать...

PS если вы не понимаете того сообщения, то видимо мы с вами говорим на разных языках. Это конечно плохо, но не смертельно.


Название: Re: Написание собственного графика.
Отправлено: m_ax от Сентябрь 18, 2013, 21:27
Кажется логичным, с т.з. архитектуры иметь саму модель данных, которая содержит информацию о всех кривых (легенда, вектор точек, уникальный идентификатор каждой кривой и т.д.), смотрелка (базовая), которая умеет их отображать и которая через прокси модель отображает эти кривые. Прокси модель должна отдавать смотрелки уже просеянные данные из самой модели. 
Делегаты для смотрелки, которые настраивают вид отображения каждой кривой и вообще всякие там режимы отображения данных (ну типа чтоб можно было переключаться в логарифмический масштаб и т.д. и т.п..)     

Сейчас я, например, вообще не имею представления (исходя из прочитанного) о текущей архитектуре этого плотера.. От того, возможно, все непонималки)


Название: Re: Написание собственного графика.
Отправлено: Igors от Сентябрь 19, 2013, 08:47
Ещё одна попытка вам объяснить - в начале есть только точки. Нет отрезков.
...
PS если вы не понимаете того сообщения, то видимо мы с вами говорим на разных языках. Это конечно плохо, но не смертельно.
Хотите рисовать только точки (без линий) - рисуйте "как есть", не вставляйте никакх доп точек, так Вы только добавляете забот и себе  и пользователю. Становится сложно понять "что за точка", доп точки могут наползать на реальные и.т.п. Да, при большом увеличении будут пустоты, ну значит режим "точки" для такого масштаба не предназначен, надо включить рехим "линии + точки", вот и все

 
Кажется логичным, с т.з. архитектуры иметь саму модель данных, которая содержит информацию о всех кривых (легенда, вектор точек, уникальный идентификатор каждой кривой и т.д.), смотрелка (базовая), которая умеет их отображать и которая через прокси модель отображает эти кривые. Прокси модель должна отдавать смотрелки уже просеянные данные из самой модели. 
Делегаты для смотрелки, которые настраивают вид отображения каждой кривой и вообще всякие там режимы отображения данных (ну типа чтоб можно было переключаться в логарифмический масштаб и т.д. и т.п..)     
Модель, прокси-модель, делегат - зачем все эти навороты? Проще и лучше держать все точки в векторе - или др контейнере, вот и вся модель. View запрашивает видимый диапазон по X, он выдается в виде подмассива, или 2 итераторов, т.е. никакие промежуточные контейнеры не нужны. 

"Виртуальные точки" легко вставляются прямо в процедуру рисования (если уж такое неуемное желание делать так). Там писать минут 15 (если не городить и не умничать  :))



Название: Re: Написание собственного графика.
Отправлено: Bepec от Сентябрь 19, 2013, 10:03
1) Да, я с вами согласен по поводу двух режимов.

2) Не встраиваются они в процедуру рисования. Тут уже нужно определиться, что отдаёт model.

PS к сожалению пока очень плотный график - не могу этим заняться.


Название: Re: Написание собственного графика.
Отправлено: Igors от Сентябрь 19, 2013, 10:53
2) Не встраиваются они в процедуру рисования. Тут уже нужно определиться, что отдаёт model.
Да отчего же не встраиваются?

Код
C++ (Qt)
struct BepecView {
 void Draw1Point( const QPointF & src ) const;  // рисует 1 точку, src в координатах модели
 void DrawPoints( const QPointF * pt, int count );
 
 qreal mX0, mX1, mY0, mY1;         // размер окна в координатах модели
 qreal mScaleX, mScaleY;    // масштабы по осям
 ..
};
 
void BepecView::DrawPoints( const QPointF * pt, int count );
{
QPointF prv;
Draw1Point(pt[0]);   // всегда рисуем первую точку
for (int i = 1; i < count; ++i) {
 const QPointF & nxt = pt[i];
 qreal prvX = prv.x();
 qreal prvY = prv.y();
 qreal nxtX = nxt.x();
 qreal nxtY = nxt.y();
 if (nxtX - prvX < 1.0f / mScaleX) continue;  // прореживание
 
// пересечение слева
 if (prvX <= mX0 && nxtX >= mX0)
  Draw1Point(LerpX(prv, nxt, mX0));
 
// пересечение сверху
  if (qMin(prvY, nxtY) <= mY1 && qMax(prvY, nxtY) >= mY1)
   Draw1Point(LerpY(prv, nxt, mY1));
 
// пересечение снизу
  if (qMin(prvY, nxtY) <= mY0 && qMax(prvY, nxtY) >= mY0)
   Draw1Point(LerpY(prv, nxt, mY0));
 
// пересечение справа
 if (prvX <= mX1 && nxtX >= mX1)
  Draw1Point(LerpX(prv, nxt, mX1));
 
// рисуем саму точку и делаем ее текущей
 Draw1Point(nxt);
 prv = nxt;
}  
 
// всегда рисуем последнюю точку
if (prv != pt[count - 1])
 Draw1Point(pt[count - 1]);  
}
 
LerpX(Y) как было выше. Вот и все, чего мудрить и совать в модель ф-ционал view?


Название: Re: Написание собственного графика.
Отправлено: zzzseregazzz от Сентябрь 26, 2013, 11:00
А что вы делаете, если надо построить график из 1-й точки ? Куда ее поместить? Мне кажется, лучше всего по центру.
Qwt такие графики или совсем не отображает, или помещает точку куда-то на край, где ее не видно. Есть ли метод, чтобы поместить одну точку в центр?


Название: Re: Написание собственного графика.
Отправлено: Vamireh от Октябрь 01, 2013, 21:31
А что вы делаете, если надо построить график из 1-й точки ? Куда ее поместить? Мне кажется, лучше всего по центру.
Qwt такие графики или совсем не отображает, или помещает точку куда-то на край, где ее не видно. Есть ли метод, чтобы поместить одну точку в центр?

Я использую свой класс для графиков. Насчет одной точки - не проверял, но по идеи будет тоже самое, что и линия, параллельная абциссе. В этом случае у меня вертикальный диапазон увеличивается на 5% в обе стороны и прямая становится посередине. Если прямая f(x)=0.0, то вертикальный диапазон становится [-0.5;0.5] с тем же эффектом


Название: Re: Написание собственного графика.
Отправлено: Bepec от Ноябрь 19, 2013, 14:33
Идея заглохла в связи проблем со здоровьем и пока погружается в анабиоз. Увы.


Название: Re: Написание собственного графика.
Отправлено: sergek от Ноябрь 19, 2013, 21:00
Выздоравливайте. Есть функция рисования трехмерных поверхностей. Писал давно, на C++Builder. Но там есть Брезенхем, вращение, масштабирование. Книжку уже не помню, кажется, Машинная графика, но очень старая. Могу выслать пример использования, если скажете, куда.