CParabolaBlendCurve.h
#ifndef CPARABOLABLENDCURVE_H
#define CPARABOLABLENDCURVE_H
#include <QVector>
#include <QPointF>
class CParabolaBlendCurve
{
public:
CParabolaBlendCurve();
QVector<QPointF> parabolaBlendCurve(QVector<QPointF>);
QPointF parabolaBlendCurve(qreal t, QPointF p0, QPointF p1, QPointF p2, QPointF p3);
QVector<QPointF> createParabolaCurve(QPointF p0, QPointF p1, QPointF p2, QPointF p3);
};
#endif // CPARABOLABLENDCURVE_H
CParabolaBlendCurve.cpp
#include "cparabolablendcurve.h"
#include <QtMath>
CParabolaBlendCurve::CParabolaBlendCurve()
{
}
QVector<QPointF> CParabolaBlendCurve::parabolaBlendCurve(QVector<QPointF> points)
{
if (points.size() < 4)
{
return points;
}
QVector<QPointF> curvePoints;
// first curve
QPointF virtualHeaderPoint = points.at(1);
QVector<QPointF> pointVector = createParabolaCurve(virtualHeaderPoint,points.at(0),points.at(1),points.at(2));
curvePoints += pointVector;
// mixed curve
for (int i=0; i<=points.size() - 4; i++)
{
QVector<QPointF> pointVector = createParabolaCurve(points.at(i), points.at(i+1), points.at(i+2), points.at(i+3));
curvePoints += pointVector;
}
// last curve
QPointF virtualTailPoint = points.at(points.size() - 2);
pointVector = createParabolaCurve(points.at(points.size()-3), points.at(points.size()-2),points.at(points.size()-1),virtualTailPoint);
curvePoints += pointVector;
return curvePoints;
}
QPointF CParabolaBlendCurve::parabolaBlendCurve(qreal t, QPointF p0, QPointF p1, QPointF p2, QPointF p3)
{
qreal x = (4 * qPow(t, 2) - t - 4 * qPow(t, 3)) * p0.x() +
(1 - 10 * qPow(t, 2) + 12 * qPow(t, 3)) * p1.x() +
(t + 8 * qPow(t, 2) - 12 * qPow(t, 3)) * p2.x() +
(4 * qPow(t, 3) - 2 * qPow(t, 2)) * p3.x();
qreal y = (4 * qPow(t, 2) - t - 4 * qPow(t, 3)) * p0.y() +
(1 - 10 * qPow(t, 2) + 12 * qPow(t, 3)) * p1.y() +
(t + 8 * qPow(t, 2) - 12 * qPow(t, 3)) * p2.y() +
(4 * qPow(t, 3) - 2 * qPow(t, 2)) * p3.y();
return QPointF(x, y);
}
QVector<QPointF> CParabolaBlendCurve::createParabolaCurve(QPointF p0, QPointF p1, QPointF p2, QPointF p3)
{
QVector<QPointF> lineVector;
int pointCount = 100;
qreal maxT = 0.5;
qreal step = maxT / pointCount;
qreal t = 0;
for (int i = 0; i<pointCount; i++)
{
QPointF point = parabolaBlendCurve(t, p0, p1, p2, p3);
if (!point.isNull())
{
lineVector.append(point);
}
t += step;
}
return lineVector;
}