diff --git a/src/domain/UBGraphicsScene.cpp b/src/domain/UBGraphicsScene.cpp index 4327a495..c64815f2 100644 --- a/src/domain/UBGraphicsScene.cpp +++ b/src/domain/UBGraphicsScene.cpp @@ -37,7 +37,6 @@ #include "frameworks/UBGeometryUtils.h" #include "frameworks/UBPlatformUtils.h" -#include "frameworks/UBInterpolator.h" #include "core/UBApplication.h" #include "core/UBSettings.h" @@ -552,13 +551,13 @@ bool UBGraphicsScene::inputDeviceMove(const QPointF& scenePos, const qreal& pres drawLineTo(position, width, true); } - else{ - UBInterpolator::InterpolationMethod interpolator = UBInterpolator::NoInterpolation; + else { + bool interpolate = false; if ((currentTool == UBStylusTool::Pen && UBSettings::settings()->boardInterpolatePenStrokes->get().toBool()) || (currentTool == UBStylusTool::Marker && UBSettings::settings()->boardInterpolateMarkerStrokes->get().toBool())) { - interpolator = UBInterpolator::Bezier; + interpolate = true; } @@ -572,14 +571,14 @@ bool UBGraphicsScene::inputDeviceMove(const QPointF& scenePos, const qreal& pres mDistanceFromLastStrokePoint += distance; if (mDistanceFromLastStrokePoint > MIN_DISTANCE) { - QList > newPoints = mCurrentStroke->addPoint(scenePos, width, interpolator); + QList > newPoints = mCurrentStroke->addPoint(scenePos, width, interpolate); if (newPoints.length() > 1) drawCurve(newPoints); mDistanceFromLastStrokePoint = 0; } - if (interpolator == UBInterpolator::Bezier) { + if (interpolate) { // Bezier curves aren't drawn all the way to the scenePos (they stop halfway between the previous and // current scenePos), so we add a line from the last drawn position in the stroke and the // scenePos, to make the drawing feel more responsive. This line is then deleted if a new segment is diff --git a/src/domain/UBGraphicsStroke.cpp b/src/domain/UBGraphicsStroke.cpp index 4456b26d..9122bc54 100644 --- a/src/domain/UBGraphicsStroke.cpp +++ b/src/domain/UBGraphicsStroke.cpp @@ -77,9 +77,17 @@ QList UBGraphicsStroke::polygons() const /** * @brief Add a point to the curve, interpolating extra points if required - * @return The points (or point, if none were interpolated) that were added + * @param point The position of the point to add + * @param width The width of the stroke at that point. + * @param interpolate If true, a Bézier curve will be drawn rather than a straight line + * @return A list containing the last point drawn plus the point(s) that were added + * + * This method should be called when a new point is given by the input method (mouse, pen or other), and the points that are returned + * should be used to draw the actual stroke on-screen. This is because if interpolation (bézier curves) are to be used, the points to draw + * do not correspond to the points that were given by the input method. + * */ -QList > UBGraphicsStroke::addPoint(const QPointF& point, qreal width, UBInterpolator::InterpolationMethod interpolationMethod) +QList > UBGraphicsStroke::addPoint(const QPointF& point, qreal width, bool interpolate) { strokePoint newPoint(point, width); @@ -88,17 +96,17 @@ QList > UBGraphicsStroke::addPoint(const QPointF& point, q if (n == 0) { mReceivedPoints << newPoint; mDrawnPoints << newPoint; - return QList(); + return QList() << newPoint; } - if (interpolationMethod == UBInterpolator::NoInterpolation) { + if (!interpolate) { strokePoint lastPoint = mReceivedPoints.last(); mReceivedPoints << newPoint; mDrawnPoints << newPoint; return QList() << lastPoint << newPoint; } - else if (interpolationMethod == UBInterpolator::Bezier) { + else { // The curve we are interpolating is not between two drawn points; // it is between the midway points of the second-to-last and last point, and last and current point. @@ -118,14 +126,10 @@ QList > UBGraphicsStroke::addPoint(const QPointF& point, q QPointF p1 = mReceivedPoints[mReceivedPoints.size() - 1].first; QPointF p2 = point; - UBQuadraticBezier bz; - QPointF startPoint = (p1+p0)/2.0; QPointF endPoint = (p2+p1)/2.0; - bz.setPoints(startPoint, p1, endPoint); - - QList calculated = bz.getPoints(10); + QList calculated = UBGeometryUtils::quadraticBezier(startPoint, p1, endPoint, 10); QList newPoints; qreal startWidth = mDrawnPoints.last().second; diff --git a/src/domain/UBGraphicsStroke.h b/src/domain/UBGraphicsStroke.h index 918ec894..930d9546 100644 --- a/src/domain/UBGraphicsStroke.h +++ b/src/domain/UBGraphicsStroke.h @@ -33,7 +33,6 @@ #include #include "core/UB.h" -#include "frameworks/UBInterpolator.h" @@ -60,7 +59,7 @@ class UBGraphicsStroke void clear(); - QList > addPoint(const QPointF& point, qreal width, UBInterpolator::InterpolationMethod interpolationMethod = UBInterpolator::NoInterpolation); + QList > addPoint(const QPointF& point, qreal width, bool interpolate = false); const QList >& points() { return mDrawnPoints; } diff --git a/src/frameworks/UBGeometryUtils.cpp b/src/frameworks/UBGeometryUtils.cpp index 80d5e448..7a9a4cbc 100644 --- a/src/frameworks/UBGeometryUtils.cpp +++ b/src/frameworks/UBGeometryUtils.cpp @@ -447,3 +447,31 @@ qreal UBGeometryUtils::angle(const QPointF& p1, const QPointF& p2, const QPointF return 180.* beta/3.14159; } + + + +/** + * @brief Calculate a quadratic Bézier curve and return it in the form of a list of points + * @param p0 The start point of the curve + * @param p1 The control point of the curve + * @param p2 The end point of the curve + * @param nPoints The number of points by which to approximate the curve, i.e. the length of the returned list + * @return A list of points that can be used to draw the curve. + */ +QList UBGeometryUtils::quadraticBezier(const QPointF& p0, const QPointF& p1, const QPointF& p2, unsigned int nPoints) +{ + QPainterPath path(p0); + path.quadTo(p1, p2); + + QList points; + + if (nPoints <= 1) + return points; + + for (unsigned int i(0); i <= nPoints; ++i) { + qreal percent = qreal(i)/qreal(nPoints); + points << path.pointAtPercent(percent); + } + + return points; +} diff --git a/src/frameworks/UBGeometryUtils.h b/src/frameworks/UBGeometryUtils.h index f4174709..6e2992cc 100644 --- a/src/frameworks/UBGeometryUtils.h +++ b/src/frameworks/UBGeometryUtils.h @@ -57,6 +57,8 @@ class UBGeometryUtils static qreal angle(const QPointF& p1, const QPointF& p2, const QPointF& p3); + static QList quadraticBezier(const QPointF& p0, const QPointF& p1, const QPointF& p2, unsigned int nPoints); + const static int centimeterGraduationHeight; const static int halfCentimeterGraduationHeight; const static int millimeterGraduationHeight; diff --git a/src/frameworks/UBInterpolator.cpp b/src/frameworks/UBInterpolator.cpp deleted file mode 100644 index 3b75da12..00000000 --- a/src/frameworks/UBInterpolator.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include "UBInterpolator.h" - -UBInterpolator::UBInterpolator() -{ -} - -UBInterpolator::~UBInterpolator() -{ -} - -UBQuadraticBezier::UBQuadraticBezier() -{ - mPath = 0; -} - -UBQuadraticBezier::~UBQuadraticBezier() -{ - if (mPath) - delete mPath; -} - -void UBQuadraticBezier::setPoints(QList points) -{ - setPoints(points[0], points[1], points[2]); - -} - -void UBQuadraticBezier::setPoints(QPointF start, QPointF control, QPointF end) -{ - mPath = new QPainterPath(start); - mPath->quadTo(control, end); -} - -/** - * @brief Return n points along the curve, including start and end points (thus n should be larger than or equal to 2). - * - * The higher n, the more accurate the resulting curve will be. - */ -QList UBQuadraticBezier::getPoints(int n) -{ - QList points; - - if (n <= 1) - return points; - - for (int i(0); i <= n; ++i) { - qreal percent = qreal(i)/qreal(n); - - points << mPath->pointAtPercent(percent); - } - - return points; -} diff --git a/src/frameworks/UBInterpolator.h b/src/frameworks/UBInterpolator.h deleted file mode 100644 index 9a714488..00000000 --- a/src/frameworks/UBInterpolator.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef UBINTERPOLATOR_H -#define UBINTERPOLATOR_H - -#include - -class UBInterpolator -{ - /* Abstract class representing an interpolator */ - -public: - enum InterpolationMethod { - NoInterpolation, - //SimpleSpline, - //CatmullRom, - Bezier - }; - - UBInterpolator(); - virtual ~UBInterpolator(); - - virtual void setPoints(QList points) = 0; - //virtual double y(double x) {} - -}; - -class UBQuadraticBezier : public UBInterpolator -{ - -public: - UBQuadraticBezier(); - virtual ~UBQuadraticBezier(); - - virtual void setPoints(QList points); - void setPoints(QPointF start, QPointF control, QPointF end); - - //virtual double y(double x); - - QList getPoints(int n); - -private: - - QPainterPath* mPath; -}; - -#endif // UBINTERPOLATOR_H diff --git a/src/frameworks/frameworks.pri b/src/frameworks/frameworks.pri index 8d6d435d..74d6edbb 100644 --- a/src/frameworks/frameworks.pri +++ b/src/frameworks/frameworks.pri @@ -6,8 +6,7 @@ HEADERS += src/frameworks/UBGeometryUtils.h \ src/frameworks/UBVersion.h \ src/frameworks/UBCoreGraphicsScene.h \ src/frameworks/UBCryptoUtils.h \ - src/frameworks/UBBase32.h \ - $$PWD/UBInterpolator.h + src/frameworks/UBBase32.h SOURCES += src/frameworks/UBGeometryUtils.cpp \ src/frameworks/UBPlatformUtils.cpp \ @@ -16,8 +15,7 @@ SOURCES += src/frameworks/UBGeometryUtils.cpp \ src/frameworks/UBVersion.cpp \ src/frameworks/UBCoreGraphicsScene.cpp \ src/frameworks/UBCryptoUtils.cpp \ - src/frameworks/UBBase32.cpp \ - $$PWD/UBInterpolator.cpp + src/frameworks/UBBase32.cpp win32 {