Russian Qt Forum
Сентябрь 30, 2024, 20:24 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 2 [3]   Вниз
  Печать  
Автор Тема: Написание собственного графика.  (Прочитано 21469 раз)
xokc
Птица говорун
*****
Offline Offline

Сообщений: 976



Просмотр профиля
« Ответ #30 : Сентябрь 18, 2013, 13:34 »

PPS что быстрее - drawPoint, drawPolygon или drawPolyline?
См. тут http://www.prog.org.ru/topic_11954_0.html
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #31 : Сентябрь 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 его рисует (др пример выше)
« Последнее редактирование: Сентябрь 19, 2013, 08:21 от Igors » Записан
Bepec
Гость
« Ответ #32 : Сентябрь 18, 2013, 16:12 »

to xokc: спасибо, посмотрю.

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

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

Сообщений: 11445


Просмотр профиля
« Ответ #33 : Сентябрь 18, 2013, 17:15 »

1) вы читали сообщение в котором приаттачена картинка?

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

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

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

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

Записан
Bepec
Гость
« Ответ #34 : Сентябрь 18, 2013, 20:51 »

Ещё одна попытка вам объяснить - в начале есть только точки. Нет отрезков. View запрашивает точки, входящие в видимый rect.
И вот тут вопрос - как лучше возвращать...

PS если вы не понимаете того сообщения, то видимо мы с вами говорим на разных языках. Это конечно плохо, но не смертельно.
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #35 : Сентябрь 18, 2013, 21:27 »

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

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

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #36 : Сентябрь 19, 2013, 08:47 »

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

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

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

Записан
Bepec
Гость
« Ответ #37 : Сентябрь 19, 2013, 10:03 »

1) Да, я с вами согласен по поводу двух режимов.

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

PS к сожалению пока очень плотный график - не могу этим заняться.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #38 : Сентябрь 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?
Записан
zzzseregazzz
Гость
« Ответ #39 : Сентябрь 26, 2013, 11:00 »

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

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

Я использую свой класс для графиков. Насчет одной точки - не проверял, но по идеи будет тоже самое, что и линия, параллельная абциссе. В этом случае у меня вертикальный диапазон увеличивается на 5% в обе стороны и прямая становится посередине. Если прямая f(x)=0.0, то вертикальный диапазон становится [-0.5;0.5] с тем же эффектом
Записан
Bepec
Гость
« Ответ #41 : Ноябрь 19, 2013, 14:33 »

Идея заглохла в связи проблем со здоровьем и пока погружается в анабиоз. Увы.
Записан
sergek
Гипер активный житель
*****
Offline Offline

Сообщений: 872


Мы должны приносить пользу людям.


Просмотр профиля
« Ответ #42 : Ноябрь 19, 2013, 21:00 »

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

Qt 5.13.0 Qt Creator 5.0.1
Win10, Ubuntu 20.04
Страниц: 1 2 [3]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.104 секунд. Запросов: 23.