我有一个数学问题,有点难以描述,但无论如何我都会试一试。
在时间轴中,我有多个帧,我想跳过一定数量的帧,这些帧应该沿着时间轴均匀分布。
例如我有10帧,我想跳过5,然后解决方案很简单:我们跳过每隔一帧。 10/5 = 2
if (frame%2 == 0)
skip();
但是如果上面的除法确实导致浮动数字怎么办?
例如在44帧中,我想跳过15次。如何确定应跳过的15帧?基本上我正在寻找一种算法,它沿着44帧尽可能均匀地分布15帧。 它可能看起来像是在2之后跳过然后在3帧之后交替出现。
谢谢!
答案 0 :(得分:3)
您可以保留一个额外的浮点值t,它对应于要跳过的下一帧,并在每次跳过时更新它。像这样:
int frame_num = 44;
int skips_num = 15;
double dt =((double)(frame_num))/skips_num;
double t = 0.0;
...
// then, in your loop
if (frame == (int)t) {
skip();
t += dt;
}
答案 1 :(得分:2)
如果要跳过的帧数不是帧总数的除数,显然不能总是这样做。因此,如果始终跳过至少所需的帧数非常重要,请在分区上执行下限(totalFrames / framesToSkip)。
话虽如此,您可以应用与您提议的相同技巧。
if (totalFrames % floor(totalFrames/framesToSkip) == 0)
skip();
请注意,在44和15的情况下,你跳过15以上。另一个可能性是ceil而不是floor,在这种情况下你不会跳过15帧而是14帧。
另一个解决方案是对最接近的整数进行舍入,这是一个更好的近似值,但是,有时候你跳过的时间比希望的要多,有时甚至比希望的要少,但平均来说你有更好的结果
答案 2 :(得分:2)
让我觉得混合跳过非跳跃的问题有点像混合步骤的问题,这些步骤沿着对角线向下,在绘制带有像素的线条时直线穿过。线条绘制问题在http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
处得到了非常详细的解决答案 3 :(得分:1)
我开始写一个改进Igor的解决方案,但最后我真正发现的唯一改进是明确说明应该使用round(t)
而不是(int)t
。所以这里是Igor的解决方案(改变了一些变量名,因此更明显并使用了圆函数)。
int frame_num = 44;
int skips_num = 15;
double frames_between_skips =((double)(frame_num))/skips_num;
double next_skip = 0.0;
...
// then, in your loop
if (current_frame == round(next_skip)) {
skip();
next_skip += frames_between_skips;
}
使用round(t)
将使其最公平,并尝试删除最接近理想丢帧(双)的帧(int),同时保持完整精度计时器(next_skip
)。
几个笔记
next_skip
增加一帧以上,否则你将停止增加next_skip
并且不再删除帧数。