1 | // Copyright (C) 2018 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only |
3 | |
4 | #include <beziereasing_p.h> |
5 | |
6 | QT_BEGIN_NAMESPACE |
7 | |
8 | void BezierEasing::addCubicBezierSegment(const QPointF &c1, const QPointF &c2, const QPointF &endPoint) |
9 | { |
10 | mBezier = QBezier::fromPoints(p1: QPointF(0.0, 0.0), p2: c1, p3: c2, p4: endPoint); |
11 | } |
12 | |
13 | qreal BezierEasing::valueForProgress(qreal progress) const |
14 | { |
15 | qreal res = mBezier.pointAt(t: tForX(x: progress)).y(); |
16 | return qBound(min: qreal(0.0), val: res, max: qreal(1.0)); |
17 | } |
18 | |
19 | qreal BezierEasing::tForX(qreal x) const |
20 | { |
21 | if (x <= 0.0) |
22 | return 0.0; |
23 | else if (x >= 1.0) |
24 | return 1.0; |
25 | |
26 | qreal t0 = 0.0; |
27 | qreal t1 = 1.0; |
28 | |
29 | for (int i = 0; i < 10; i++) { // 10 iterations gives error smaller than 0.001 |
30 | qreal t = qreal(0.5) * (t0 + t1); |
31 | qreal a, b, c, d; |
32 | QBezier::coefficients(t, a, b, c, d); |
33 | qreal xt = a * mBezier.x1 + b * mBezier.x2 + c * mBezier.x3 + d * mBezier.x4; |
34 | if (xt < x) |
35 | t0 = t; |
36 | else |
37 | t1 = t; |
38 | } |
39 | |
40 | return t0; |
41 | } |
42 | |
43 | QT_END_NAMESPACE |
44 | |