我试图将动画更改为根据贝塞尔曲线具有平滑的缓入/缓出。然而,结果并不尽如人意。非常感谢您的反馈和想法如何做得更好。
以显示动画(从 GIF 中提取)的一系列 .png 文件形式提供的数据。 这包含在 github 的 data_src 目录中。 (请参阅下面的链接)。
用户界面有2个窗口:
单击部署按钮时,.png 文件序列将根据贝塞尔曲线形状调整形状 - 即先缓入后缓出。实时播放动画会显示 Ease-in,Ease-out 动作。
GitHub 链接:
https://github.com/mrglobal/bezier_easeinout。 使用的IDE是QT Creator。用 C++ 编写的代码
为简单起见,我在 bezier_curve.cpp 中提供了一些硬编码的 Ease-In 和 Ease-Out 模型。该代码不包括带有控制点的用户界面,以允许用户动态创建贝塞尔曲线。有关硬编码的 c0、p0、p1、c1 值,请参阅 Bezier_Curve::deploy_bezier_curve。
代码的主体展示了我如何遵循贝塞尔曲线形状,试图在“实时”播放时将原始动画帧序列转换为缓入/缓出序列。
更详细的代码排列结构说明请看mainwindow.cpp。我已经非常广泛地添加了评论 - 希望它们有用。注意我没有优化代码以便于理解。
贝塞尔曲线的解释如下图所示。基本上我叠加了 N 帧的动画序列(在本例中为 142 帧)。示例仅显示 4 个点以供说明。在每一点,将贝塞尔曲线的切线与下一点的切线进行比较。本质上它是沿着贝塞尔曲线上的点的切线的 dy/dx。请注意,点 0 处的第一个 dy/dx 是贝塞尔曲线上该点与 2 个端点之间的直线减去 begin angle 的切线。见下图[2]
然后将每个点的dy/dx值通过以下公式转换为帧数:
(dy/dx in degrees)/(begin angle in degrees)
分母的原因是开始角度是偏离标准(线性线)的帧数为 0 的位置。因此(至少对我而言)将其作为分母将 dy/dx 转换为数字是有意义的框架偏离规范。
转换后的值存储为: /* * 跳度指数 = (19, -4, -3, 0.... * 其中每个数字: * +N : 跳转到第 N 帧 * 例如+19 :跳转到第 19 帧 * -N : 通过将相同的帧内容扩展 N 次来延迟前向序列 * 例如-4 扩展同一帧 4 次 * 0 : 保持顺序 * */
下一步是遍历此列表并从第一帧开始重新插入动画帧。按照示例,这将转换为动画帧序列:
+19: 帧 0 的帧图像位于帧索引 19
-4 第 1、2、3、4 帧的帧图像位于帧索引 20
-3 第 5、6、7 帧的帧图像位于帧索引 21
0 第 8 帧具有帧图像帧索引 22
结果是有问题的,因为即使在简单的缓入贝塞尔曲线上,它似乎也没有遵循平滑的过渡。此外,当存在缓入和缓出贝塞尔曲线时,这种从左到右帧图像移动的方法会超出跑道。
这是最小代码:
车架等级:
#include <QObject>
#include <QWidget>
#include <QImage>
#define NUMBER_FRAMES 142
#define INTER_FRAME_INTERVAL_MSECS 35
class Frame : public QWidget
{
Q_OBJECT
public:
explicit Frame(QWidget *parent = nullptr);
int index;
int src_index;
int delta;
bool overwritten;
QString filename;
QImage *image;
signals:
protected:
void paintEvent(QPaintEvent *event);
};