Optimize Bezier curve shape approximation
Using CubicBezier::pointAtPercent instead of QPainterPath::pointAtPercent makes layout about 25% faster in some cases.
This commit is contained in:
parent
f78dbf0876
commit
c9c1f03a2f
3 changed files with 31 additions and 10 deletions
|
@ -311,17 +311,13 @@ void SlurSegment::computeBezier(QPointF p6o)
|
|||
ups(Grip::DRAG).p = t.map(p5);
|
||||
ups(Grip::SHOULDER).p = t.map(p6);
|
||||
|
||||
QPainterPath p;
|
||||
p.moveTo(QPointF());
|
||||
p.cubicTo(p3 + p3o, p4 + p4o, p2);
|
||||
p = t.map(p);
|
||||
|
||||
_shape.clear();
|
||||
QPointF start = pp1;
|
||||
int nbShapes = 32; // (pp2.x() - pp1.x()) / _spatium;
|
||||
qreal minH = qAbs(3 * w);
|
||||
const CubicBezier b(pp1, ups(Grip::BEZIER1).pos(), ups(Grip::BEZIER2).pos(), ups(Grip::END).pos());
|
||||
for (int i = 1; i <= nbShapes; i++) {
|
||||
QPointF point = p.pointAtPercent(i/float(nbShapes));
|
||||
const QPointF point = b.pointAtPercent(i/float(nbShapes));
|
||||
QRectF re = QRectF(start, point).normalized();
|
||||
if (re.height() < minH) {
|
||||
qreal d1 = (minH - re.height()) * .5;
|
||||
|
|
|
@ -41,9 +41,36 @@ struct UP {
|
|||
QPointF p; // layout position relative to pos()
|
||||
QPointF off; // user offset in point units
|
||||
|
||||
QPointF pos() const { return p + off; }
|
||||
bool operator!=(const UP& up) const { return p != up.p || off != up.off; }
|
||||
};
|
||||
|
||||
//---------------------------------------------------------
|
||||
// CubicBezier
|
||||
// Helper class to optimize cubic Bezier curve points
|
||||
// calculation.
|
||||
//---------------------------------------------------------
|
||||
|
||||
class CubicBezier {
|
||||
QPointF p1;
|
||||
QPointF p2;
|
||||
QPointF p3;
|
||||
QPointF p4;
|
||||
|
||||
public:
|
||||
CubicBezier(QPointF _p1, QPointF _p2, QPointF _p3, QPointF _p4)
|
||||
: p1(_p1), p2(_p2), p3(_p3), p4(_p4) {}
|
||||
|
||||
QPointF pointAtPercent(qreal t) const
|
||||
{
|
||||
Q_ASSERT(t >= 0.0 && t <= 1.0);
|
||||
const qreal r = 1.0 - t;
|
||||
const QPointF B123 = r * (r*p1 + t*p2) + t * (r*p2 + t*p3);
|
||||
const QPointF B234 = r * (r*p2 + t*p3) + t * (r*p3 + t*p4);
|
||||
return r*B123 + t*B234;
|
||||
}
|
||||
};
|
||||
|
||||
class SlurTie;
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -305,17 +305,15 @@ void TieSegment::computeBezier(QPointF p6o)
|
|||
// path.translate(staffOffset);
|
||||
// shapePath.translate(staffOffset);
|
||||
|
||||
QPainterPath p;
|
||||
p.moveTo(QPointF());
|
||||
p.cubicTo(p3 + p3o, p4 + p4o, p2);
|
||||
_shape.clear();
|
||||
QPointF start;
|
||||
start = t.map(start);
|
||||
|
||||
qreal minH = qAbs(3.0 * w);
|
||||
int nbShapes = 15;
|
||||
const CubicBezier b(pp1, ups(Grip::BEZIER1).pos(), ups(Grip::BEZIER2).pos(), ups(Grip::END).pos());
|
||||
for (int i = 1; i <= nbShapes; i++) {
|
||||
QPointF point = t.map(p.pointAtPercent(i/float(nbShapes)));
|
||||
const QPointF point = b.pointAtPercent(i/float(nbShapes));
|
||||
QRectF re = QRectF(start, point).normalized();
|
||||
if (re.height() < minH) {
|
||||
d = (minH - re.height()) * .5;
|
||||
|
|
Loading…
Reference in a new issue