collision entre un cercle et un segment de droite

Programmation avancée de jeux en PureBasic
Avatar de l’utilisateur
Thyphoon
Messages : 2697
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

collision entre un cercle et un segment de droite

Message par Thyphoon »

voici un petit truc pour détecter la collision entre un cercle et un segment de droite.

J’espère que ça vous sera utile

Code : Tout sélectionner

 If InitSprite() And InitKeyboard() And InitMouse()
    winMain = OpenWindow(#PB_Any,0,0,800,600,"Press [Esc] to close",#PB_Window_ScreenCentered | #PB_Window_SystemMenu)
    OpenWindowedScreen(WindowID(winMain), 0, 0, 800, 600, 1, 0, 0)
    SetFrameRate(60)
Else
  MessageRequester("","Unable to init") :
EndIf

; ma procedure qui me retourne la distance entre un segment BE et un point M
Procedure distancePointDroite(xB.l,yB.l,xE.l,yE.l,xM.l,yM.l):
    ; coordonnées a,b du vecteur EB
    a.l=xE-xB
    b.l=yE-yB
    ; équation de la perpendiculaire D1 en B à (EB): ax+by+w1
    w1.l=-a*xB-b*yB
    ; équation de la perpendiculaire D2 en E à (EB): ax+by+w2
    w2.l=-a*xE-b*yE
    ; équation de la droite (EB) : bx-ay+w3
    w3.l= a*yB-b*xB
    ;puissance de M par rapport à D1
    PMD1.l=a*xM+b*yM+w1
    ; puissance de M par rapport à D2
    PMD2.l=a*xM+b*yM+w2
    ;puissance de B par rapport à D2
    PBD2.l=a*xB+b*yB+w2
    ;puissance de E par rapport à D1
    PED1.l=a*xE+b*yE+w1
    ; A ce stade encore ni racine ni quotient
    If PMD1*PED1 <0 ;M et E de part et d'autre de D1
        ProcedureReturn Sqr((xM-xB)*(xM-xB)+(yM-yB)*(yM-yB)) ; pas de quotient
    ElseIf PMD2*PBD2 <0: ;M et B de part et d'autre de D2
        ProcedureReturn Sqr((xM-xE)*(xM-xE)+(yM-yE)*(yM-yE)) ; idem
        ; sinon
    Else
      ProcedureReturn Abs(b*xM-a*yM+w3)/Sqr(a*a+b*b) ; là rien à faire
    EndIf
  EndProcedure
  
  ;cordonée de mon segment
  xa=150
  ya=150
  xb=600
  yb=400

Repeat
  Delay(1)
  EventID = WindowEvent()
  ExamineKeyboard()
  ExamineMouse()

  ClearScreen(0) 
  
  StartDrawing(ScreenOutput())
    DrawingMode(#PB_2DDrawing_Outlined)
    ;je calcule la distance entre mon point et le segment
    dist=distancePointDroite(xa,ya,xb,yb,MouseX(), MouseY())
    ;si la distance est inférieur au rayon de mon cercle alors on touche la droite
    If dist<=16
      col=#Red ; si on touche la droite on utilisera la couleur rouge
    Else
      col=#White ; sinon on utilisera le blanc
    EndIf
        
    Circle(MouseX(), MouseY(), 16, col) ; je trace mon cercle
    LineXY(xa,ya,xb,yb,#Green) ; je trace ma droite
    txt.s=Str(dist)
    wtxt=TextWidth(txt)
    htxt=TextHeight(txt)
    
    DrawText(MouseX()-wtxt/2, MouseY()-htxt/2,Str(dist))
      
  StopDrawing()
 
  FlipBuffers()
Until KeyboardReleased(#PB_Key_Escape) Or EventID = #PB_Event_CloseWindow
Dernière modification par Thyphoon le sam. 07/mai/2011 14:57, modifié 1 fois.
Avatar de l’utilisateur
case
Messages : 1528
Inscription : lun. 10/sept./2007 11:13

Re: collision entre un cercle et un segment de droite

Message par case »

bonne idée mais ca ne fonctionne pas très bien...
Image


ça ne fonctionnais pas a cause des long qui ne sont pas assez précis pour de la géométrie...

Code : Tout sélectionner

If InitSprite() And InitKeyboard() And InitMouse()
    winMain = OpenWindow(#PB_Any,0,0,800,600,"Press [Esc] to close",#PB_Window_ScreenCentered | #PB_Window_SystemMenu)
    OpenWindowedScreen(WindowID(winMain), 0, 0, 800, 600, 1, 0, 0)
    SetFrameRate(60)
Else
  MessageRequester("","Unable to init") :
EndIf

; ma procedure qui me retourne la distance entre un segment BE et un point M
Procedure distancePointDroite(xB.d,yB.d,xE.d,yE.d,xM.d,yM.d):
    ; coordonnées a,b du vecteur EB
    a.d=xE-xB
    b.d=yE-yB
    ; équation de la perpendiculaire D1 en B à (EB): ax+by+w1
    w1.d=-a*xB-b*yB
    ; équation de la perpendiculaire D2 en E à (EB): ax+by+w2
    w2.d=-a*xE-b*yE
    ; équation de la droite (EB) : bx-ay+w3
    w3.d= a*yB-b*xB
    ;puissance de M par rapport à D1
    PMD1.d=a*xM+b*yM+w1
    ; puissance de M par rapport à D2
    PMD2.d=a*xM+b*yM+w2
    ;puissance de B par rapport à D2
    PBD2.d=a*xB+b*yB+w2
    ;puissance de E par rapport à D1
    PED1.d=a*xE+b*yE+w1
    ; A ce stade encore ni racine ni quotient
    If PMD1*PED1 <0 ;M et E de part et d'autre de D1
        ProcedureReturn Sqr((xM-xB)*(xM-xB)+(yM-yB)*(yM-yB)) ; pas de quotient
    ElseIf PMD2*PBD2 <0: ;M et B de part et d'autre de D2
        ProcedureReturn Sqr((xM-xE)*(xM-xE)+(yM-yE)*(yM-yE)) ; idem
        ; sinon
    Else
      ProcedureReturn Abs(b*xM-a*yM+w3)/Sqr(a*a+b*b) ; là rien à faire
    EndIf
  EndProcedure
 
  ;cordonée de mon segment
  xa.d=150
  ya.d=150
  xb.d=600
  yb.d=400

Repeat
  Delay(1)
  EventID = WindowEvent()
  ExamineKeyboard()
  ExamineMouse()

  ClearScreen(0)
 
  StartDrawing(ScreenOutput())
    DrawingMode(#PB_2DDrawing_Outlined)
    ;je calcule la distance entre mon point et le segment
    dist.d=distancePointDroite(xa,ya,xb,yb,MouseX(), MouseY())
    ;si la distance est inférieur au rayon de mon cercle alors on touche la droite
    If dist<=16
      col=#Red ; si on touche la droite on utilisera la couleur rouge
    Else
      col=#White ; sinon on utilisera le blanc
    EndIf
       
    Circle(MouseX(), MouseY(), 16, col) ; je trace mon cercle
    LineXY(xa,ya,xb,yb,#Green) ; je trace ma droite
    txt.s=Str(dist)
    wtxt=TextWidth(txt)
    htxt=TextHeight(txt)
   
    DrawText(MouseX()-wtxt/2, MouseY()-htxt/2,Str(dist))
     
  StopDrawing()

  FlipBuffers()
Until KeyboardReleased(#PB_Key_Escape) Or EventID = #PB_Event_CloseWindow

ImageImage
Avatar de l’utilisateur
Thyphoon
Messages : 2697
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Re: collision entre un cercle et un segment de droite

Message par Thyphoon »

Alors là je comprends pas ... ça te le fait tout le temps ou a un endroit bien précis ?
car j'ai beau essayer de reproduire le bug je n'y arrive pas...
Avatar de l’utilisateur
Thyphoon
Messages : 2697
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Re: collision entre un cercle et un segment de droite

Message par Thyphoon »

Oups tu as editer ton message entre temps ...
Effectivement ! merci pour la correction ... :o)
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: collision entre un cercle et un segment de droite

Message par Backup »

Excellent :)
Répondre