Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Фигуры Лиссажу
Форум на CrossPlatform.RU > Библиотеки > Qt > Qt Система рисования. Печать
QMainWindow
Добрый день!
Вот подумываю написать по фану программу, генерирующая эти фигуры. Возникли 3 вопроса:
1. Какой класс лучше использовать? Здесь придется очень часто обновлять экран - 0-500ГЦ. Пейнтер, наверное, не подойдет.
2. С помощью чего обновлять экран. Можно отталкиваться от QTimer. Но рационально ли это?
3. Как сделать остаточный след на экране (как в осциллографе, даже если двигать точку медленно, то все равно будет заметна светимость следа)?

Заранее СПС.))
ufna
1. обновления в Гцах - это уже для монитора вопрос, в мс сколько?

Если не QPainter - советую писать на ассемблере или уж лучше напрямую работать с видеокарточкой :) Ну или забить на Qt и юзать DirectX/OGL, шейдеры и т.п.

Вопрос - что это за фигуры в принципе?

2. обновлять экран - можно по таймеру, это рациоально. Можно - тупо апдейтить и апдейтить в конце каждой перерисовки.

3. двойная буферизация как возможный вариант. Хотя это к вопросу №1 больше, т.к. далее - дело техники
QMainWindow
Гц - это я вспоминаю значения, стоявшие на осциллографе у нас, когда была практическая работа по данной теме. Т.е. в данном случае - герцы - значения на осциллографе.
Ну я не такой крутой кодер, чтобы уж прям с видеокартой напрямую работать))) Лучше средствами Qt. А OpenGL на Qt может подойти? Или для таких дел QPainter тоже может сгодиться. Я просто почему спрашиваю, потому вот сделаю через Пейнтер, а потом окажется, что можно было делать через другой класс, который подходит лучше.))
Вот ссылка: http://ru.wikipedia.org/wiki/Фигуры_Лиссажу. Тут написано лучше, чем скажу я.
ufna
я далек от осцилографов, но в графике имеют значения мс, а вот как вы их уже к герцам приложите - вопрос по области применения

OpenGL и Qt дружат отлично, но - здесь те же системы отрисовки, графика то 2Д и динамическая.

Тут как бы - а "другой" - это какой класс? :) QPainter - по сути основа всей отрисовки в Qt. Если не оно, то уже только в видеокарту лезть :)

Вначале переведите герцы нужные Вам в фпс, просчитайте скорость обработки одного кадра чисто математически - а потом уже начинайте реализацию :) логика отрисовки не сильно зависит от выбранного АПИ в данном случае, имхо.
Алексей1153
никаких жутких ухищрений не нужно, компутер успеет такую фигуру нарисовать и в динамике :)

параметрически кривая задана


единственное, что надо сделать - задать инерцию люминофора. То есть просто точку гонять по кривой недостаточно - глаз не обманется. Надо запоминать шлейф на 1/24 секунды назад и отрисовывать эту линию

тактировать можно таймером этак 40...200 мс
Litkevich Yuriy
Цитата(QMainWindow @ 19.10.2010, 1:28) *
а потом окажется, что можно было делать через другой класс, который подходит лучше.))
а другого в Qt нету. QPainter - рисовальщик всех примитивов

Цитата(QMainWindow @ 19.10.2010, 0:54) *
2. С помощью чего обновлять экран. Можно отталкиваться от QTimer. Но рационально ли это?
Цитата(QMainWindow @ 19.10.2010, 0:54) *
3. Как сделать остаточный след на экране (как в осциллографе, даже если двигать точку медленно, то все равно будет заметна светимость следа)?
полностью имитировать работу осциллографа на компьютере не стоит.
Для начала просто рисуй, пусть накладываются. Если дальше захочешь развивать программу там и видно будет.

П.С. где-то у меня была программка на дельфи 4, которая именно фигуры Лисажу рисовала
QMainWindow
А OpenGL? Или пейнтера с головой хватит?
Алексей1153
QMainWindow, ты сначала с QPainter сделай что-нибудь, а там увидим :)
QMainWindow
Привет всем!
Короч только что написал прогу. Все хорошо получилось, делал через QPainter. Единственное, что осталось - это след на экране. Как правильно сделать - не знаю. На данный момент, чтобы изображение отображалось, в paintEvent записал цикл с N = 200. Но это все же не след.
Вот тут говорили про буфер. Никогда не работал, не знаю как это работает. Какие классы хоть смотреть? :)
Алексей1153
QMainWindow, используй вектор

std::vector<QLine>(200) trace_buffer;

организуй кольцо - заведи два итератора- один на начало следа, второй на конец


отрисовав ломаную линию (кстати, по любасу метод есть, чтобы цепь QLine вывести разом) , делай сдвиг, выкидывая из начала несколько звеньев. А новые добавляй в конец. Приоритет делай для конца - если кольцо полностью забито, то выкидывай начальные и добавляй новые в конец

можно ещё поиграться с градиентным цветом очередных линий (QLine), будет совсем как люминофор ))
QMainWindow
Сделал через вектор на 200 элементов - тормознуто! При одной и той же частоте W цикл бегает по экрану много быстрее чем вектор.((
kwisp
Цитата(QMainWindow @ 27.10.2010, 23:14) *
Сделал через вектор на 200 элементов - тормознуто!

код покажи?
как сделал?
QMainWindow
MainWindow::MainWindow()
{...
for(i=0; i<200; i++)
    {
        TraceBufferX.push_front(0);
        TraceBufferY.push_front(0);
    }
...
}

void MainWindow::Start()
{
    connect(timer, SIGNAL(timeout()), this, SLOT(NewFrame()));
    timer->start(10);
}

void MainWindow::NewFrame()
{
    TraceBufferX.pop_back();
    TraceBufferY.pop_back();
    TraceBufferX.push_front(R1*cos(w1*t+f1));
    TraceBufferY.push_front(R2*sin(w2*t+f2));
    t=t+dt;
    update();
}

void MainWindow::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.fillRect(2,2,506,506,QColor("#67b56c"));
    painter.setMatrix(QMatrix(1,0,0,-1,255,255));
    painter.setRenderHint(QPainter::Antialiasing, true);
    painter.setPen(QPen(QColor(255,0,0), 3, Qt::SolidLine, Qt::RoundCap));
    for(i=0; i<int(exp(w0/4.5)); i++)
    {
        painter.drawPoint(R1*cos(w1*(t-0.1*i)+f1), R2*sin(w2*(t-0.1*i)+f2)); //-- цикл
        //painter.drawLine(TraceBufferX.value(i), TraceBufferY.value(i), TraceBufferX.value(i-1), TraceBufferY.value(i-1)); //--либо линией рисовать
        //painter.drawPoint(TraceBufferX.value(i), TraceBufferY.value(i)); //--либо точками.
    }

}
kwisp
Цитата(QMainWindow @ 27.10.2010, 23:14) *
При одной и той же частоте W цикл бегает по экрану много быстрее чем вектор

этого в коде не увидел.
где вектор.?
подпиши все переменные.

Цитата(QMainWindow @ 27.10.2010, 23:32) *
for(i=0; i<200; i++)
{
TraceBufferX.push_front(0);
TraceBufferY.push_front(0);
}

вот это вообще странная запись
QMainWindow
Сделал, чтобы не писать оператора if, когда нужно удалять последний элемент, след же не бесконечный. Буфера - координаты точек следа по x и y. t - время.

могу прогу скинуть, код короткий
Алексей1153
QMainWindow, я ж предложил кольцо сделать. Размер вектора не меняется при этом. Это будет просто аналог статического массива на время жизни экземпляра вектора

а тормоза вот тут
    for(i=0; i<int(exp(w0/4.5)); i++)
    {
        painter.drawPoint(R1*cos(w1*(t-0.1*i)+f1), R2*sin(w2*(t-0.1*i)+f2)); //-- цикл
    }


вот, чем надо выводить полилинию из вектора-кольца :)

void QPainter::drawLines ( const QLine * lines, int lineCount )

Цитата(kwisp @ 28.10.2010, 1:41) *
могу прогу скинуть, код короткий

скинь. Только в 3 ночи возиться лично я не буду - я скоро спать ))
QMainWindow
Вот: http://ifolder.ru/19986495
Код простой, подписывать ничего не стал, т.к. особо и нечего.))
Алексей1153
QMainWindow, не открывается ссылка. Сделай проще - удали папки release и debug, да архивчик тут подвесь
Алексей1153
QMainWindow, я скачал таки. Ищу драчовый напильник, доводить до ума )))

вообще то, плоттеры обычно делают в новом классе, так ГОРАЗДО УДОБНЕЕ. Но это переделывать я не буду - сам уж сделаешь
Алексей1153
вот, что у меня вышло. Правда, кольцевой буфер содержит сейчас QPoint, но нпеределать в QLine не сложно - когда кладёшь очередную точку добавляй линию. Это сделай сам, а мне щас работать надо ))


приращение времени я в регулируемое окошко не выводил, тоже сам делай

m_t+=3;//dt;

QMainWindow
Спасибо, а где собственно прикрепленный архив? :) Не видно что-то...
Алексей1153
QMainWindow, хм, я , видать, забыл кнопочку нажать. А потом форум был в дауне.

С собой нету проекта, завтра с работы скину
Алексей1153
ха, я понял, почему не прицепился файл. Дурацкое ограничение - использовать только зип. А у меня в раре был
Litkevich Yuriy
Тему разделил: О прикрепленых файлах
QMainWindow
Спасибо за прогу, посмотрел.
Обнаружился интересный феномен (по крайней для меня).
Вот код:
void MainWindow::Start()
{
    connect(timer, SIGNAL(timeout()), this, SLOT(NewFrame()));
    timer->start(10);
}

и слот:
void MainWindow::NewFrame()
{
    Tr.remove(1);
    Tr.append(QLineF(R1*cos(w1*t+f1), R2*sin(w2*t+f2), R1*cos(w1*(t-dt)+f1), R2*sin(w2*(t-dt)+f2)));
    t=t+dt;
    update();
}

Это кнопка Старт. Прикол в том, что если на нее нажимать много раз, не меняя какие-либо параметры на панели, то точка на экране начнет двигаться быстрее и быстрее. Как это можно объяснить?
Алексей1153
QMainWindow, точно утверждать не могу, но, возможно, ты соединяешь сигнал со слотом ещё раз, следовательно таймер срабатывает с "дребезгом"

Делай контроль количества соединений. Или по кнопке "стоп" рассоединяй сигнал и слот

А ещё лучше - соединить один раз в конструкторе и больше не трогать :)
Litkevich Yuriy
Цитата(Алексей1153 @ 29.10.2010, 23:45) *
QMainWindow, точно утверждать не могу, но, возможно, ты соединяешь сигнал со слотом ещё раз, следовательно таймер срабатывает с "дребезгом"
Алексей, почти в яблочко. Только вместо дребезга картинка такая:
сколько раз сигнал соединён с одним и тем же слотом, столько раз он и будет доставлен в слот.

QMainWindow, Если MainWindow::Start() - это слот, то фкнцияю соединения вынеси туда, где создаётся объект таймера. А в этом слоте только запускай таймер
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2021 IPS, Inc.