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

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

Страниц: 1 [2] 3   Вниз
  Печать  
Автор Тема: Написание собственного графика.  (Прочитано 21754 раз)
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



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

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

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

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

Arch Linux Plasma 5
Bepec
Гость
« Ответ #16 : Сентябрь 17, 2013, 17:20 »

Ну я пока масштабированием не особо занимался, но не особо катит Веселый При любом приближении если крайняя точка уходит - получается обрубок висящий в воздухе. Идеально, если две точки попадут точно на края Улыбающийся Но увы.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

to Igors: ответ содержится в вопроса, clip отрежет необходимые %.
Я ничего у Вас не спрашивал, прочитайте мой ответа  Улыбающийся  Ось малюнок

 A*---------|-----------------|------------*B
 
Проводите линию начиная с последней слева (за границами отображаемой области) и кончая первой справа. Это гарантирует что отрезок будет нарисован
Записан
Bepec
Гость
« Ответ #18 : Сентябрь 17, 2013, 18:58 »

Ну собственно опишу подробнее проблему.

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

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

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

Собственно проблема Веселый

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

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


Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #19 : Сентябрь 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 или как нравится
Записан
Bepec
Гость
« Ответ #20 : Сентябрь 17, 2013, 19:57 »

Завтра посмотрю, а на вид всё довольно просто. Хотя чуток и непонятно Улыбающийся

Я так понимаю мы ищем наименьшее и наибольшее значение в точках. Но ведь мне эти точки неизвестны. У меня в исходных данных только чёрные точки жирные на рисунке.
Записан
_OLEGator_
Гость
« Ответ #21 : Сентябрь 17, 2013, 21:11 »

Еще надо чтобы корректно отрабатывались такие случаи (черный прямоугольник - область видимости):
Записан
Bepec
Гость
« Ответ #22 : Сентябрь 17, 2013, 22:04 »

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

Сообщений: 11445


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

Еще надо чтобы корректно отрабатывались такие случаи (черный прямоугольник - область видимости):
Их не нужно специально отрабатывать - просто установить clip на прямоугольник и тупо рисовать все что попало туда по X + запаска по 1 точке слева/справа

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

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

Начните с простого среднего а там видно будет
Записан
Bepec
Гость
« Ответ #24 : Сентябрь 18, 2013, 06:57 »

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

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

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

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

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

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

Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



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

И вопрос про сжатие - как вы поступите, если вот на картинке в 300 на 300 пикселей (мой аттач выше) нужно разместить 60000 точек млиа Веселый Как их нарисовать, чтобы не тормозило всё?
Нужно выбрать 300 значений из 60000. Улыбающийся
Считаем шаг и берем значения из модели с учетом этого шага:
Код
C++ (Qt)
int step = 60000 / 300;
for( int x = 0; x < 300; ++x )
{
   int y = data[ x * step ];
   setPixel( x, y, color);
}
 
Записан
_OLEGator_
Гость
« Ответ #26 : Сентябрь 18, 2013, 08:43 »

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

Сообщений: 11445


Просмотр профиля
« Ответ #27 : Сентябрь 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);  // всегда тянем линию к последней
}
 
« Последнее редактирование: Сентябрь 18, 2013, 08:47 от Igors » Записан
Bepec
Гость
« Ответ #28 : Сентябрь 18, 2013, 11:39 »

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

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


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

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

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

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

Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



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


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

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

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

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

Arch Linux Plasma 5
Страниц: 1 [2] 3   Вверх
  Печать  
 
Перейти в:  


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