2010-05-10 10 views
2

J'ai un problème mathématique qui est un peu difficile à décrire, mais je vais essayer quand même. Dans un scénario, j'ai un certain nombre d'images, dont je veux sauter un certain nombre d'images, qui devraient être réparties uniformément le long de la chronologie.sauter un certain nombre de cadres sur une timeline

par exemple j'ai 10 images et je veux sauter 5, alors la solution est facile: nous sautons toutes les deux images. 10/5 = 2

if (frame%2 == 0) 
    skip(); 

mais si la division ci-dessus ne résulte en un nombre flottant? Par exemple dans 44 images je veux sauter 15 fois. comment puis-je déterminer les 15 cadres qui devraient être sautés?

bascially je cherche un algorithme qui distribue que 15 images aussi uniformément que possible le long des 44 images. il ressemblera probablement à quelque chose comme sauter après 2 et ensuite après 3 images alternativement.

merci!

Répondre

3

Vous pouvez garder une valeur flottante supplémentaire, t, qui correspond à l'image suivante à ignorer, et la met à jour chaque fois que vous l'ignorez. Comme ceci:

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; 
} 
+0

Ceci est en général égal au revêtement de sol du résultat puisque la coulée d'un point flottant sur un int (habituellement) est fonctionnellement égale au revêtement de sol. La mauvaise partie est que le comportement n'est pas toujours défini (en fonction de la langue et du système d'exploitation). – Henri

+0

@Henri: il est égal à plancher le t, mais il n'est pas égal à plancher du diviseur. Cette approche va être plus précise que votre solution. – Unreason

+0

Simple et efficace, bien que je préférerais que le «sol» soit explicite plutôt que caché dans la distribution;) –

2

Vous ne pouvez évidemment pas toujours le faire vraiment de manière égale dans le cas où le nombre d'images que vous voulez sauter n'est pas un diviseur du nombre total d'images. Donc, s'il est important de toujours sauter au moins le nombre de cadres que vous voulez, effectuez un étage sur la division (totalFrames/framesToSkip). Cela dit, vous pouvez appliquer le même tour que vous avez proposé.

if (totalFrames % floor(totalFrames/framesToSkip) == 0) 
    skip(); 

Notez que dans le cas de 44 et 15 vous sauter beaucoup plus que 15. L'autre acceuillent à Ceil au lieu de plancher, dans ce cas, vous passez l'habitude de 15 cadres mais 14 cadres.

Une autre solution est de faire un tour entier le plus proche, c'est une meilleure approximation, cependant, vous parfois sauter plus souhaité et parfois moins souhaité, mais en moyenne, vous ont de meilleurs résultats

+0

merci. oui je sais que je ne peux pas exactement rencontrer ce nombre avec la division. C'est pourquoi je demande un autre moyen de distribuer ces cadres qui devraient être ignorés. – clamp

1

Je suis parti d'écrire une solution qui améliore d'Igor, mais à la fin la seule amélioration que j'ai vraiment trouvé était d'affirmer explicitement que round(t) doit être utilisé au lieu de (int)t. Donc, voici la solution d'Igor (avec certains noms de variables changés, c'est plus évident et en utilisant la fonction round).

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; 
} 

L'utilisation round(t) fera ce soit le plus juste et essayer de laisser tomber le cadre (int) qui est le plus proche du cadre de chute idéal (double), tout en maintenant la minuterie complète de précision (next_skip).

Couple de notes

  • prendre soin si le cadre commence par 0 ou 1 et ajuster en conséquence,
  • prendre soin que frame_num n'est pas> skips_num (si elle est assurez-vous d'augmenter next_skip de plus qu'un cadre chaque fois qu'une trame est tombé, sinon vous allez cesser d'augmenter la next_skip et pas plus de cadres déposerons)
2

Il me semble que le problème de mélange skips avec les non-skips est un peu comme le pr oblem de mélanger les étapes qui vont en diagonale vers le bas avec des étapes qui vont tout droit en dessinant une ligne avec des pixels. Le problème de dessin au trait est résolu dans les moindres détails à http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm

+0

très bonne remarque! – clamp

Questions connexes