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 10 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