|
|
@@ -2,10 +2,28 @@
|
|
|
from __future__ import division
|
|
|
from math import *
|
|
|
from dmF import *
|
|
|
-
|
|
|
-dbg = True
|
|
|
|
|
|
-def casesEntre(coord1, coord2, formeCases = "H"):
|
|
|
+def ligne(coord1, coord2, formeCases = "H"):
|
|
|
+ if coord1 != coord2:
|
|
|
+ if len(coord1) == 2 and len(coord2) == 2:
|
|
|
+ retour = _ligne2d(coord1, coord2, formeCases)
|
|
|
+ elif len(coord1) == 3 and len(coord2) == 3:
|
|
|
+ retour = _ligne3d(coord1, coord2, formeCases)
|
|
|
+ elif len(coord1) == 2 and len(coord2) == 3:
|
|
|
+ x1, y1 = coord1
|
|
|
+ retour = _ligne3d((x1, y1, 0), coord2, formeCases)
|
|
|
+ elif len(coord1) == 2 and len(coord2) == 3:
|
|
|
+ x2, y2 = coord2
|
|
|
+ retour = _ligne3d(coord1, (x2, y2, 0), formeCases)
|
|
|
+ else:
|
|
|
+ retour = [coord1]
|
|
|
+ else:
|
|
|
+ retour = [coord1]
|
|
|
+ return retour
|
|
|
+
|
|
|
+def _ligne2d(coord1, coord2, formeCases = "H"):
|
|
|
+ """renvoie la liste des cases traversees par la ligne entre les cases 1 et 2
|
|
|
+ prend en parametre des coord de la forme (x,y)"""
|
|
|
x1, y1 = coord1
|
|
|
x2, y2 = coord2
|
|
|
|
|
|
@@ -16,19 +34,33 @@ def casesEntre(coord1, coord2, formeCases = "H"):
|
|
|
y1, y2 = y2, y1
|
|
|
inversee = True
|
|
|
|
|
|
- if coord1 != coord2:
|
|
|
- if formeCases == "H":
|
|
|
- retour = _brH(x1, y1, x2, y2)
|
|
|
- else:
|
|
|
- retour = _brC(x1, y1, x2, y2)
|
|
|
+ if formeCases == "H":
|
|
|
+ retour = _brH(x1, y1, x2, y2)
|
|
|
else:
|
|
|
- retour = [coord1]
|
|
|
-
|
|
|
+ retour = _brC(x1, y1, x2, y2)
|
|
|
+
|
|
|
# retourne la liste si les coordonnees ont ete interverties
|
|
|
if inversee:
|
|
|
retour.reverse()
|
|
|
return retour
|
|
|
|
|
|
+
|
|
|
+def _ligne3d(coord1, coord2, formeCases = "H"):
|
|
|
+ """renvoie la liste des cases traversees par la ligne entre les cases 1 et 2
|
|
|
+ prend en parametre des coord de la forme (x,y, z)"""
|
|
|
+ x1, y1, z1 = coord1
|
|
|
+ x2, y2, z2 = coord2
|
|
|
+ ligne = _ligne2d((x1, y1), (x2, y2), formeCases)
|
|
|
+ ligneZ = _brC(0, z1, (len(ligne)-1), z2)
|
|
|
+
|
|
|
+ retour = []
|
|
|
+ for coordZ in ligneZ:
|
|
|
+ dist, z = coordZ
|
|
|
+ x, y = ligne[dist]
|
|
|
+ retour.append((x, y, z))
|
|
|
+
|
|
|
+ return retour
|
|
|
+
|
|
|
def _brC(x1, y1, x2, y2):
|
|
|
"""Algorithme ligne de Bresenham (pour cases carrees)"""
|
|
|
|
|
|
@@ -63,11 +95,9 @@ def _brC(x1, y1, x2, y2):
|
|
|
def _brH(x1, y1, x2, y2):
|
|
|
"""Algorithme ligne de Bresenham (pour cases hexagonales)"""
|
|
|
#calcul selon secteur
|
|
|
- if abs(x2 - x1) < (2*(y2-y1) + abs(x2 % 2) - abs(x1 % 1)):
|
|
|
- if dbg: print "*** V"
|
|
|
+ if abs(x2 - x1) < (2*abs((y2-y1)) + abs(x2 % 2) - abs(x1 % 1)):
|
|
|
retour = _brH_v(x1, y1, x2, y2)
|
|
|
else:
|
|
|
- if dbg: print "*** H"
|
|
|
retour = _brH_h(x1, y1, x2, y2)
|
|
|
return retour
|
|
|
|
|
|
@@ -75,32 +105,47 @@ def _brH_h(x1, y1, x2, y2):
|
|
|
"""Algorithme ligne de Bresenham (pour cases hexagonales - secteur horizontal)"""
|
|
|
# Calcul des ecarts
|
|
|
dx = x2 - x1
|
|
|
- dy = y2 - y1
|
|
|
-
|
|
|
+ dy = y2 - y1
|
|
|
+ if (x1 + x2) % 2 == 1:
|
|
|
+ if x1 % 2 == 0:
|
|
|
+ dy += 0.5
|
|
|
+ else:
|
|
|
+ dy -= 0.5
|
|
|
+
|
|
|
# Calcul de l'erreur (l'ecart qui doit s'accumuler au fur et a mesure qu'on avance)
|
|
|
- error = 0.0
|
|
|
- pasY = 1 if y1 < y2 else -1
|
|
|
- if dbg: print "# de: {}|{} vers {}|{}".format(x1, y1, x2, y2)
|
|
|
+ k = dy / dx
|
|
|
+ pas = 1
|
|
|
|
|
|
# on itere sur les coordonnees de la boite qui contient les coordonnees 1 et 2
|
|
|
retour = []
|
|
|
- x, y = x1, y1
|
|
|
- #ky: decalage entre cases paires et impaires
|
|
|
- ky = 0
|
|
|
+ d = 0.0
|
|
|
+ pos = (x1, y1)
|
|
|
+ retour.append(pos)
|
|
|
|
|
|
- while not x > x2:
|
|
|
- if dbg: print " > {}, {}, {}, {}".format(x, y, pasY * ky, error)
|
|
|
-
|
|
|
- coord = (x, y + (pasY * ky))
|
|
|
- retour.append(coord)
|
|
|
-
|
|
|
- x += 1
|
|
|
- ky = 0.5 if (x - x1) % 2 == 1 else 0
|
|
|
+ while pos != (x2, y2):
|
|
|
+ d += k*pas
|
|
|
+ if d > 0:
|
|
|
+ #on se deplace vers la case en dessous a droite
|
|
|
+ x, y = pos
|
|
|
+ if x %2 == 0:
|
|
|
+ pos = x + 1, y
|
|
|
+ else:
|
|
|
+ pos = x + 1, y + 1
|
|
|
+ retour.append(pos)
|
|
|
+ d -= 0.5
|
|
|
+ else:
|
|
|
+ #on se deplace vers la case au dessus a droite
|
|
|
+ x, y = pos
|
|
|
+ if x %2 == 0:
|
|
|
+ pos = x + 1, y - 1
|
|
|
+ else:
|
|
|
+ pos = x + 1, y
|
|
|
+ retour.append(pos)
|
|
|
+ d += 0.5
|
|
|
|
|
|
- error += (0.9087 * (abs(dy) / dx))
|
|
|
- if error > 0.5 + ky:
|
|
|
- y += pasY
|
|
|
- error -= 1
|
|
|
+ if pos[0] > x2:
|
|
|
+ retour = []
|
|
|
+ break
|
|
|
|
|
|
return retour
|
|
|
|
|
|
@@ -109,20 +154,20 @@ def _brH_v(x1, y1, x2, y2):
|
|
|
#on prend comme unite la demi largeur: u = 0.5773
|
|
|
#la demi hauteur d'un hexa vaut donc 0.8860u, ou sqrt(3)/2
|
|
|
#[a revoir] une fois cela pose, on muliplie tout par 4dy afin d'eviter nombres flottants et divisions
|
|
|
+ sens = 1 if y2 > y1 else -1
|
|
|
|
|
|
# Calcul des ecarts
|
|
|
dx = 1.5 * (x2 - x1) #en x, on a 1.5u de centre a centre
|
|
|
- dy = y2 - y1 #en y, on compte en demi hauteurs
|
|
|
+ dy = sens * (y2 - y1) #en y, on compte en demi hauteurs
|
|
|
if (x1 + x2) % 2 == 1:
|
|
|
if x1 % 2 == 0:
|
|
|
- dy += 0.5
|
|
|
+ dy += sens*0.5
|
|
|
else:
|
|
|
- dy -= 0.5
|
|
|
+ dy -= sens*0.5
|
|
|
|
|
|
- #k est la tangente de l'angle par rapport a la verticale
|
|
|
- k = dx/(dy*sqrt(3))
|
|
|
+ k = dx/(dy*sqrt(3)) #k est la tangente de l'angle par rapport a la verticale
|
|
|
pas = 0.5*sqrt(3) #on avance par demi hauteurs
|
|
|
-
|
|
|
+
|
|
|
retour = []
|
|
|
d = 0.0 #decalage
|
|
|
pos = (x1, y1)
|
|
|
@@ -131,27 +176,23 @@ def _brH_v(x1, y1, x2, y2):
|
|
|
while pos != (x2, y2):
|
|
|
d += (k*pas)
|
|
|
if d <= 0.5:
|
|
|
- #on se deplace vers la case en dessous
|
|
|
+ #on se deplace vers la case en dessous (ou au dessus)
|
|
|
x, y = pos
|
|
|
- pos = x, y+1
|
|
|
+ pos = x, y + sens
|
|
|
retour.append(pos)
|
|
|
d += (k*pas)
|
|
|
else:
|
|
|
- #on se deplace vers la case en dessous a droite
|
|
|
+ #on se deplace vers la case en dessous (ou au dessus) a droite
|
|
|
x, y = pos
|
|
|
- if x %2 == 0:
|
|
|
- pos = x + 1, y
|
|
|
+ if (x %2 == 0 and sens == 1) or (x % 2 == 1 and sens == -1):
|
|
|
+ pos = x + 1, y
|
|
|
else:
|
|
|
- pos = x + 1, y + 1
|
|
|
+ pos = x + 1, y + sens
|
|
|
retour.append(pos)
|
|
|
d -= 1.5
|
|
|
- if dbg: print " > d = {} -> {}".format(d, pos)
|
|
|
-
|
|
|
- return retour
|
|
|
-
|
|
|
-# print casesEntre((0,0), (4,5))
|
|
|
-# print casesEntre((1,0), (5,5))
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
+ if sens*pos[1] > sens*y2:
|
|
|
+ retour = []
|
|
|
+ break
|
|
|
|
|
|
+ return retour
|