(Sur edit: j'ai ajouté une deuxième fonction qui permet la version de coordonnées cartésiennes à obtenir directement.)
Je suis arrivé ce bien avant ma tête a explosé. C'est une forme fermée dans le sens où elle donne les coordonnées de dire le millionième carré sans avoir besoin de les placer une par une en boucle. L'écrire ne donnerait pas une bonne formule mais vous pourriez écrire comme une formule définie par morceaux avec 8 pièces. La réponse est donnée en coordonnées de grille basées sur 1. La première coordonnée vous indique combien de cases vous êtes à droite ou à gauche de l'axe des ordonnées et la seconde coordonnée à quelle distance vers le haut ou vers le bas. A partir de ces chiffres, il est relativement facile, par ex. obtenir les coordonnées cartésiennes de leur coin supérieur gauche. J'implémenté dans le python:
from math import sqrt, ceil
def coordinates(m):
n = ceil(sqrt(m)/2) #shell number
i = m - 4*(n-1)**2 #index in shell
if i <= n:
return (n,-i)
elif i <= 2*n-1:
return (2*n - i, -n)
elif i <= 3*n - 1:
return (2*n - 1 - i, -n)
elif i <= 4*n - 2:
return (-n, -4*n + 1 + i)
elif i <= 5*n - 2:
return (-n, -4*n + 2 + i)
elif i <= 6*n - 3:
return (-6*n + 2 + i, n)
elif i <= 7*n - 3:
return (-6*n + 3 + i,n)
else:
return (n, 8*n -3 - i)
Pour obtenir le (x, y) les coordonnées cartésiennes des coins supérieurs gauche de la (i, j) coordonnées de grille vous pouvez utiliser la fonction suivante, qui a un paramètre de largeur en option pour permettre carrés non unitaires:
def cartesianFromGrid(i,j,w = 1):
x = w * (i if i < 0 else i - 1)
y = w * (j if j > 0 else j + 1)
return (x,y)
Il est possible d'obtenir directement les coordonnées cartésiennes du coin supérieur gauche directement sans passer d'abord par coordonnées de la grille. La formule résultante implique moins de cas (puisque je n'ai pas besoin de passer de 1 directement à -1 ou vice versa) bien que je garde les deux formules dans la réponse puisque la perspective de la grille est plus naturelle:
def cartCoordinates(m):
n = ceil(sqrt(m)/2) #shell number
i = m - 4*(n-1)**2 #index in shell
if i <= n:
return (n-1,-i+1)
elif i <= 3*n - 1:
return (2*n - 1 - i, -n + 1)
elif i <= (5*n - 2):
return (-n, -4*n + 2 + i)
elif i <= 7*n - 3:
return (-6*n + 2 + i, n)
else:
return (n-1, 8 * n - 3 - i)
def cartCoordinates(m):
n = ceil(sqrt(m)/2) #shell number
i = m - 4*(n-1)**2 #index in shell
if i <= n:
return (n-1,-i+1)
elif i <= 3*n - 1:
return (2*n - 1 - i, -n + 1)
elif i <= (5*n - 2):
return (-n, -4*n + 2 + i)
elif i <= 7*n - 3:
return (-6*n + 2 + i, n)
else:
return (n-1, 8 * n - 3 - i)
sortie pour 1-16:
>>> for n in range(1,17):
print(n, ': grid coords =', coordinates(n),
'Cartesian =',cartesianFromGrid(*coordinates(n)))
1 : grid coords = (1, -1) Cartesian = (0, 0)
2 : grid coords = (-1, -1) Cartesian = (-1, 0)
3 : grid coords = (-1, 1) Cartesian = (-1, 1)
4 : grid coords = (1, 1) Cartesian = (0, 1)
5 : grid coords = (2, -1) Cartesian = (1, 0)
6 : grid coords = (2, -2) Cartesian = (1, -1)
7 : grid coords = (1, -2) Cartesian = (0, -1)
8 : grid coords = (-1, -2) Cartesian = (-1, -1)
9 : grid coords = (-2, -2) Cartesian = (-2, -1)
10 : grid coords = (-2, -1) Cartesian = (-2, 0)
11 : grid coords = (-2, 1) Cartesian = (-2, 1)
12 : grid coords = (-2, 2) Cartesian = (-2, 2)
13 : grid coords = (-1, 2) Cartesian = (-1, 2)
14 : grid coords = (1, 2) Cartesian = (0, 2)
15 : grid coords = (2, 2) Cartesian = (1, 2)
16 : grid coords = (2, 1) Cartesian = (1, 1)
Dans le cas où vous vous demandiez:
>>> coordinates(1000000)
(500, 1)
Cette dernière réponse est logique puisque l'un carré millionième est la clé de voûte d'une grille de 1000x1000 de carrés.
j'ai utilisé ci-dessus pour placer des carrés de couleur sur un widget toile tkinter:
Vous devriez indiquer l'ordre. Je suppose que tous les carrés sont la première spirale autour de l'origine et les points sont les seconds? –
Que voulez-vous dire par les coordonnées? Centre de carré? Coin gauche? Par exemple - quel numéro attribueriez-vous au carré noir? (2, -2)? –
@ r3oath Deux commentaires: 1) Vous devez étiqueter cette question avec le langage de programmation dans lequel vous envisagez de mettre en œuvre votre solution, et 2) vous devriez revoir les réponses bien réfléchies données ci-dessous. –