IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Récupérer coordonnées overlapping


Sujet :

Python

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2009
    Messages : 27
    Par défaut Récupérer coordonnées overlapping
    Bonjour,
    j'aurais voulu savoir comment récupérer les coordonnées d'un overlapping avec tkinter.

    j'emploie
    can.find_overlapping(self.x+self.r, self.y+self.r, self.x-self.r, self.y-self.r)
    dans mon programme, et je voudrais pouvoir obtenir les coordonnées x et y de l'endroit ou ils se touchent.

    Merci de vos réponses

  2. #2
    Membre émérite
    Homme Profil pro
    heu...
    Inscrit en
    Octobre 2007
    Messages
    648
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : heu...

    Informations forums :
    Inscription : Octobre 2007
    Messages : 648
    Par défaut
    En Tkinter, je n'en ai aucune idée, néanmoins voici une façon d'obtenir la zone superposée (overlapped) de deux zones:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    >>> def separate_ranges(a,b):
        f=lambda a,b: all(x<b[0] for x in a) or all(x>=b[1] for x in a)
        return f(a,b) or f(b,a)
     
    >>> def overlaping_ranges(a,b):
        return not separate_ranges(a,b)
     
    >>> def get_overlaping_area(area_a,area_b):
    	a_xs,a_ys,a_xe,a_ye = area_a
    	b_xs,b_ys,b_xe,b_ye = area_b
    	a_x,b_x = (a_xs,a_xe),(b_xs,b_xe)
    	a_y,b_y = (a_ys,a_ye),(b_ys,b_ye)
    	if overlaping_ranges(a_x,b_x) and overlaping_ranges(a_y,b_y):
    		x=sorted(list(a_x+b_x))[1:3]
    		y=sorted(list(a_y+b_y))[1:3]
    		return sum(zip(x,y),())
     
     
    >>> get_overlaping_area((0,0,100,100),(50,50,150,150))
    (50, 50, 100, 100)
    >>> get_overlaping_area((0,0,100,100),(5,5,95,95))
    (5, 5, 95, 95)
    où une area = (object.x, object.y, object.x+object.width, object.y+object.height)

    A moins que je n'ai pas compris ce dont tu parle (ce qui est possible), tu ne peux obtenir seulement une coordonée x et y, cause collision (dans un contexte graphique) signifie superposition, et là c'est donc une zone que tu recherches. Même lors d'une collision en un seul point, cela reste une zone (de taille 0x0).

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2009
    Messages : 27
    Par défaut
    enfaite, je fais un programme ou l'utilisateur dessine avec la souris et tous les points de ce trait sont stoqués dans une liste.

    Ensuite, il y a une bille qui rebondit sur le trait.

    Mais j'aimerais pouvoir trouver la position ou la bille touche le trait pour pouvoir prendre la coordonnée suivante de la liste afin de pouvoir calculer la pente pour le rebond.

    j'ai essayé avec ca, mais ca ne trouve pas l'intersection à tous les coups et ca fait beaucoup de calculs pour pas grand chose
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     for n in range(-self.rayon, self.rayon):
                for o in range(-self.rayon, self.rayon):
                    if (self.x+n, self.y+o)in liste:
                        b=liste[liste.index((self.x+n, self.y+o))+1]
                        a=(self.x+n, self.y+o)
                        self.pente=(b[1]-a[1])/(b[0]-a[0])
    C'est pourquoi j'aimerais pouvoir faire plus ou moins la même chose avec find_overlapping ou autre chose

  4. #4
    Membre Expert

    Homme Profil pro
    Diverses et multiples
    Inscrit en
    Mai 2008
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Diverses et multiples

    Informations forums :
    Inscription : Mai 2008
    Messages : 662
    Par défaut
    Salut, voici un petit exemple de code qui crée un masque correspondant à la balle (un ensemble contenant toutes les coordonnées “dans” la balle), puis teste l’appartenance de chaque point de la ligne à ce masque… C’est vite fait (le code de génération du masque, notamment, ne produit pas forcément un résultat optimal), mais ça devrait te donner des idées

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    import math
     
    def get_ball_mask(radius):
        mask = set()
        for x in range(radius+1):
            for y in range(round(math.sqrt(radius**2 - x**2))+1):
                mask.update([(x, y), (-x, y), (x, -y), (-x, -y)])
        return mask
     
    def pos_ball_mask(mask, pos_x, pos_y):
        return set(((x+pos_x, y+pos_y) for x, y in mask))
     
    mask = get_ball_mask(10)
    print(mask)
     
    curr_mask = pos_ball_mask(mask, 20, 15)
    print(curr_mask)
     
    line = [(x, 10) for x in range(40)]
     
    for i, pix in enumerate(line):
        if pix in curr_mask:
            print("Intersection détectée avec liste[%i]"%i)
    Note que j’ai séparé génération du masque en coordonnées “absolues”, et génération du masque pour la position courante de la balle, pour des questions de performance…

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2009
    Messages : 27
    Par défaut
    Merci beaucoup pour ces réponses.

    est-ce que les différentes fonctions font bien les actions suivantes?

    fait une liste contenant tout les points de la bille

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pos_ball_mask(mask, pos_x, pos_y)
    s'occupe de modifier la liste pendant le déplacement de la bille

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    line = [(x, 10) for x in range(40)]
    fait une liste de tuple avec un x de 1 à 40 et de y=10, pourquoi le y ne varie pas?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for i, pix in enumerate(line):
        if pix in curr_mask:
            print("Intersection détectée avec liste[%i]"%i)
    si les valeurs de la ligne sont dans la liste des coordonnées de la bille, print...

  6. #6
    Membre Expert

    Homme Profil pro
    Diverses et multiples
    Inscrit en
    Mai 2008
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Diverses et multiples

    Informations forums :
    Inscription : Mai 2008
    Messages : 662
    Par défaut
    Citation Envoyé par cobe91 Voir le message
    Merci beaucoup pour ces réponses.

    est-ce que les différentes fonctions font bien les actions suivantes?

    fait une liste contenant tout les points de la bille
    Oui, avec la bille centrée sur (0, 0)… Ce masque est globalement circulaire (avec un rayon de radius pixels), mais encore une fois, mon code est simple mais pas forcément optimal*!

    Citation Envoyé par cobe91 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pos_ball_mask(mask, pos_x, pos_y)
    s'occupe de modifier la liste pendant le déplacement de la bille
    Plus précisément, elle décale les point du masque pour “centrer” la bille sur (pos_x, pos_y) –*ça reste à toi de calculer ces coordonnées, bien sûr.

    Citation Envoyé par cobe91 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    line = [(x, 10) for x in range(40)]
    fait une liste de tuple avec un x de 1 à 40 et de y=10, pourquoi le y ne varie pas?
    C’était juste pour créer une ligne vite fait, y peut évidemment varier tout comme x

    Citation Envoyé par cobe91 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for i, pix in enumerate(line):
        if pix in curr_mask:
            print("Intersection détectée avec liste[%i]"%i)
    si les valeurs de la ligne sont dans la liste des coordonnées de la bille, print...
    Exactement –*il y a “collision” entre bille et ligne… Évidemment, toi, tu feras autre chose qu’un bête print

    À propos, pour calculer ta pente, le mieux serait à mon avis d’utiliser les premier et dernier points de la ligne en collision avec la bille…

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2009
    Messages : 27
    Par défaut
    Merci beaucoup pour cette aide,malheureusement, ca ne marche pas à tous les coups.

    J'ai donc changé de méthode. Ma ligne est composée de pleins de petits bouts de ligne qui sont chacun un élément de classe. Comme cela, j'appelle can.find_overlapping(...)[1] et il me rend le numéro du segment et à partir de la, je calcule la pente du segment.

  8. #8
    Membre émérite
    Homme Profil pro
    heu...
    Inscrit en
    Octobre 2007
    Messages
    648
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : heu...

    Informations forums :
    Inscription : Octobre 2007
    Messages : 648
    Par défaut
    Pourtant, tu n'a pas forcement besoins d'en arriver là, le mask proposé par mont29 est un set de coordonées, une ligne (droite), c'est deux points. Il est donc très facile de créer un set des coordonées de la ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    def get_line_mask(coords_a, coords_b):
        res=set()
        xa,ya=coords_a
        xb,yb=coords_b
        x_dir = cmp(xb,xa)
        y_dir = cmp(yb,ya)
        if not x_dir: x_dir = 1
        if not y_dir: y_dir = 1
        for c in zip(range(xa,xb,x_dir),range(ya,yb,y_dir)):
            res.add(c)
        return res
    Puis par la suite, il te faut effectuer une intersection entre le mask de la balle et le mask de la ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    overlap=line_mask.intersection(ball_mask)
    a partir de là, si j'ai bien compris, tu veux obtenir les deux coordonées de la ligne "intersectée" (hum...), pour cela:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if overlap:
        coord_a,coord_b= min(overlap),max(overlap)
    Et voilà.

    Mais normalement tout cela devrait être inutile, la démarche de vérification de la présence d'un pixel de la ligne au sein du mask de la balle certifie la collision avec une ligne a, les deux point de cette ligne permettent de calculer la pente.

    La seule chose que j'ai à l'esprit qui ferait que la démarche proposée par mont29 (incluant, la surcharge inutile décrite ici) ne fonctionne pas, c'est dans le cas où la vélocité de ta balle serait trop importante... cad que l'incrément du déplacement est plus grand que le diamètre de la balle, ce qui peux éviter à la balle de toucher le trait.

    Edit : ... bah si t'as trouvé... c'est bien le principal

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Récupérer coordonnées gps Mobil java
    Par dmellorente dans le forum Développement Mobile en Java
    Réponses: 0
    Dernier message: 31/07/2009, 09h51
  2. Récupérer coordonnées Graphics2D
    Par Lebas dans le forum Graphisme
    Réponses: 3
    Dernier message: 19/07/2008, 14h44
  3. Récupérer coordonnées pixels
    Par Invité dans le forum 2D
    Réponses: 8
    Dernier message: 04/06/2008, 17h31
  4. Récupérer Coordonnées d'une Cellule avec un Vlookup
    Par mouimouic dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 23/01/2008, 19h34
  5. Réponses: 9
    Dernier message: 19/12/2005, 14h24

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo