Bonjour, j'ai fait dans mon jeu une fonction qui detecte une intersection entre 2 rectangles, elle reçoit 2 rectangles r1 et r2 de type ( ( int, int ) , ( int, int ) ) et elle return True si les deux rectangles se superposent et False si ce n'est pas le cas, la fonction la voici :
def collision_rect(r1,r2):
((a1, b1), (c1, d1)) = r1
((a2, b2), (c2, d2)) = r2
if a2 <= a1 and a1 <= c2:
if (b1 <= b2 and b2 <= d1) or (b2 <= b1 and b1 <= d2):
return True
elif a1 <= a2 and a2 <= c1:
if (b2 <= b1 and b1 <= d2) or (b1 <= b2 and b2 <= d1):
return True
return False (b1 <= b2 and b2 <= d1) et (b2 <= b1 and b1 <= d2) represente le cas ci dessus qu'on appelera le cas1:
tandis que (b2 <= b1 and b1 <= d2) et (b1 <= b2 and b2 <= d1) represente le cas ci dessus qu'on appelera le cas2 :
j'ai tester avec des cas simple, le cas n°2 à l'air de fonctionner, par contre le n°1 il ne détecte pas :s vous auriez une idée de pourquoi ? ![]()
Aprés quelque test supplémentaire j'ai réportorier les cas dans le cas n°1 où elle fonctionner les cas où elle ne fonctionner pas

Bon personnellement j'ai un peu raccourci le tout mais voilà mon code pour regarder entre deux rectangles :
def collision_rect(r1,r2):
x1,y1,w1,h1 = r1[0][0], r1[0][1], r1[1][0] - r1[0][0], r1[1][1] - r1[0][1]
x2,y2,w2,h2= r2[0][0], r2[0][1], r2[1][0] - r2[0][0], r2[1][1] - r2[0][1]
return [True,False][x1 >= x2 + w2 or x1 + w1 <= x2 or y1 >= y2 + h2 or y1 + h1 <= y2]
En gros tu regards si un des points est dehors, si oui le booléen renvoie True donc choisit la case [1] du tableau du return --> False
Si aucun des points n'est dehors, le booléen renvoie False donc choisit la case [0] du tableau du return --> True
Le 28 novembre 2016 à 20:20:31 Elmohe a écrit :
Bon personnellement j'ai un peu raccourci le tout mais voilà mon code pour regarder entre deux rectangles :def collision_rect(r1,r2): x1,y1,w1,h1 = r1[0][0], r1[0][1], r1[1][0] - r1[0][0], r1[1][1] - r1[0][1] x2,y2,w2,h2= r2[0][0], r2[0][1], r2[1][0] - r2[0][0], r2[1][1] - r2[0][1] return [True,False][x1 >= x2 + w2 or x1 + w1 <= x2 or y1 >= y2 + h2 or y1 + h1 <= y2]En gros tu regards si un des points est dehors, si oui le booléen renvoie True donc choisit la case [1] du tableau du return --> False
Si aucun des points n'est dehors, le booléen renvoie False donc choisit la case [0] du tableau du return --> True
Ce que tu entend par point, c'est sommet c'est ça ?
Btw tu peux toujours remplacer [True,False] par [1,0] ou même en mode très compact mais pas du tout compréhensible :
def collision_rect(r1,r2):
return 1-(r1[0][0]>=r2[0][0]+r2[1][0]-r2[0][0]or r1[0][0]+r[1][0]-r1[0][0]<=r2[0][0]or r1[0][1]>=r2[0][1]+r2[1][1]-r2[0][1]or r1[0][1]+r1[1][1]-r1[0][1]<=r2[0][1])
Et normalement ça devrait marcher ![]()
J'ai des schémas devant moi, j'essaie de comprendre ce que fait ta fonction avec les differentes données en fonction des schémas et franchement je comprend pas :s
x1 >= x2 + w2
si ça c'est vrai ça prouve quoi parce que admettons un rectangle en 540,30 de largeur 10 et de hauteur 20, x2 + w2 = 550 on a donc le x du deuxieme sommet, donc prouvet que le x du premier rectangle est supérieur ou égal à ça on est daccord c'est prouver que les deux rectangles ne se supperposent pas ?
Pareil pour la hauteur du coup ?
Oh et oui, je parle de sommet en effet ![]()
Après si tes rectangles sont des OBB (Oriented Bounding Box, rectangles tournés quoi), la formule n'est pas la même
Le 28 novembre 2016 à 20:32:00 Coeugniet a écrit :
J'ai des schémas devant moi, j'essaie de comprendre ce que fait ta fonction avec les differentes données en fonction des schémas et franchement je comprend pas :s
x1 >= x2 + w2si ça c'est vrai ça prouve quoi parce que admettons un rectangle en 540,30 de largeur 10 et de hauteur 20, x2 + w2 = 550 on a donc le x du deuxieme sommet, donc prouvet que le x du premier rectangle est supérieur ou égal à ça on est daccord c'est prouver que les deux rectangles ne se supperposent pas ?
Pareil pour la hauteur du coup ?
Oui en fait comme on donne les sommet en haut à gauche et en bas à droite, on calcule plus simplement les autres sommets en y ajoutant la valeur ![]()
Et du coup tu peux un peu schématiser tout ça, tu traces un rectangle, puis tu prolonges ses côtés comme des droites, tu traces un autre rectangle et tu appliques l'algo dans ta tête
C'est d'ailleurs plus simple quand tu prends r2 le gros rectangle du centre et r1 le petit rectangle ajouté, tu verras mieux ![]()
Le 28 novembre 2016 à 20:32:04 Elmohe a écrit :
Oh et oui, je parle de sommet en effet
Après si tes rectangles sont des OBB (Oriented Bounding Box, rectangles tournés quoi), la formule n'est pas la même
Non il ne sont pas orientés, largeur parallèle à l'axe des x et hauteur à l'axe des y ![]()
Le 28 novembre 2016 à 20:35:24 Coeugniet a écrit :
Le 28 novembre 2016 à 20:32:04 Elmohe a écrit :
Oh et oui, je parle de sommet en effet
Après si tes rectangles sont des OBB (Oriented Bounding Box, rectangles tournés quoi), la formule n'est pas la mêmeNon il ne sont pas orientés, largeur parallèle à l'axe des x et hauteur à l'axe des y
Du coup normalement même la formule hyper-ultra-méga-super-giga-compacte devrait marcher
Même si on peut faire plus court ahah ![]()
Le 28 novembre 2016 à 20:35:11 Elmohe a écrit :
Le 28 novembre 2016 à 20:32:00 Coeugniet a écrit :
J'ai des schémas devant moi, j'essaie de comprendre ce que fait ta fonction avec les differentes données en fonction des schémas et franchement je comprend pas :s
x1 >= x2 + w2si ça c'est vrai ça prouve quoi parce que admettons un rectangle en 540,30 de largeur 10 et de hauteur 20, x2 + w2 = 550 on a donc le x du deuxieme sommet, donc prouvet que le x du premier rectangle est supérieur ou égal à ça on est daccord c'est prouver que les deux rectangles ne se supperposent pas ?
Pareil pour la hauteur du coup ?Oui en fait comme on donne les sommet en haut à gauche et en bas à droite, on calcule plus simplement les autres sommets en y ajoutant la valeur
Et du coup tu peux un peu schématiser tout ça, tu traces un rectangle, puis tu prolonges ses côtés comme des droites, tu traces un autre rectangle et tu appliques l'algo dans ta tête
C'est d'ailleurs plus simple quand tu prends r2 le gros rectangle du centre et r1 le petit rectangle ajouté, tu verras mieux
Aaaaaaaah mais moi j'avai pas compris ça du tout, je pensais que tu donnais x,y,largeur,hauteur ; fin au final tu calcul ça aprés non ? parce que moi ma fonction traite avec ça x,y du sommet haut/gauche et largeur/hauteur
J'ai quand même tester ta fonction du coup, et ça me retourne False quand je fait ça :print(collision_rect(((2,2),(2,2)),((3,1),(2,6))))
Normal ?
Aaah d'accord
Donc en fait un rectangle est défini par ((x,y),(largeur,hauteur)) ?
C'était pas précisé du coup bah il te suffit de changer un peu, tu vires les soustractions ![]()
Le 28 novembre 2016 à 20:42:33 Elmohe a écrit :
Aaah d'accord
Donc en fait un rectangle est défini par((x,y),(largeur,hauteur))?
C'était pas précisé du coup bah il te suffit de changer un peu, tu vires les soustractions
Dacc ^^, cf mon post du dessus :p
Le 28 novembre 2016 à 20:41:33 Coeugniet a écrit :
J'ai quand même tester ta fonction du coup, et ça me retourne False quand je fait ça :print(collision_rect(((2,2),(2,2)),((3,1),(2,6))))
Normal ?
Euhh essaie avec deux rectangles qui se touchent pas, peut-être que la logique not n'avait pas lieu d'être...
Selon ma fonction tu n'utilise pas les largeur hauteur mais x1,y1,x2,y2 et x1',y1',x2',y2' du coup normal pour lui le premier rectangle est un point ![]()
Ah bah oui t'avais pas modifié du coup normalement ça marche ![]()
En tout cas je l'ai utilisée dans mon jeu et ça marchait à merveille donc pas de raison que ça ne marche pas chez toi :P
Bon après j'utilisais des carrés, ça rend la chose plus simple d'un coup ahah
J'AI RIEN DIT !
elle marche j'avai zapper d'enlever les soustraction my bad :D
Merci beaucoup une fois de plus, décidemment, bon par contre faut que je l'étudie de plus prés encore parce que je l'ai pas tout à fait comprise, et puis c'est quoi ce prof qui me file des fonctions toute pourrie qui marche pas là ahah je vais l'engueuler demain x')
Ahah tape lui dessus de ma part
En fait j'avais pris cette fonction d'internet ils y a quelques jours mais au final quand tu y penses c'est simple.
Tu regardes le coin en haut à gauche, bah s'il est à droite de l'autre rectangle forcément ils se touchent pas ![]()
Après fais bien gaffe aux <= et < ! Ici comme tu le vois j'utilise des <=, en fait c'est parce que x1+w1 par exemple bah ça renvoie par le x de son sommet mais le x de son sommet + 1 ! Penses-y ;)
x1 = 0, w1 = 5, 0+5=5 pourtant le x de l'autre sommet c'est 4 ![]()
<spoil>Et dire qu'un prof d'info s'est fait marcher dessus par un enfant de 14 ans
</spoil>
Le 28 novembre 2016 à 20:51:54 Elmohe a écrit :
Ahah tape lui dessus de ma part
En fait j'avais pris cette fonction d'internet ils y a quelques jours mais au final quand tu y penses c'est simple.
Tu regardes le coin en haut à gauche, bah s'il est à droite de l'autre rectangle forcément ils se touchent pas
Après fais bien gaffe aux <= et < ! Ici comme tu le vois j'utilise des <=, en fait c'est parce que x1+w1 par exemple bah ça renvoie par le x de son sommet mais le x de son sommet + 1 ! Penses-y ;)
x1 = 0, w1 = 5, 0+5=5 pourtant le x de l'autre sommet c'est 4
On regarde le coin en haut a gauche d'un rectangle, s'il est a droite du coin haut droite du deuxieme rectangle forcement il est pas dedans, oui daccord mais ça veut pas forcement dire qu'a l'inverse il y est, c'est bien de savoir s'il est pas dedans mais je veux savoir s'il se superpose du coup si mon rectangle est tout a gauche et l'autre tout a droite il ne se touche pas pourtant le coin haut gauche de r1 et a gauche de celui de r2 ?
En fait tu regardes ça pour chaque coin, du coup avec tous les or dans la booléenne tu rends l'ensemble vrai même si une seule condition est vérifiée : si un seul coin est dehors, forcément avec les or on considère que tout est dehors. Mais comme on veut return True seulement si les rectangles se superposent, on n'à plus qu'à effectuer un not logique sur la booléenne renvoyée (avec 1-boléenne ou [True,False][booléenne] ou encore ~(booléenne) ou enfin not(booléenne)) ahah ![]()