Qt анимация движения точки по заданной траектории
Суть вопроса в том, что я не совсем понимаю как вообще сделать анимацию движения точки по траектории. Был уже похожий вопрос тут Анимация перемещения точки по траектории в Qt, но так и не понятно как мне это осуществить. Вообще задача состоит из того, что нам нужно запустить анимацию движения точки по заданной траектории (к примеру синуса) и это траектория должна оставлять след когда точка пройдет по ней. Подскажите пожалуйста, как в qt это можно сделать. Хотелось бы использовать QGraphicsScene если это возможно.
Собственно, я сделал через QGraphicsScene отрисовку анимации движения точки, мне осталось сделать отрисовку траектории ее передвижения. Была мысль записывать в условный QVector vec каждую точку, а потом отрисовывать ее через MainWindow::paintEvent, но к сожалению ничего не выходит. Возможно есть мысли как сделать отрисовку траектории движения точки. Ниже код H:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsItem>
#include <QGraphicsEllipseItem>
#include <QTimer>
#include <QVector>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE;
class FalCirc: public QGraphicsEllipseItem{
public:
FalCirc(int xps, int yps);
void advance(int phase);
QVector<QPoint> vec;
private:
double tim;
int a;
int b;
int tn;
double tk, t;
double x0, y0, x1, y1;
};
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
QGraphicsScene* scene;
QTimer* anim_timer;
FalCirc* f;
// QWidget interface
protected slots:
void paintEvent(QPaintEvent *event);
};
#endif // MAINWINDOW_H
CPP:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <cmath>
#define CIRCLE_SIZE 5
#define CIRCLE_X 400
#define CIRCLE_Y 200
#define pi 3.14
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
scene = new QGraphicsScene(0, 0, 800, 600, this);
ui->graphicsView->setScene(scene);
scene->addRect(scene->sceneRect());
f = new FalCirc(CIRCLE_X+100,CIRCLE_Y+100);
// f = new FalCirc(CIRCLE_X+(R*(m+1)*cos(m*1)-h*cos((m+1)*1)),CIRCLE_Y+(R*(m+1)*sin(m*1)-h*sin((m+1)*1)));
scene->addItem(f);
anim_timer = new QTimer(this);
connect(anim_timer, SIGNAL(timeout()),scene, SLOT(advance()));
anim_timer->start(1000/60);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event)
QPainter p(this); // Создаём новый объект рисовальщика
p.setPen(QPen(Qt::red,1,Qt::SolidLine)); // Настройки рисования
p.drawEllipse(this->f->x(),this->f->y(),20,20);
}
FalCirc::FalCirc(int xps,int yps)
{
setRect(400,300,20,20);
setPos(400,200);
a=50;
b=75;
tn=0;
tk= 4 * pi;
x0 = CIRCLE_X +100;
y0 = CIRCLE_Y +100;
}
void FalCirc::advance(int phase)
{
if(phase){
t+=0.01;
x1=(a+b)*cos(t)-a*cos(((a+b)*t)/a);
y1=(a+b)*sin(t)-a*sin(((a+b)*t)/a);
vec.push_back(QPoint(x1,y1));
this->setRect(x1,y1,5,5);
}
}
Ответы (2 шт):
Вот рабочий вариант анимации движения точки из верхнего угла по диагонали (бесконечно) mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QTimer>
#include <QGraphicsEllipseItem>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
protected slots:
void onTimeout();
private:
QGraphicsScene* _scene;
QGraphicsView* _view;
QTimer* _timer;
QGraphicsEllipseItem* _point;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include <QVBoxLayout>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
_scene = new QGraphicsScene(0, 0, 800, 600, this);
_scene->addRect(_scene->sceneRect());
_view = new QGraphicsView;
_view->setScene(_scene);
QVBoxLayout* mainLayout = new QVBoxLayout;
mainLayout->addWidget(_view);
QWidget* mainWidget = new QWidget;
mainWidget->setLayout(mainLayout);
this->setCentralWidget(mainWidget);
_point = new QGraphicsEllipseItem(0, 0, 10, 10);
_scene->addItem(_point);
_timer = new QTimer(this);
connect(_timer, &QTimer::timeout, this, &MainWindow::onTimeout);
_timer->start(100);
}
MainWindow::~MainWindow()
{
}
void MainWindow::onTimeout()
{
QPointF oldPos = _point->pos();
QPointF newPos = QPointF(_point->pos().x() + 10, _point->pos().y() + 10);
_point->setPos(newPos);
QGraphicsLineItem* line = new QGraphicsLineItem (QLineF(oldPos, newPos));
_scene->addItem(line);
}
В общем получился такой код. Спасибо всем из коментов, особенно e-n-shirokov!
.h
class FalCirc: public QGraphicsEllipseItem{
public:
FalCirc(QGraphicsScene* parent);
void advance(int phase);
QGraphicsScene* main_widg;
private:
double t;
double x0, y0, x1, y1;
double R;
double m;
double h;
};
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
QGraphicsScene* scene;
QTimer* anim_timer;
FalCirc* f;
};
.Cpp
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
scene = new QGraphicsScene(0, 0, 800, 600, this);
ui->graphicsView->setScene(scene);
scene->addRect(scene->sceneRect());
f = new FalCirc(scene);
scene->addItem(f);
anim_timer = new QTimer(this);
connect(anim_timer, SIGNAL(timeout()),scene, SLOT(advance()));
anim_timer->start(1000/60);
}
MainWindow::~MainWindow()
{
delete ui;
}
FalCirc::FalCirc(QGraphicsScene* parent)
{
main_widg = parent;
setRect(400,300,20,20);
t=0; R=100; m=0.2; h=10;
}
void FalCirc::advance(int phase)
{
if(phase){
t+=0.1;
x1=((R*(m+1))*(cos(m*t)))-(h*(cos((m+1)*t)));
y1=((R*(m+1))*(sin(m*t)))-(h*(sin((m+1)*t)));
x0=x1;
y0=y1;
main_widg->addLine(x0+400,y0+300,x1+400,y1+300);
this->setPos(x1,y1);
}
}
