6#include <PhosphorAnimation/phosphoranimation_export.h>
41 static qreal
lerp(qreal from, qreal to, qreal t)
43 return from + (to - from) * t;
47 return qAbs(to - from);
49 static constexpr qreal retargetEpsilon = 1.0e-6;
52 return std::isfinite(v);
59 static QPointF
lerp(
const QPointF& from,
const QPointF& to, qreal t)
61 return QPointF(from.x() + (to.x() - from.x()) * t, from.y() + (to.y() - from.y()) * t);
63 static qreal
distance(
const QPointF& from,
const QPointF& to)
65 return QLineF(from, to).length();
67 static constexpr qreal retargetEpsilon = 0.5;
70 return std::isfinite(p.x()) && std::isfinite(p.y());
77 static QSizeF
lerp(
const QSizeF& from,
const QSizeF& to, qreal t)
79 return QSizeF(from.width() + (to.width() - from.width()) * t,
80 from.height() + (to.height() - from.height()) * t);
82 static qreal
distance(
const QSizeF& from,
const QSizeF& to)
84 const qreal dw = to.width() - from.width();
85 const qreal dh = to.height() - from.height();
86 return std::sqrt(dw * dw + dh * dh);
88 static constexpr qreal retargetEpsilon = 0.5;
91 return std::isfinite(s.width()) && std::isfinite(s.height());
98 static QRectF
lerp(
const QRectF& from,
const QRectF& to, qreal t)
106 static qreal
distance(
const QRectF& from,
const QRectF& to)
110 return std::sqrt(dp * dp + ds * ds);
112 static constexpr qreal retargetEpsilon = 0.5;
115 return std::isfinite(r.x()) && std::isfinite(r.y()) && std::isfinite(r.width()) && std::isfinite(r.height());
124 return c <= 0.04045 ? c / 12.92 : qPow((c + 0.055) / 1.055, 2.4);
128 return c <= 0.0031308 ? c * 12.92 : 1.055 * qPow(c, 1.0 / 2.4) - 0.055;
140 const qreal rLin = fR + (tR - fR) * t;
141 const qreal gLin = fG + (tG - fG) * t;
142 const qreal bLin = fB + (tB - fB) * t;
143 const qreal a = from.alphaF() + (to.alphaF() - from.alphaF()) * t;
147 qBound(0.0,
linearToSrgb(bLin), 1.0), qBound(0.0, a, 1.0));
161 const qreal l = 0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * bv;
162 const qreal m = 0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * bv;
163 const qreal s = 0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * bv;
165 const qreal lCbrt = std::cbrt(l);
166 const qreal mCbrt = std::cbrt(m);
167 const qreal sCbrt = std::cbrt(s);
170 out.
L = 0.2104542553 * lCbrt + 0.7936177850 * mCbrt - 0.0040720468 * sCbrt;
171 out.
a = 1.9779984951 * lCbrt - 2.4285922050 * mCbrt + 0.4505937099 * sCbrt;
172 out.
b = 0.0259040371 * lCbrt + 0.7827717662 * mCbrt - 0.8086757660 * sCbrt;
178 const qreal lCbrt = lab.
L + 0.3963377774 * lab.
a + 0.2158037573 * lab.
b;
179 const qreal mCbrt = lab.
L - 0.1055613458 * lab.
a - 0.0638541728 * lab.
b;
180 const qreal sCbrt = lab.
L - 0.0894841775 * lab.
a - 1.2914855480 * lab.
b;
182 const qreal l = lCbrt * lCbrt * lCbrt;
183 const qreal m = mCbrt * mCbrt * mCbrt;
184 const qreal s = sCbrt * sCbrt * sCbrt;
186 r = +4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s;
187 g = -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s;
188 bv = -0.0041960863 * l - 0.7034186147 * m + 1.7076147010 * s;
204 mid.
L = fLab.
L + (tLab.
L - fLab.
L) * t;
205 mid.
a = fLab.
a + (tLab.
a - fLab.
a) * t;
206 mid.
b = fLab.
b + (tLab.
b - fLab.
b) * t;
208 qreal rLin, gLin, bLin;
211 const qreal a = from.alphaF() + (to.alphaF() - from.alphaF()) * t;
215 qBound(0.0,
linearToSrgb(bLin), 1.0), qBound(0.0, a, 1.0));
226 const qreal dA = to.alphaF() - from.alphaF();
227 return std::sqrt(dR * dR + dG * dG + dB * dB + dA * dA);
237 static QColor
lerp(
const QColor& from,
const QColor& to, qreal t)
241 static qreal
distance(
const QColor& from,
const QColor& to)
245 static constexpr qreal retargetEpsilon = 1.0e-4;
248 return std::isfinite(c.redF()) && std::isfinite(c.greenF()) && std::isfinite(c.blueF())
249 && std::isfinite(c.alphaF());
275 const qreal m11 = t.m11();
276 const qreal m12 = t.m12();
277 const qreal m21 = t.m21();
278 const qreal m22 = t.m22();
280 d.
sx = std::sqrt(m11 * m11 + m21 * m21);
281 d.
rotation = d.
sx > 1.0e-9 ? std::atan2(-m21, m11) : 0.0;
283 const qreal cosR = std::cos(d.
rotation);
284 const qreal sinR = std::sin(d.
rotation);
286 d.
sy = m22 * cosR + m12 * sinR;
287 const qreal shearTimesSy = m12 * cosR - m22 * sinR;
288 d.
shear = qAbs(d.
sy) > 1.0e-9 ? shearTimesSy / d.
sy : 0.0;
294 const qreal cosR = std::cos(d.
rotation);
295 const qreal sinR = std::sin(d.
rotation);
297 const qreal m11 = d.
sx * cosR;
298 const qreal m12 = d.
sy * (d.
shear * cosR + sinR);
299 const qreal m21 = -d.
sx * sinR;
300 const qreal m22 = d.
sy * (cosR - d.
shear * sinR);
302 return QTransform(m11, m12, m21, m22, d.
tx, d.
ty);
308 constexpr qreal kIdentityEps = 1.0e-9;
309 return qAbs(t.m11() - 1.0) < kIdentityEps && qAbs(t.m22() - 1.0) < kIdentityEps && qAbs(t.m12()) < kIdentityEps
310 && qAbs(t.m21()) < kIdentityEps;
313inline QTransform
lerpTransform(
const QTransform& from,
const QTransform& to, qreal t)
327 constexpr qreal kNearSingularDet = 1.0e-6;
328 const qreal detFrom = from.m11() * from.m22() - from.m12() * from.m21();
329 const qreal detTo = to.m11() * to.m22() - to.m12() * to.m21();
330 const bool reflection = detFrom * detTo < 0.0;
331 const bool nearSingular = std::abs(detFrom) < kNearSingularDet || std::abs(detTo) < kNearSingularDet;
332 if (reflection || nearSingular) {
334 return QTransform(S::lerp(from.m11(), to.m11(), t), S::lerp(from.m12(), to.m12(), t),
335 S::lerp(from.m21(), to.m21(), t), S::lerp(from.m22(), to.m22(), t),
336 S::lerp(from.dx(), to.dx(), t), S::lerp(from.dy(), to.dy(), t));
351 while (dRot > M_PI) {
354 while (dRot < -M_PI) {
367 static QTransform
lerp(
const QTransform& from,
const QTransform& to, qreal t)
374 static qreal
distance(
const QTransform& from,
const QTransform& to)
376 const qreal d11 = to.m11() - from.m11();
377 const qreal d12 = to.m12() - from.m12();
378 const qreal d21 = to.m21() - from.m21();
379 const qreal d22 = to.m22() - from.m22();
380 const qreal dtx = to.dx() - from.dx();
381 const qreal dty = to.dy() - from.dy();
382 return std::sqrt(d11 * d11 + d12 * d12 + d21 * d21 + d22 * d22 + dtx * dtx + dty * dty);
384 static constexpr qreal retargetEpsilon = 0.5;
387 return std::isfinite(t.m11()) && std::isfinite(t.m12()) && std::isfinite(t.m21()) && std::isfinite(t.m22())
388 && std::isfinite(t.dx()) && std::isfinite(t.dy());
Position-carrying T whose damage region is fully determined by endpoints + overshoot.
Definition Interpolate.h:396
Definition Interpolate.h:403
Size-only T — caller must supply an anchor for damage rect.
Definition Interpolate.h:400
qreal srgbToLinear(qreal c)
Definition Interpolate.h:122
void okLabToLinear(const OkLab &lab, qreal &r, qreal &g, qreal &bv)
Definition Interpolate.h:176
qreal linearToSrgb(qreal c)
Definition Interpolate.h:126
QTransform lerpTransform(const QTransform &from, const QTransform &to, qreal t)
Definition Interpolate.h:313
QColor lerpColorOkLab(const QColor &from, const QColor &to, qreal t)
Definition Interpolate.h:191
qreal colorDistance(const QColor &from, const QColor &to)
L2 norm in linear-RGB space — matches the lerp space so velocity rescale uses a consistent metric.
Definition Interpolate.h:221
DecomposedTransform decomposeTransform(const QTransform &t)
QR-style decomposition on the 2x2 linear part under Qt's post-multiply row-vector convention: M = R x...
Definition Interpolate.h:269
OkLab linearToOkLab(qreal r, qreal g, qreal bv)
Definition Interpolate.h:159
bool isPureTranslate(const QTransform &t)
True if the 2x2 linear part is identity (only translation present).
Definition Interpolate.h:306
QTransform recomposeTransform(const DecomposedTransform &d)
Definition Interpolate.h:292
QColor lerpColorLinear(const QColor &from, const QColor &to, qreal t)
Definition Interpolate.h:131
Definition AnimatedValue.h:31
constexpr qreal kRectSizeEpsilonPx
Sub-pixel epsilon for rect size-change detection.
Definition Interpolate.h:26
ColorSpace
Interpolation space selector for AnimatedValue<QColor, ...>.
Definition Interpolate.h:29
@ Linear
sRGB -> linear lerp -> sRGB (radiometrically correct)
@ OkLab
sRGB -> OkLab lerp -> sRGB (perceptually uniform)
static qreal distance(const QColor &from, const QColor &to)
Definition Interpolate.h:241
static bool isFinite(const QColor &c)
Definition Interpolate.h:246
static QColor lerp(const QColor &from, const QColor &to, qreal t)
Linear-space sRGB lerp.
Definition Interpolate.h:237
static bool isFinite(const QPointF &p)
Definition Interpolate.h:68
static QPointF lerp(const QPointF &from, const QPointF &to, qreal t)
Definition Interpolate.h:59
static qreal distance(const QPointF &from, const QPointF &to)
Definition Interpolate.h:63
static bool isFinite(const QRectF &r)
Definition Interpolate.h:113
static QRectF lerp(const QRectF &from, const QRectF &to, qreal t)
Definition Interpolate.h:98
static qreal distance(const QRectF &from, const QRectF &to)
4-D Euclidean norm over (x, y, w, h).
Definition Interpolate.h:106
static QSizeF lerp(const QSizeF &from, const QSizeF &to, qreal t)
Definition Interpolate.h:77
static qreal distance(const QSizeF &from, const QSizeF &to)
Definition Interpolate.h:82
static bool isFinite(const QSizeF &s)
Definition Interpolate.h:89
static qreal distance(qreal from, qreal to)
Definition Interpolate.h:45
static bool isFinite(qreal v)
Definition Interpolate.h:50
static qreal lerp(qreal from, qreal to, qreal t)
Definition Interpolate.h:41
Type-specific linear interpolation and path-distance for AnimatedValue<T>.
Definition Interpolate.h:36
Definition Interpolate.h:155
qreal b
Definition Interpolate.h:156
qreal L
Definition Interpolate.h:156
qreal a
Definition Interpolate.h:156