Sur une map toroïdale, type [n,m] répétée à l'infinie à l'horizontale et à la verticale, il y a une infinité de vecteurs qui vont de [x,y] à [u,v], sous la forme:
Maintenant, si tu cherches la distance entre [x,y] et [u,v], on va considérer que tu cherche le vecteur de cette famille dont la longueur est la plus faible, puis que tu prend la longueur de ce vecteur. En d'autres mots, tu cherches la plus courte distance entre [x,y] et [u,v] en te servant (ou non) du fait que la map "boucle" N/S et E/O.
Les modulos sont là pour cela!
Avec le [0,0] au centre de la map, et une map qui va de [-n/2, -m/2] à [n/2, m/2] et donc les points sont modulo [n,m] (un peu comme les angles d'un cercle qui vont de -Pi à Pi, et qui sont modulo 2Pi).
Je vais quand même vérifier l'équation, pour être sûr
Petit oubli des -n/2 et -m/2:
Cela marche également avec la norme infinie que tu utilises:
Mais ici, je considère que les modulo sont les restes positifs dans la division par n ou par m. Or, dans la plupart des langages (dont PHP), on a:
Ce qui ne nous arrange pas...
Je vais réarranger la formule pour ces langages-là.
Pour des langages dont le modulo % renvoie "-13 % 64 = -13", comme PHP, il faut employer:
Au fait, attention avec les map toroïdales:
Un rayon infini lancé à l'horizontal sur une map toroïdale touchera forcément une cible, soit il touchera le lanceur en lui revenant dans le dos, soit il parcourra toute la map et touchera forcément une cible, s'il en existe une qui possède une surface. S'il n'y a que des points sur la map, je ne suis pas certain de ce qui se passera...
Code :
Vecteurs( [x,y] [u,v] ) = { (p,q) entiers relatifs: [ u-x+p*n, v-y+q*m ] }
Maintenant, si tu cherches la distance entre [x,y] et [u,v], on va considérer que tu cherche le vecteur de cette famille dont la longueur est la plus faible, puis que tu prend la longueur de ce vecteur. En d'autres mots, tu cherches la plus courte distance entre [x,y] et [u,v] en te servant (ou non) du fait que la map "boucle" N/S et E/O.
Les modulos sont là pour cela!
Code :
Distance( [x,y] [u,v] ) = sqrt( ((u-x+n/2)%n)² + ((v-y+m/2)%m)² )
Avec le [0,0] au centre de la map, et une map qui va de [-n/2, -m/2] à [n/2, m/2] et donc les points sont modulo [n,m] (un peu comme les angles d'un cercle qui vont de -Pi à Pi, et qui sont modulo 2Pi).
Je vais quand même vérifier l'équation, pour être sûr
Petit oubli des -n/2 et -m/2:
Code :
Distance( [x,y] [u,v] ) = sqrt( ((u-x+n/2)%n - n/2)² + ((v-y+m/2)%m - m/2)² )
Cela marche également avec la norme infinie que tu utilises:
Code :
Distance( [x,y] [u,v] ) = ABS((u-x+n/2)%n - n/2) + ABS((v-y+m/2)%m - m/2)
Mais ici, je considère que les modulo sont les restes positifs dans la division par n ou par m. Or, dans la plupart des langages (dont PHP), on a:
Citation :-13 % 64 = -13
Ce qui ne nous arrange pas...
Je vais réarranger la formule pour ces langages-là.
Pour des langages dont le modulo % renvoie "-13 % 64 = -13", comme PHP, il faut employer:
Code :
Distance1( [x,y] [u,v] ) = ABS((u-x+3*n/2)%n - n/2) + ABS((v-y+3*m/2)%m - m/2)
Distance2( [x,y] [u,v] ) = sqrt( ((u-x+3*n/2)%n - n/2)² + ((v-y+3*m/2)%m - m/2)² )
Au fait, attention avec les map toroïdales:
Un rayon infini lancé à l'horizontal sur une map toroïdale touchera forcément une cible, soit il touchera le lanceur en lui revenant dans le dos, soit il parcourra toute la map et touchera forcément une cible, s'il en existe une qui possède une surface. S'il n'y a que des points sur la map, je ne suis pas certain de ce qui se passera...