QT:让图形沿着样条曲线匀速走。附源码求解决QAQ
在QT上能够根据鼠标点出的点算出cardinal样条曲线,然后让图形在上面走。
代码有点长,目前已经实现了根据鼠标所点出的点画出样条曲线。
但是不知道怎么让物件在图上匀速走。
如果做路径弧长参数化的话感觉略麻烦。
有一个同学把弧长分成非常多的小片段来移动近似于匀速了。
求详细解答感激不尽。。3天前才为了这个作业自学起QT的
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
resize(820,350);
pix = QPixmap(720,350);
btdraw = new QPushButton(this);
btdraw ->setText("生成路径");
btdraw->setGeometry(QRect(730,100,80,25));
connect(btdraw,SIGNAL(clicked()),this,SLOT(test()));
btMove = new QPushButton(this);
btMove ->setText("小车运动");
btMove->setGeometry(QRect(730,230,80,25));
connect(btMove,SIGNAL(clicked()),this,SLOT(test2()));
lineEdit = new QLineEdit(this);
lineEdit->setGeometry(QRect(785,130,30,25));
lineEdit->setText("20");
lineEdit2 = new QLineEdit(this);
lineEdit2->setGeometry(QRect(785,160,30,25));
lineEdit2->setText("1");
lineEdit3 = new QLineEdit(this);
lineEdit3->setGeometry(QRect(785,265,30,25));
lineEdit3->setText("10");
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::paintEvent(QPaintEvent *)
{
QPainter pp(&pix);
pp.drawEllipse(Point,3,3);
QBrush brush(Qt::blue);
if(QAQ==1)
{
QPainterPath path;
path.moveTo(x1[0],y1[0]);
CPt *s;
s=Spline;
int draw;
for(draw=0;draw<=g*(count-1);draw++)
{
path.lineTo(s->x,s->y);
s++;
}
pp.drawPath(path);
QAQ = 0;
}
if(TWT==1)
{
pp.setBrush(brush);
CPt *s2;
s2=Spline;
int move;
for(move=0;move<=(v*(count-1));move++)
{
pp.drawEllipse(s2->x,s2->y,20,20);
s2++;
}
}
QPainter painter(this);
painter.drawPixmap(0,0,pix);
}
void MainWindow::mousePressEvent(QMouseEvent *event)
{
if((event->button()==Qt::LeftButton)&&QwQ==1)
{
Point = event->pos();
x1[dot]=event->x();
y1[dot]=event->y();
dot++;
count++;
update();
}
}
void MainWindow::test()
{
QString str = lineEdit->text();
g = str.toInt();
QString str2 = lineEdit2->text();
t = str2.toDouble();
CSpline(x1,y1,g,t,count);
QAQ = 1;
QwQ = 0;
update();
}
void MainWindow::test2()
{
QString str = lineEdit3->text();
v = str.toInt();
CSpline(x1,y1,v,t,count);
TWT = 1;
update();
}
void MainWindow::CSpline(double x[], double y[], int grain, double tension, int n)
{
int i, np;
n0 = n;
np = n0;
CPt jd[100];
CPt *knots;
knots0 = knots;
for(i=1; i<=np; i++){
jd[i].x = x[i-1];
jd[i].y = y[i-1];
}
jd[0].x = x[0];
jd[0].y = y[0];
jd[np+1].x = x[np-1];
jd[np+1].y = y[np-1];
np=np+2;
knots=jd;
CubicSpline(np,knots,grain,tension);
}
void MainWindow::CubicSpline(int n, CPT *knots, int grain, double tension)
{
CPt *s;
CPt *k0,*kml,*k1,*k2;
int i,j;
double alpha[50];
GetCardinalMatrix(tension);
for(i=0;i<grain;i++)
alpha[i] = ((double)i)/grain;
s = Spline;
kml = knots;
k0 = kml+1;
k1 = k0+1;
k2 = k1+1;
for(i=1;i<n-1;i++){
for(j=0;j<grain;j++){
s->x = Matrix(kml->x,k0->x,k1->x,k2->x,alpha[j]);
s->y = Matrix(kml->y,k0->y,k1->y,k2->y,alpha[j]);
s++;
}
k0++;kml++;k1++;k2++;
}
}
void MainWindow::GetCardinalMatrix(double a1)
{
m[0]=-a1; m[1]=2.-a1; m[2]=a1-2.; m[3]=a1;
m[4]=2.*a1; m[5]=a1-3.; m[6]=3.-2*a1; m[7]=-a1;
m[8]=-a1; m[9]=0.; m[10]=a1; m[11]=0.;
m[12]=0.; m[13]=1.; m[14]=0.; m[15]=0.;
}
double MainWindow::Matrix(double a, double b, double c, double d, double alpha)
{
double p0,p1,p2,p3;
p0=m[0]*a+m[1]*b+m[2]*c+m[3]*d;
p1=m[4]*a+m[5]*b+m[6]*c+m[7]*d;
p2=m[8]*a+m[9]*b+m[10]*c+m[11]*d;
p3=m[12]*a+m[13]*b+m[14]*c+m[15]*d;
return(p3+alpha*(p2+alpha*(p1+alpha*p0)));
}