6 votes

Floor(X) modulo X est égal à X ?

Question rapide. Je travaille essentiellement sur un programme où nous avons une entité qui traverse une grille. Chaque fois qu'elle termine une "étape" (c'est-à-dire qu'elle passe de (0, 0) à (1, 0)), je dois déclencher un événement. Le mouvement de l'entité par image est calculé par :

frameMovement = entitySpeed * (frameDeltaMs / 1000)

et ensuite ajouté à la coordonnée X de l'entité. J'ai choisi d'utiliser des unités mondiales (1 unité mondiale correspond à 16 pixels) au lieu de pixels bruts pour le système de coordonnées, simplement pour des raisons de séparation. Le monde n'a pas besoin de savoir que la distance pour un carré est de 16 pixels - seul le système de dessin le sait.

En gros, j'essaie de trouver comment indiquer au système que l'unité a terminé un "pas". De toute évidence, en raison de la façon dont le mouvement de la trame est calculé, vous ne serez jamais exactement sur un nouveau carré, je dois donc "clipper" l'unité sur ce carré ou avoir une méthode qui renvoie "vrai" si nous sommes à une certaine distance du carré (qui pour l'instant, j'ai décidé d'être 0,05wu - environ 0,8 pixels du carré).

La fonction que j'ai jusqu'à présent est la suivante :

return Math.floor(x) % x == 0;

Je n'utilise que X, car j'essaie juste de le faire fonctionner pour le moment. Cependant, le problème que j'ai est que cette fonction semble renvoyer l'un des deux résultats suivants :

x = 0f;
System.out.println(Math.floor(x) % x);
> NaN

C'est normal, car 0 % 0 est en effet NaN. Je peux contourner ce problème sans problème. Cependant, le problème que j'ai en ce moment est l'autre résultat

x = 1f; // Or any number with 1sd > 0
System.out.println(Math.floor(x) % x);
> 1f

C'est-à-dire que l'autre résultat renvoie toujours la valeur de X, plutôt que le modulo correct (qui, si math.floor(x) et x sont égaux - c'est-à-dire que x est égal à 1f), devrait être 0.

Je ne suis pas tout à fait sûr de la cause de ce problème. Si vous avez des réponses à me donner ou des suggestions sur la façon dont je peux mieux résoudre ce problème, je suis tout ouïe.

TL;DR : J'ai besoin de savoir quand une Entité se déplace d'une coordonnée à la suivante. Les coordonnées (et la transition de l'Entité à travers celles-ci) sont stockées sous forme de flottant. Si une Entité est à mi-chemin de la traversée d'un carré, la coordonnée X de l'Entité est stockée comme 1.5, par exemple. Enfin, Floor(1.0) % 1.0 renvoie 1.0, et non 0.

EDIT :

Dans mon code, j'ai ceci

    System.out.println("x equals " + x + ". Math.floor(x)%x==Math.floor(x): "+(Math.floor(x)%x==Math.floor(x)));

Avec sortie http://pastebin.com/egDwj7Gs

EDIT 2 : Les images sont amusantes !

http://prntscr.com/1j193n

Le carré blanc est l'entité. Le carré rouge est simplement une grille dessinée. Chaque carré est de 16 par 16.

Comme vous pouvez le voir, le carré blanc est actuellement à (6,5, 0). J'ai besoin que le programme reconnaisse fondamentalement quand il passe (7, 0).

EDIT : Lee et moi avons eu une discussion, voici notre discussion : https://chat.stackoverflow.com/rooms/34727/discussion-between-neglected-and-lee-meador

Il a résolu le problème pour moi et j'ai donc accepté sa réponse comme correcte.

        float after = pos.x+changeInPosition;

        if (Math.floor(after) != Math.floor(pos.x)) {
            // We passed a boundary
        }
        pos.x = after;

4voto

Lee Meador Points 7902

Modulo signifie que nous divisons et prenons le reste (comme en 3ème année pour moi).

Alors...

10 % 9 is 1.

Et

10 % 10 is 0

Et

10.5 % 10.5 is 0. 

(Vous pourriez peut-être avoir des problèmes d'arrondi si vous aviez x = ...calculer 10,5... et ensuite x % x où vous obtiendriez un nombre juste inférieur à 10,5 ou juste supérieur à 0).

Donc, pour tous les entiers,

Floor(x) % x is 0.

Pour un nombre non entier, cela fonctionne différemment.

Floor(10.5) => 10 

et

10 % 10.5 is 10.

Ainsi, à l'exception de l'effet des erreurs d'arrondi dans la virgule flottante, Floor(x) % x est soit 0 (pour les entiers) soit Floor(x) pour les non-entiers.

Plus de

Vous pourriez peut-être savoir s'il a passé une ligne de la grille en comparant les positions avant et après :

if (Math.Floor(xAfterMoving / gridSize) != Math.floor(xBeforeMoving / gridSize)) {
    fireXGridCrossingEvent();
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X