Removed spline interpolators

preferencesAboutTextFull
Craig Watson 9 years ago
parent 1ef73a70b8
commit 999fcec917
  1. 3
      OpenBoard.pro
  2. 24
      src/domain/UBGraphicsScene.cpp
  3. 104
      src/domain/UBGraphicsStroke.cpp
  4. 2
      src/domain/UBGraphicsStroke.h
  5. 86
      src/frameworks/UBInterpolator.cpp
  6. 57
      src/frameworks/UBInterpolator.h

@ -66,9 +66,6 @@ INCLUDEPATH += src/pdf-merger
include(src/pdf-merger/pdfMerger.pri) include(src/pdf-merger/pdfMerger.pri)
#ThirdParty #ThirdParty
INCLUDEPATH += $$THIRD_PARTY_PATH/spline/
INCLUDEPATH += $$THIRD_PARTY_PATH/alglib/
include($$THIRD_PARTY_PATH/alglib/alglib.pri)
DEPENDPATH += $$THIRD_PARTY_PATH/quazip/ DEPENDPATH += $$THIRD_PARTY_PATH/quazip/
INCLUDEPATH += $$THIRD_PARTY_PATH/quazip/ INCLUDEPATH += $$THIRD_PARTY_PATH/quazip/
include($$THIRD_PARTY_PATH/quazip/quazip.pri) include($$THIRD_PARTY_PATH/quazip/quazip.pri)

@ -630,30 +630,6 @@ bool UBGraphicsScene::inputDeviceRelease()
mDrawWithCompass = false; mDrawWithCompass = false;
} }
else if (mCurrentStroke){ else if (mCurrentStroke){
/*
// -------------------------------------------------------------------------
// Replace the stroke by a smoother one
// -------------------------------------------------------------------------
UBGraphicsStroke* smoothStroke = mCurrentStroke->smoothe();
foreach(UBGraphicsPolygonItem* poly, mCurrentStroke->polygons()){
mPreviousPolygonItems.removeAll(poly);
removeItem(poly);
}
delete mCurrentStroke;
mCurrentStroke = smoothStroke;
moveTo(smoothStroke->points()[0]);
for (int i(1); i < smoothStroke->points().size(); ++i) {
QPointF currentPoint = smoothStroke->points()[i];
drawLineTo(currentPoint, dc->currentToolWidth(), dc->currentToolWidth(), false);
moveTo(currentPoint);
}
// -------------------------------------------------------------------------
*/
UBGraphicsStrokesGroup* pStrokes = new UBGraphicsStrokesGroup(); UBGraphicsStrokesGroup* pStrokes = new UBGraphicsStrokesGroup();
// Remove the strokes that were just drawn here and replace them by a stroke item // Remove the strokes that were just drawn here and replace them by a stroke item

@ -88,7 +88,7 @@ QList<QPointF> UBGraphicsStroke::addPoint(const QPointF& point, UBInterpolator::
// We don't draw anything below the minimum distance. For performance reasons but also to make the curve // We don't draw anything below the minimum distance. For performance reasons but also to make the curve
// look smoother (e.g shaking slightly won't affect the curve). // look smoother (e.g shaking slightly won't affect the curve).
if (distance < MIN_DISTANCE) { if (distance < MIN_DISTANCE) {
// we still keep track of that point to calculate the distance correctly next time around // but we still keep track of that point to calculate the distance correctly next time around
mLastReceivedPoint = point; mLastReceivedPoint = point;
return QList<QPointF>(); return QList<QPointF>();
} }
@ -123,59 +123,7 @@ QList<QPointF> UBGraphicsStroke::addPoint(const QPointF& point, UBInterpolator::
return newPoints; return newPoints;
} }
else { return QList<QPointF>();
qreal MIN_INTERPOLATION_DISTANCE = 0;
QPointF lastPoint;
if (!mDrawnPoints.isEmpty())
lastPoint = mDrawnPoints.last();
QList<QPointF> newPoints;
// Interpolation
if (n > 3 && QLineF(lastPoint, point).length() > MIN_INTERPOLATION_DISTANCE) {
/*
UBSimpleSpline sp;
sp.setPoints(mDrawnPoints[n-2], mDrawnPoints[n-1], point);
*/
// todo: better way of avoiding problems with equal x's (such as PCA). in the meantime this'll do.
qreal x0 = mDrawnPoints[n-3].x();
qreal x1 = mDrawnPoints[n-2].x();
qreal x2 = mDrawnPoints[n-1].x();
qreal x3 = point.x();
if (!(x0 == x1 || x0 == x2 || x0 == x3 || x1 == x2 || x1 == x3 || x2 == x3)) {
UBCatmullRomSpline sp;
sp.setPoints(QList<QPointF>() << mDrawnPoints[n-3] << mDrawnPoints[n-2] << mDrawnPoints[n-1] << point);
// get an extra 3 values in between the current point and last one
int n_points = 3; // number of points to interpolate
double interval = (point.x() - lastPoint.x())/double(n_points+1);
qDebug() << "Interpolating between: " << lastPoint << " and " << point;
for (int i(1); i <= n_points; ++i) {
double x = lastPoint.x() + i*interval;
QPointF newPoint(x, sp.y(x));
qDebug() << newPoint;
newPoints << newPoint;
mAllPoints << newPoint;
//qDebug() << "Got new point: " << newPoint;
}
}
}
newPoints << point;
mAllPoints << point;
mDrawnPoints << point;
return newPoints;
}
} }
bool UBGraphicsStroke::hasPressure() bool UBGraphicsStroke::hasPressure()
@ -220,51 +168,3 @@ void UBGraphicsStroke::clear()
mPolygons.clear(); mPolygons.clear();
} }
} }
/**
* @brief Smoothe the curve, by interpolating extra points where needed.
*
* @return A new stroke based on the current one.
*/
UBGraphicsStroke* UBGraphicsStroke::smoothe()
{
// Catmull-Rom spline interpolation
UBCatmullRomSpline sp;
UBGraphicsStroke * smoothStroke = new UBGraphicsStroke();
smoothStroke->mAllPoints << mAllPoints[0];
for (int i(0); i < mAllPoints.size() - 3; ++i) {
QPointF p1, p2;
p1 = mAllPoints[i+1];
p2 = mAllPoints[i+2];
qreal x0 = mAllPoints[i].x();
qreal x1 = p1.x();
qreal x2 = p2.x();
qreal x3 = mAllPoints[i+3].x();
if (!(x0 == x1 || x0 == x2 || x0 == x3 || x1 == x2 || x1 == x3 || x2 == x3)) {
sp.setPoints(QList<QPointF>() << mAllPoints[i] << mAllPoints[i+1] << mAllPoints[i+2] << mAllPoints[i+3]);
smoothStroke->mAllPoints << mAllPoints[i+1];
int n_points = 3; // number of points to interpolate
double interval = (p2.x() - p1.x())/double(n_points+1);
for (int i(1); i <= n_points; ++i) {
double x = p1.x() + i*interval;
QPointF newPoint(x, sp.y(x));
smoothStroke->mAllPoints << newPoint;
}
}
}
smoothStroke->mAllPoints << mAllPoints[mAllPoints.size() - 2] << mAllPoints[mAllPoints.size() - 1];
return smoothStroke;
}

@ -59,8 +59,6 @@ class UBGraphicsStroke
QList<QPointF> addPoint(const QPointF& point, UBInterpolator::InterpolationMethod interpolationMethod = UBInterpolator::NoInterpolation); QList<QPointF> addPoint(const QPointF& point, UBInterpolator::InterpolationMethod interpolationMethod = UBInterpolator::NoInterpolation);
UBGraphicsStroke* smoothe();
const QList<QPointF>& points() { return mAllPoints; } const QList<QPointF>& points() { return mAllPoints; }
protected: protected:

@ -8,92 +8,6 @@ UBInterpolator::~UBInterpolator()
{ {
} }
UBSimpleSpline::UBSimpleSpline()
{
}
void UBSimpleSpline::setPoints(QList<QPointF> points)
{
setPoints(points[0], points[1], points[2]);
}
void UBSimpleSpline::setPoints(QPointF p0, QPointF p1, QPointF p2)
{
/*
p0 -= p0;
p1 -= p0;
p2 -= p0;
*/
long double x0, x1, x2, y0, y1, y2;
x0 = p0.x();
x1 = p1.x();
x2 = p2.x();
y0 = p0.y();
y1 = p1.y();
y2 = p2.y();
long double k1 = (y2-y0)/(x2-x0);
m_a = (y1-y2-k1*(x1-x2))/(pow(x1,3) - pow(x2,3) - 3*x2*(pow(x1,2)-pow(x2,2)) -
3*(pow(x1,2) - 2*x1*x2)*(x1-x2));
m_b = -3*m_a*x2;
m_c = k1 - 3*m_a*pow(x1,2) - 2*m_b*x1;
m_d = y1 - m_a*pow(x1,3) - m_b*pow(x1,2) - m_c*x1;
}
double UBSimpleSpline::y(double x)
{
return m_a*pow(x, 3) + m_b*pow(x, 2) + m_c*x + m_d;
}
UBCatmullRomSpline::UBCatmullRomSpline()
{
mInterpolant = 0;
}
UBCatmullRomSpline::~UBCatmullRomSpline()
{
if (mInterpolant)
delete mInterpolant;
}
void UBCatmullRomSpline::setPoints(QList<QPointF> points)
{
// todo : basis change to avoid crashing when several X's are equal
mInterpolant = new alglib::spline1dinterpolant();
// alglib arrays are defined as strings
QString x = "[";
QString y = "[";
foreach(QPointF point, points) {
x += (QString::number(point.x()) + QString(","));
y += (QString::number(point.y()) + QString(","));
}
x.chop(1);
y.chop(1);
x+="]";
y+="]";
alglib::real_1d_array xArray = x.toLatin1().data();
alglib::real_1d_array yArray = y.toLatin1().data();
alglib::spline1dbuildcatmullrom(xArray, yArray, *mInterpolant);
}
double UBCatmullRomSpline::y(double x)
{
return alglib::spline1dcalc(*mInterpolant, x);
}
UBQuadraticBezier::UBQuadraticBezier() UBQuadraticBezier::UBQuadraticBezier()
{ {
mPath = 0; mPath = 0;

@ -3,9 +3,6 @@
#include <QtGui> #include <QtGui>
#include "spline.h"
#include "interpolation.h"
class UBInterpolator class UBInterpolator
{ {
/* Abstract class representing an interpolator */ /* Abstract class representing an interpolator */
@ -13,8 +10,8 @@ class UBInterpolator
public: public:
enum InterpolationMethod { enum InterpolationMethod {
NoInterpolation, NoInterpolation,
SimpleSpline, //SimpleSpline,
CatmullRom, //CatmullRom,
Bezier Bezier
}; };
@ -22,58 +19,10 @@ public:
virtual ~UBInterpolator(); virtual ~UBInterpolator();
virtual void setPoints(QList<QPointF> points) = 0; virtual void setPoints(QList<QPointF> points) = 0;
virtual double y(double x) {} //virtual double y(double x) {}
};
class UBSimpleSpline : public UBInterpolator
{
/* A basic cubic spline interpolator, that requires only three
* points to interpolate between the second and third one.
* To do so, the curvature at p2 is set to 0, so the resulting
* curve is not very smooth.
* However, it is better than linear interpolation and requires no
* "future" points, so it can be used seamlessly during drawing.
*/
public:
UBSimpleSpline();
virtual ~UBSimpleSpline() {}
virtual void setPoints(QList<QPointF> points);
void setPoints(QPointF p0, QPointF p1, QPointF p2);
virtual double y(double x);
private:
long double m_a,
m_b,
m_c,
m_d;
};
class UBCatmullRomSpline : public UBInterpolator
{
/* Catmull-Rom spline, using AlgLib as backend
*
* This requires four points to interpolate between the middle two.
*/
public:
UBCatmullRomSpline();
virtual ~UBCatmullRomSpline();
virtual void setPoints(QList<QPointF> points);
virtual double y(double x);
private:
alglib::spline1dinterpolant * mInterpolant;
}; };
class UBQuadraticBezier : public UBInterpolator class UBQuadraticBezier : public UBInterpolator
{ {

Loading…
Cancel
Save