Draw last (half-) segment of stroke to make drawing feel smoother

Also, clarified the difference between received and drawn points
in UBGraphicsStroke
preferencesAboutTextFull
Craig Watson 8 years ago
parent b55ab7c92c
commit 43e0e414c9
  1. 25
      src/domain/UBGraphicsScene.cpp
  2. 1
      src/domain/UBGraphicsScene.h
  3. 31
      src/domain/UBGraphicsStroke.cpp
  4. 8
      src/domain/UBGraphicsStroke.h

@ -335,6 +335,7 @@ UBGraphicsScene::UBGraphicsScene(UBDocumentProxy* parent, bool enableUndoRedoSta
, mZLayerController(new UBZLayerController(this))
, mpLastPolygon(NULL)
, mCurrentPolygon(0)
, mTempPolygon(NULL)
, mSelectionFrame(0)
{
UBCoreGraphicsScene::setObjectName("BoardScene");
@ -561,6 +562,23 @@ bool UBGraphicsScene::inputDeviceMove(const QPointF& scenePos, const qreal& pres
if (newPoints.length() > 1) {
drawCurve(newPoints, mPreviousWidth, width);
}
if (interpolator == UBInterpolator::Bezier) {
// 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
// added to the stroke. (Or it is added to the stroke when we stop drawing)
if (mTempPolygon) {
removeItem(mTempPolygon);
mTempPolygon = NULL;
}
QPointF lastDrawnPoint = newPoints.last();
mTempPolygon = lineToPolygonItem(QLineF(lastDrawnPoint, scenePos), mPreviousWidth, width);
addItem(mTempPolygon);
}
}
}
else if (currentTool == UBStylusTool::Eraser)
@ -629,6 +647,13 @@ bool UBGraphicsScene::inputDeviceRelease()
mDrawWithCompass = false;
}
else if (mCurrentStroke){
if (mTempPolygon) {
UBGraphicsPolygonItem * poly = dynamic_cast<UBGraphicsPolygonItem*>(mTempPolygon->deepCopy());
removeItem(mTempPolygon);
mTempPolygon = NULL;
addPolygonItemToCurrentStroke(poly);
}
UBGraphicsStrokesGroup* pStrokes = new UBGraphicsStrokesGroup();
// Remove the strokes that were just drawn here and replace them by a stroke item

@ -442,6 +442,7 @@ public slots:
UBZLayerController *mZLayerController;
UBGraphicsPolygonItem* mpLastPolygon;
UBGraphicsPolygonItem* mTempPolygon;
bool mDrawWithCompass;
UBGraphicsPolygonItem *mCurrentPolygon;

@ -70,18 +70,18 @@ QList<UBGraphicsPolygonItem*> UBGraphicsStroke::polygons() const
*/
QList<QPointF> UBGraphicsStroke::addPoint(const QPointF& point, UBInterpolator::InterpolationMethod interpolationMethod)
{
int n = mDrawnPoints.size();
int n = mReceivedPoints.size();
if (n == 0) {
mReceivedPoints << point;
mDrawnPoints << point;
mAllPoints << point;
return QList<QPointF>();
}
if (interpolationMethod == UBInterpolator::NoInterpolation) {
QPointF lastPoint = mDrawnPoints.last();
QPointF lastPoint = mReceivedPoints.last();
mReceivedPoints << point;
mDrawnPoints << point;
mAllPoints << point;
return QList<QPointF>() << lastPoint << point;
}
@ -91,23 +91,24 @@ QList<QPointF> UBGraphicsStroke::addPoint(const QPointF& point, UBInterpolator::
// Don't draw segments smaller than a certain length. This can help with performance
// (less polygons in a stroke) but mostly with keeping the curve smooth.
qreal MIN_DISTANCE = 3*mAntiScaleRatio;
qreal distance = QLineF(mDrawnPoints.last(), point).length();
qreal MIN_DISTANCE = 5*mAntiScaleRatio;
qreal distance = QLineF(mReceivedPoints.last(), point).length();
if (distance < MIN_DISTANCE) {
return QList<QPointF>();
return QList<QPointF>() << mDrawnPoints.last();
}
// The first segment is just a straight line to the first midway point
if (n == 1) {
QPointF lastPoint = mDrawnPoints[0];
mDrawnPoints << point;
QPointF lastPoint = mReceivedPoints[0];
mReceivedPoints << point;
mDrawnPoints << QPointF((lastPoint + point)/2.0);
return QList<QPointF>() << lastPoint << ((lastPoint + point)/2.0);
}
QPointF p0 = mDrawnPoints[mDrawnPoints.size() - 2];
QPointF p1 = mDrawnPoints[mDrawnPoints.size() - 1];
QPointF p0 = mReceivedPoints[mReceivedPoints.size() - 2];
QPointF p1 = mReceivedPoints[mReceivedPoints.size() - 1];
QPointF p2 = point;
UBQuadraticBezier bz;
@ -119,11 +120,15 @@ QList<QPointF> UBGraphicsStroke::addPoint(const QPointF& point, UBInterpolator::
QList<QPointF> newPoints = bz.getPoints(10);
// avoid adding duplicates
if (newPoints.first() == mDrawnPoints.last())
mDrawnPoints.removeLast();
foreach(QPointF p, newPoints) {
mAllPoints << p;
mDrawnPoints << p;
}
mDrawnPoints << point;
mReceivedPoints << point;
return newPoints;
}

@ -59,7 +59,7 @@ class UBGraphicsStroke
QList<QPointF> addPoint(const QPointF& point, UBInterpolator::InterpolationMethod interpolationMethod = UBInterpolator::NoInterpolation);
const QList<QPointF>& points() { return mAllPoints; }
const QList<QPointF>& points() { return mDrawnPoints; }
protected:
void addPolygon(UBGraphicsPolygonItem* pol);
@ -68,11 +68,11 @@ class UBGraphicsStroke
QList<UBGraphicsPolygonItem*> mPolygons;
/// Points that were drawn by the user (actually received through input device)
QList<QPointF> mDrawnPoints;
/// Points that were drawn by the user (i.e, actually received through input device)
QList<QPointF> mReceivedPoints;
/// All the points (including interpolated) that are used to draw the stroke
QList<QPointF> mAllPoints;
QList<QPointF> mDrawnPoints;
qreal mAntiScaleRatio;
};

Loading…
Cancel
Save