瀏覽代碼

Bresenham: fonctionne du tonnerre!

unknown 10 年之前
父節點
當前提交
b433a37ded
共有 3 個文件被更改,包括 320 次插入65 次删除
  1. 224 9
      DMonde.ppr
  2. 1 2
      lib/Pinceau.py
  3. 95 54
      lib/br.py

+ 224 - 9
DMonde.ppr

@@ -182,7 +182,6 @@ DMonde
 			lib\test.py
 			lib\VueEditionForme.py
 			lib\dmF.py
-			lib\bresenham.py
 		-parties
 			-Partie1
 				-journal
@@ -202,12 +201,66 @@ DMonde
 3=lib\Case.py
 4=lib\Pinceau.py
 5=lib\bresenham.py
+6=lib\ui\corbeille_ui\dmOngletsH.py
+7=lib\ui\corbeille_ui\dmtableattaques - Copie.py
+8=lib\ui\corbeille_ui\dmtableattaques_tableAttaques.py
+9=lib\ui\dm.py
+10=lib\ui\dmOngletsH.py
+11=lib\ui\ecran_creerPlateau.py
+12=lib\ui\ecran_editionAttaques.py
+13=lib\ui\ecran_editionCombattant.py
+14=lib\ui\ecran_editionCreature.py
+15=lib\ui\ecran_editionDecor.py
+16=lib\ui\ecran_editionObjet.py
+17=lib\ui\ecran_editionQuantiteObjet.py
+18=lib\ui\ecran_editionTerrain.py
+19=lib\ui\ecran_explorateur.py
+20=lib\ui\ecran_gestionCombat.py
+21=lib\ui\ecran_panneauAttaques.py
+22=lib\ui\ecran_panneauPj.py
+23=lib\ui\ecran_principal.py
+24=lib\ui\ecran_selectionPj.py
+25=lib\ui\panneauImage.py
+26=lib\ui\ressource_rc.py
+27=lib\__init__.py
+28=lib\Actions.py
+29=lib\AEtoile.py
+30=lib\afficherSousMenu.py
+31=lib\Boucle.py
+32=lib\Cache - Copie.py
+33=lib\Cache.py
+34=lib\Combattant.py
+35=lib\Creature.py
+36=lib\Decor.py
+37=lib\EcranAffichageTexte.py
+38=lib\EcranChargerPlateau.py
+39=lib\EcranCreerPlateau.py
+40=lib\EcranEditionCombattant.py
+41=lib\EcranEditionDecor.py
+42=lib\EcranEditionObjet.py
+43=lib\EcranEditionTerrain.py
+44=lib\EcranFondPlateau.py
+45=lib\EcranGestionCombat.py
+46=lib\EcranSelectionPj.py
+47=lib\EffetsCase.py
+48=lib\EntreeSortie.py
+49=lib\fonctionsCommunes.py
+50=lib\Forme.py
+51=lib\frameAttaque.py
+52=lib\framePj.py
+53=lib\Inventaire.py
+54=lib\lancer.py
+55=lib\Objet.py
+56=lib\ObjetAction.py
+57=lib\outilsSvg.py
+58=lib\Partie.py
+59=lib\Pion.py
 [Selected Project Files]
 Main=
-Selected=lib\bresenham.py
+Selected=lib\ui\ecran_creerPlateau.py
 [DMonde.py]
 TopLine=14
-Caret=16,19
+Caret=38,27
 [lib\Plateau.py]
 TopLine=7
 Caret=1,39
@@ -216,11 +269,173 @@ BookMark1=9,1512
 TopLine=208
 Caret=13,225
 [lib\Case.py]
-TopLine=77
-Caret=22,92
+TopLine=131
+Caret=60,138
 [lib\Pinceau.py]
-TopLine=167
-Caret=23,175
+TopLine=165
+Caret=18,173
 [lib\bresenham.py]
-TopLine=138
-Caret=31,158
+TopLine=1
+Caret=44,10
+[lib\ui\corbeille_ui\dmOngletsH.py]
+TopLine=1
+Caret=1,1
+[lib\ui\corbeille_ui\dmtableattaques - Copie.py]
+TopLine=1
+Caret=1,1
+[lib\ui\corbeille_ui\dmtableattaques_tableAttaques.py]
+TopLine=1
+Caret=1,1
+[lib\ui\dm.py]
+TopLine=1
+Caret=1,1
+[lib\ui\dmOngletsH.py]
+TopLine=1
+Caret=1,1
+[lib\ui\ecran_creerPlateau.py]
+TopLine=1
+Caret=1,1
+[lib\ui\ecran_editionAttaques.py]
+TopLine=1
+Caret=1,1
+[lib\ui\ecran_editionCombattant.py]
+TopLine=1
+Caret=1,1
+[lib\ui\ecran_editionCreature.py]
+TopLine=1
+Caret=1,1
+[lib\ui\ecran_editionDecor.py]
+TopLine=1
+Caret=1,1
+[lib\ui\ecran_editionObjet.py]
+TopLine=1
+Caret=1,1
+[lib\ui\ecran_editionQuantiteObjet.py]
+TopLine=1
+Caret=1,1
+[lib\ui\ecran_editionTerrain.py]
+TopLine=1
+Caret=1,1
+[lib\ui\ecran_explorateur.py]
+TopLine=1
+Caret=1,1
+[lib\ui\ecran_gestionCombat.py]
+TopLine=1
+Caret=1,1
+[lib\ui\ecran_panneauAttaques.py]
+TopLine=1
+Caret=1,1
+[lib\ui\ecran_panneauPj.py]
+TopLine=1
+Caret=1,1
+[lib\ui\ecran_principal.py]
+TopLine=1
+Caret=1,1
+[lib\ui\ecran_selectionPj.py]
+TopLine=1
+Caret=1,1
+[lib\ui\panneauImage.py]
+TopLine=1
+Caret=1,1
+[lib\ui\ressource_rc.py]
+TopLine=1
+Caret=1,1
+[lib\__init__.py]
+TopLine=1
+Caret=1,1
+[lib\Actions.py]
+TopLine=1
+Caret=1,1
+[lib\AEtoile.py]
+TopLine=1
+Caret=1,1
+[lib\afficherSousMenu.py]
+TopLine=1
+Caret=1,1
+[lib\Boucle.py]
+TopLine=1
+Caret=1,1
+[lib\Cache - Copie.py]
+TopLine=1
+Caret=1,1
+[lib\Cache.py]
+TopLine=1
+Caret=1,1
+[lib\Combattant.py]
+TopLine=1
+Caret=1,1
+[lib\Creature.py]
+TopLine=1
+Caret=1,1
+[lib\Decor.py]
+TopLine=1
+Caret=1,1
+[lib\EcranAffichageTexte.py]
+TopLine=1
+Caret=1,1
+[lib\EcranChargerPlateau.py]
+TopLine=1
+Caret=1,1
+[lib\EcranCreerPlateau.py]
+TopLine=1
+Caret=1,1
+[lib\EcranEditionCombattant.py]
+TopLine=1
+Caret=1,1
+[lib\EcranEditionDecor.py]
+TopLine=1
+Caret=1,1
+[lib\EcranEditionObjet.py]
+TopLine=1
+Caret=1,1
+[lib\EcranEditionTerrain.py]
+TopLine=1
+Caret=1,1
+[lib\EcranFondPlateau.py]
+TopLine=1
+Caret=1,1
+[lib\EcranGestionCombat.py]
+TopLine=1
+Caret=1,1
+[lib\EcranSelectionPj.py]
+TopLine=1
+Caret=1,1
+[lib\EffetsCase.py]
+TopLine=1
+Caret=1,1
+[lib\EntreeSortie.py]
+TopLine=1
+Caret=1,1
+[lib\fonctionsCommunes.py]
+TopLine=1
+Caret=1,1
+[lib\Forme.py]
+TopLine=1
+Caret=1,1
+[lib\frameAttaque.py]
+TopLine=1
+Caret=1,1
+[lib\framePj.py]
+TopLine=1
+Caret=1,1
+[lib\Inventaire.py]
+TopLine=1
+Caret=1,1
+[lib\lancer.py]
+TopLine=1
+Caret=1,1
+[lib\Objet.py]
+TopLine=1
+Caret=1,1
+[lib\ObjetAction.py]
+TopLine=1
+Caret=1,1
+[lib\outilsSvg.py]
+TopLine=1
+Caret=1,1
+[lib\Partie.py]
+TopLine=1
+Caret=1,1
+[lib\Pion.py]
+TopLine=1
+Caret=1,1

+ 1 - 2
lib/Pinceau.py

@@ -170,8 +170,7 @@ class Pinceau():
         self.plateau.cases[coord].majEstCibleCurseur(actif)
 
     def selectionLigne(self, coord0, coord1):
-        retour = casesEntre(coord0, coord1, self.plateau.formeCases)
-#         retour = []
+        retour = ligne(coord0, coord1, self.plateau.formeCases)
         return retour
 
     def selectionRectangle(self, coord0, coord1, plein = True):

+ 95 - 54
lib/bresenham.py → lib/br.py

@@ -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