Добрый день!
Вот подумываю написать по фану программу, генерирующая эти фигуры. Возникли 3 вопроса:
1. Какой класс лучше использовать? Здесь придется очень часто обновлять экран - 0-500ГЦ. Пейнтер, наверное, не подойдет.
2. С помощью чего обновлять экран. Можно отталкиваться от QTimer. Но рационально ли это?
3. Как сделать остаточный след на экране (как в осциллографе, даже если двигать точку медленно, то все равно будет заметна светимость следа)?
Заранее СПС.))
1. обновления в Гцах - это уже для монитора вопрос, в мс сколько?
Если не QPainter - советую писать на ассемблере или уж лучше напрямую работать с видеокарточкой Ну или забить на Qt и юзать DirectX/OGL, шейдеры и т.п.
Вопрос - что это за фигуры в принципе?
2. обновлять экран - можно по таймеру, это рациоально. Можно - тупо апдейтить и апдейтить в конце каждой перерисовки.
3. двойная буферизация как возможный вариант. Хотя это к вопросу №1 больше, т.к. далее - дело техники
Гц - это я вспоминаю значения, стоявшие на осциллографе у нас, когда была практическая работа по данной теме. Т.е. в данном случае - герцы - значения на осциллографе.
Ну я не такой крутой кодер, чтобы уж прям с видеокартой напрямую работать))) Лучше средствами Qt. А OpenGL на Qt может подойти? Или для таких дел QPainter тоже может сгодиться. Я просто почему спрашиваю, потому вот сделаю через Пейнтер, а потом окажется, что можно было делать через другой класс, который подходит лучше.))
Вот ссылка: http://ru.wikipedia.org/wiki/Фигуры_Лиссажу. Тут написано лучше, чем скажу я.
я далек от осцилографов, но в графике имеют значения мс, а вот как вы их уже к герцам приложите - вопрос по области применения
OpenGL и Qt дружат отлично, но - здесь те же системы отрисовки, графика то 2Д и динамическая.
Тут как бы - а "другой" - это какой класс? QPainter - по сути основа всей отрисовки в Qt. Если не оно, то уже только в видеокарту лезть
Вначале переведите герцы нужные Вам в фпс, просчитайте скорость обработки одного кадра чисто математически - а потом уже начинайте реализацию логика отрисовки не сильно зависит от выбранного АПИ в данном случае, имхо.
никаких жутких ухищрений не нужно, компутер успеет такую фигуру нарисовать и в динамике
параметрически кривая задана
единственное, что надо сделать - задать инерцию люминофора. То есть просто точку гонять по кривой недостаточно - глаз не обманется. Надо запоминать шлейф на 1/24 секунды назад и отрисовывать эту линию
тактировать можно таймером этак 40...200 мс
А OpenGL? Или пейнтера с головой хватит?
QMainWindow, ты сначала с QPainter сделай что-нибудь, а там увидим
Привет всем!
Короч только что написал прогу. Все хорошо получилось, делал через QPainter. Единственное, что осталось - это след на экране. Как правильно сделать - не знаю. На данный момент, чтобы изображение отображалось, в paintEvent записал цикл с N = 200. Но это все же не след.
Вот тут говорили про буфер. Никогда не работал, не знаю как это работает. Какие классы хоть смотреть?
QMainWindow, используй вектор
std::vector<QLine>(200) trace_buffer;
организуй кольцо - заведи два итератора- один на начало следа, второй на конец
отрисовав ломаную линию (кстати, по любасу метод есть, чтобы цепь QLine вывести разом) , делай сдвиг, выкидывая из начала несколько звеньев. А новые добавляй в конец. Приоритет делай для конца - если кольцо полностью забито, то выкидывай начальные и добавляй новые в конец
можно ещё поиграться с градиентным цветом очередных линий (QLine), будет совсем как люминофор ))
Сделал через вектор на 200 элементов - тормознуто! При одной и той же частоте W цикл бегает по экрану много быстрее чем вектор.((
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)); //--либо точками.
}
}
Сделал, чтобы не писать оператора if, когда нужно удалять последний элемент, след же не бесконечный. Буфера - координаты точек следа по x и y. t - время.
могу прогу скинуть, код короткий
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)); //-- цикл
}
Вот: http://ifolder.ru/19986495
Код простой, подписывать ничего не стал, т.к. особо и нечего.))
QMainWindow, не открывается ссылка. Сделай проще - удали папки release и debug, да архивчик тут подвесь
QMainWindow, я скачал таки. Ищу драчовый напильник, доводить до ума )))
вообще то, плоттеры обычно делают в новом классе, так ГОРАЗДО УДОБНЕЕ. Но это переделывать я не буду - сам уж сделаешь
вот, что у меня вышло. Правда, кольцевой буфер содержит сейчас QPoint, но нпеределать в QLine не сложно - когда кладёшь очередную точку добавляй линию. Это сделай сам, а мне щас работать надо ))
приращение времени я в регулируемое окошко не выводил, тоже сам делай
m_t+=3;//dt;
Спасибо, а где собственно прикрепленный архив? Не видно что-то...
QMainWindow, хм, я , видать, забыл кнопочку нажать. А потом форум был в дауне.
С собой нету проекта, завтра с работы скину
ха, я понял, почему не прицепился файл. Дурацкое ограничение - использовать только зип. А у меня в раре был
Тему разделил: http://www.forum.crossplatform.ru/index.php?showtopic=5856
Спасибо за прогу, посмотрел.
Обнаружился интересный феномен (по крайней для меня).
Вот код:
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();
}
QMainWindow, точно утверждать не могу, но, возможно, ты соединяешь сигнал со слотом ещё раз, следовательно таймер срабатывает с "дребезгом"
Делай контроль количества соединений. Или по кнопке "стоп" рассоединяй сигнал и слот
А ещё лучше - соединить один раз в конструкторе и больше не трогать
Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)