Page 3 sur 4

Publié : sam. 05/mai/2007 17:45
par tmyke
[img]http:///www.dreamotion3d.com/_downloads/purebasic/screens/dessin1.jpg[/img]

Je dirais vite fait, qu'il faut connaitre d3, après il suffit de faire:

ang1 = ACos(d3/d2)
ang2 = 180 - 90 - ang1 (la somme des angles d'un triangle = 180° )

enfin

??? = 360 - ang2 - a2

Je regarde pour calculer d3...

non ? (j'suis a l'apéro, donc j'ai les méninges qui peuvent s'embrouiller :? )

Publié : sam. 05/mai/2007 17:48
par _Slide_
Je connais aussi le rayon, j'ai oublié ca mdr.... et comme par hasard, avec cette donné, ca devient plus simple, puisque je connais le rayon, et l'hypoténuse du triangle rectangle.... 2 coté donc, je n'ai plus qu'a trouver l'angle et faire une soustraction....

Si j'avais dessiné ce dessin plutôt et completement, je pense que j'aurai vu tout de suite le triangle rectangle lol....

Publié : sam. 05/mai/2007 17:49
par _Slide_
tmyke a écrit :[img]http:///www.dreamotion3d.com/_downloads/purebasic/screens/dessin1.jpg[/img]

Je dirais vite fait, qu'il faut connaitre d3, après il suffit de faire:

ang1 = ACos(d3/d2)
ang2 = 180 - 90 - ang1 (la somme des angles d'un triangle = 180° )

enfin

??? = 360 - ang2 - a2

Je regarde pour calculer d3...

non ? (j'suis a l'apéro, donc j'ai les méninges qui peuvent s'embrouiller :? )
C'est exactement ce que je viens de voir à l'instant :) merci de m'avoir aidé quand même.

Son jolie mes dessins non ? :)

edit : non on connait pas d3, par contre on connait le rayon, c'est de ma faute dsl :)
ps : langle recherché à changé, j'ai modifié l'image

Publié : sam. 05/mai/2007 17:55
par tmyke
Alors dansce cas d4=rayon, donc

ang2 = ACos (d4/d2)

et ??? = 360 - ang2 - a2

(j'en suis qu'au deuxième verre...)

Publié : sam. 05/mai/2007 17:59
par _Slide_
tmyke a écrit :Alors dansce cas d4=rayon, donc

ang2 = ACos (d4/d2)

et ??? = 360 - ang2 - a2

(j'en suis qu'au deuxième verre...)
Exactement qu'il faut faire oui.
ACos c'est une fonction PureBASIC ?

Publié : sam. 05/mai/2007 18:00
par tmyke
Oui, attention les angle sous PB sont a exprimer (ou récupérer) en radian...
:wink:

Publié : sam. 05/mai/2007 18:04
par _Slide_
Merci Tmyke. Boit pas trop au faite lol, laisse moi en... remarque un fond de bouteille ca va me suffire, je ne bois pas :)

Qqun aurait pas une fonction en assembleur pour normaliser un angle (en float) :
genre :

-10° => 350°
660° => 300°

Il doit bien y avoir quelqu'un qui a fait ca en assembleur avec des instructions rapide :) ? Merci

Publié : sam. 05/mai/2007 18:11
par comtois

Publié : sam. 05/mai/2007 18:11
par _Slide_
http://www.purebasic.fr/french/viewtopi ... e&start=15
J'ai utilisé la fonction recherché :)
Tonton propose du code assembleur, je vais voir ce que je peux en faire :).

Publié : sam. 05/mai/2007 18:11
par _Slide_
comtois a écrit :oui, Psychophanta a pondu ça

http://www.purebasic.fr/french/viewtopic.php?t=4280
Merci, je vais aller voir ton code plutot alors :)

Publié : sam. 05/mai/2007 18:38
par _Slide_
Je prend lequel comme code donc lol ? :lol: Dans le lien que tu m'as donné, il y en a plein, et vous avez fait plein de test, hors tu as du reflechir a celui a utiliser en fonction de ces résultats, quelles sont tes conclusions stp :) ?

Je pense que c'est celui ci (avec la modification) :

Code : Tout sélectionner

Procedure.f WrapAngleDeg(angle.f); <- wraps a value into [0,360) fringe
  !fild dword[@f] ; <- now i have 360 into st0
  !fld dword[esp]
  !fprem
  !fadd st1,st0
  !fldz
  !fcomip st1
  !fcmovnbe st0,st1
  !fstp st1
  ProcedureReturn
  !@@:dd 360
EndProcedure 
Il est 100% compatible avec la 4.02 de PB ? :)
Merci

edit : j'ai posté mes résultats ici http://www.purebasic.fr/french/viewtopi ... 3981#63981

Publié : sam. 05/mai/2007 20:07
par _Slide_
Là tuile, en faite j'ai pas a2, mince lol, une petite idée pour recuperer a2 svp ? :) Je pense que avec x2 et x3 ca se fait en 10sec... moi mon cerveau il va griller.

Merci :)

Publié : sam. 05/mai/2007 20:58
par comtois
si tu travailles en degré , tu prends ce code (PB 4.0)

Code : Tout sélectionner

Procedure.f WrapAngleDeg(angle.f); <- wraps a value into [0,360) fringe
  !fild dword[@f] ; <- now i have 360 into st0
  !fld dword[p.v_angle]
  !fprem
  !fadd st1,st0
  !fldz
  !fcomip st1
  !fcmovnbe st0,st1
  !fstp st1
  ProcedureReturn
  !@@:dd 360
EndProcedure 
Si tu travailles en radian, tu prends ce code (PB 4.0)

Code : Tout sélectionner

Procedure.f WrapAngle(angle.f); <- wraps a value into [0,2*Pi) fringe
  !fldpi; <- now i have pi into st0
  !fadd st0,st0; <- now i have 2*pi into st0
  !fld dword[p.v_angle]; <- now i have angle in st0, 2*pi into st1
  !fprem; <- now i have the remainder of angle/(2*pi) division (i.e. angle%(2*pi)) in st0, 2*pi in st1
  !fadd st1,st0;<- now i have angle%(2*pi) in st0, 2*pi+angle%(2*pi) into st1
  !fldz;<- now i have 0 in st0, angle%(2*pi) in st1, 2*pi+angle%(2*pi) into st2
  !fcomip st1; <- compare st0 and st1, and pop the stack, which means i have now angle%(2*pi) in st0, 2*pi+remainder into st1
  !fcmovnbe st0,st1; <- transfer st1 to st0 if not below or equal.
  !fstp st1; <- store st0 in st1 and pops stack, which means i have now the result in st0
  ProcedureReturn; <- return the result with this last pop
EndProcedure

Publié : sam. 05/mai/2007 21:07
par comtois
pour calculer le cosinus de l'angle phi entre deux vecteurs , tu peux faire un produit scalaire.

Cos phi = V1.V2 / |V1|.|V2|

Donc si V1 et V2 sont normés, le cos phi est égal au produit scalaire.

Publié : sam. 05/mai/2007 21:31
par comtois
pour illustrer le calcul de l'angle entre deux vecteurs, j'ai modifié un vieux code et j'en ai profité pour le mettre à jour pour la V4.
la partie qui concerne le calcul de l'angle est ici

Code : Tout sélectionner

  ;Calcul l'angle entre les deux segments
  Define.s_Vecteur2D V1, V2 
  V1\x = *S1\P2\x-*S1\P1\x
  V1\y = *S1\P2\y-*S1\P1\y
  V2\x = *S2\P2\x-*S2\P1\x
  V2\y = *S2\P2\y-*S2\P1\y
  CosAngle.f =  PRODUIT_SCALAIRE(V1, V2) / (NORME(V1)*NORME(V2)) 
  DrawText(0,20,"Angle = " + StrF(ACos(CosAngle)*#RAD2DEG,1),#White,#Black)
Et voici le code complet :

Code : Tout sélectionner

;Comtois 05/05/07 - PB4.02
;Détection collision d'un segment avec un autre segment

;-Initialisation
Global ScreenHeight.l,ScreenWidth.l
Declare Erreur(Message$)
If ExamineDesktops()
  ScreenWidth = DesktopWidth(0)
  ScreenHeight = DesktopHeight(0)
Else
  Erreur("Euh ?")
EndIf
If InitSprite() = 0 Or InitMouse() = 0 Or InitKeyboard()=0
  Erreur("Impossible d'initialiser DirectX 7 Ou plus")
ElseIf OpenWindow(0,0,0,ScreenWidth,ScreenHeight,"Collision",#PB_Window_BorderLess) = 0
  Erreur("Impossible de créer la fenêtre")
EndIf
;{/ouvre un écran
If OpenWindowedScreen( WindowID(0), 0, 0, ScreenWidth , ScreenHeight, 0, 0, 0 ) = 0
  Erreur("Impossible d'ouvrir l'écran ")
EndIf 

#RAD2DEG = 180/#PI 
 Macro PRODUIT_SCALAIRE(V1, V2)
  (V1\x * V2\x + V1\y * V2\y) 
EndMacro

 Macro NORME(V)
  (Sqr(V\x * V\x + V\y * V\y)) 
EndMacro

Structure Segment
  P1.point
  P2.point
EndStructure

Structure s_Vecteur2D
  x.f
  y.f
EndStructure

Global Box1.Segment,Box2.Segment

Procedure Erreur(Message$)
  MessageRequester( "Erreur" , Message$ , 0 )
  End
EndProcedure
Procedure.l Signe(a.l)
  If a>0
    ProcedureReturn 1
  ElseIf a=0
    ProcedureReturn 0
  Else
    ProcedureReturn -1
  EndIf
EndProcedure
Procedure.l Min(a.l,b.l)
  If a<b
    ProcedureReturn a
  Else
    ProcedureReturn b
  EndIf
EndProcedure
Procedure.l Max(a.l,b.l)
  If a>b
    ProcedureReturn a
  Else
    ProcedureReturn b
  EndIf
EndProcedure
Procedure Encadrement(*S1.Segment,*S2.Segment)
  ;Box Segment1
  Box1\P1\x=Min(*S1\P1\x,*S1\P2\x)
  Box1\P1\y=Min(*S1\P1\y,*S1\P2\y)
  Box1\P2\x=Max(*S1\P1\x,*S1\P2\x)
  Box1\P2\y=Max(*S1\P1\y,*S1\P2\y) 
  ;Box Segment2
  Box2\P1\x=Min(*S2\P1\x,*S2\P2\x)
  Box2\P1\y=Min(*S2\P1\y,*S2\P2\y)
  Box2\P2\x=Max(*S2\P1\x,*S2\P2\x)
  Box2\P2\y=Max(*S2\P1\y,*S2\P2\y)
EndProcedure

Procedure CollisionSegmentSegment(*S1.Segment,*S2.Segment)
  ;Test Collision encadrement
  If Box1\P2\x >= Box2\P1\x And Box1\P1\x <= Box2\P2\x And Box1\P2\y >= Box2\P1\y And Box1\P1\y <= Box2\P2\y
    ;Test chevauchement segments
    R1.f=((*S2\P1\x-*S1\P1\x)*(*S1\P2\y-*S1\P1\y))-((*S2\P1\y-*S1\P1\y)*(*S1\P2\x-*S1\P1\x))
    R2.f=((*S2\P2\x-*S1\P1\x)*(*S1\P2\y-*S1\P1\y))-((*S2\P2\y-*S1\P1\y)*(*S1\P2\x-*S1\P1\x))
    R3.f=((*S1\P1\x-*S2\P1\x)*(*S2\P2\y-*S2\P1\y))-((*S1\P1\y-*S2\P1\y)*(*S2\P2\x-*S2\P1\x))
    R4.f=((*S1\P2\x-*S2\P1\x)*(*S2\P2\y-*S2\P1\y))-((*S1\P2\y-*S2\P1\y)*(*S2\P2\x-*S2\P1\x))
    If (Signe(R1)*Signe(R2)<=0) And (Signe(R3)*Signe(R4)<=0)
      Resultat = #True
    EndIf
  EndIf 
  ProcedureReturn Resultat
EndProcedure

Procedure AffPoints(*S1.Segment,*S2.Segment,*P.point,mem)
  CouleurBox=RGB(70,70,70)
  CouleurSegment1=RGB(255,0,0)
  CouleurSegment2=RGB(0,255,0)
  CouleurCurseur=RGB(255,255,255)
  StartDrawing(ScreenOutput())
  ;/Affiche les encadrements des segments en premier pour ne pas effacer le tracé d'un segment
  ;Segment1
  LineXY(Box1\P1\x,Box1\P1\y,Box1\P1\x,Box1\P2\y,CouleurBox)
  LineXY(Box1\P1\x,Box1\P1\y,Box1\P2\x,Box1\P1\y,CouleurBox)
  LineXY(Box1\P2\x,Box1\P1\y,Box1\P2\x,Box1\P2\y,CouleurBox)
  LineXY(Box1\P1\x,Box1\P2\y,Box1\P2\x,Box1\P2\y,CouleurBox)
  ;Segment2
  LineXY(Box2\P1\x,Box2\P1\y,Box2\P1\x,Box2\P2\y,CouleurBox)
  LineXY(Box2\P1\x,Box2\P1\y,Box2\P2\x,Box2\P1\y,CouleurBox)
  LineXY(Box2\P2\x,Box2\P1\y,Box2\P2\x,Box2\P2\y,CouleurBox)
  LineXY(Box2\P1\x,Box2\P2\y,Box2\P2\x,Box2\P2\y,CouleurBox)
  ;/Affiche le Segment1
  Circle(*S1\P1\x,*S1\P1\y,4,CouleurSegment1)
  Circle(*S1\P2\x,*S1\P2\y,4,CouleurSegment1)
  LineXY(*S1\P1\x,*S1\P1\y,*S1\P2\x,*S1\P2\y,CouleurSegment1)
  ;/Affiche le Segment2
  Circle(*S2\P1\x,*S2\P1\y,4,CouleurSegment2)
  Circle(*S2\P2\x,*S2\P2\y,4,CouleurSegment2)
  LineXY(*S2\P1\x,*S2\P1\y,*S2\P2\x,*S2\P2\y,CouleurSegment2)
  ;/Affiche le point
  If mem
    DrawingMode(4)
    Circle(*P\x,*P\y,6,CouleurCurseur)
  Else
    DrawingMode(0)
    Circle(*P\x,*P\y,4,CouleurCurseur)
  EndIf
  ;/Affiche une croix pour mieux suivre le déplacement du point
  LineXY(*P\x,0,*P\x,ScreenHeight-1,CouleurCurseur)
  LineXY(0,*P\y,ScreenWidth-1,*P\y,CouleurCurseur)
  If CollisionSegmentSegment(*S1,*S2)
    FrontColor(#Yellow)
    BackColor(#Red)
    texte$="  IN "
  Else
    FrontColor(#White)
    BackColor(#Green)
    texte$=" OUT "
  EndIf
  DrawText(0,0,texte$)
  ;Calcul l'angle entre les deux segments
  Define.s_Vecteur2D V1, V2 
  V1\x = *S1\P2\x-*S1\P1\x
  V1\y = *S1\P2\y-*S1\P1\y
  V2\x = *S2\P2\x-*S2\P1\x
  V2\y = *S2\P2\y-*S2\P1\y
  CosAngle.f =  PRODUIT_SCALAIRE(V1, V2) / (NORME(V1)*NORME(V2)) 
  DrawText(0,20,"Angle = " + StrF(ACos(CosAngle)*#RAD2DEG,1),#White,#Black)
  StopDrawing()
EndProcedure
Procedure TestPoint(X1,Y1,X2,Y2,d)
  If X1>X2-d And X1<X2+d And Y1>Y2-d And Y1<Y2+d
    Resultat=#True
  EndIf
  ProcedureReturn Resultat
EndProcedure

Segment1.Segment
Segment2.Segment
Point.point
;Segment1
Segment1\P1\x=ScreenWidth/2
Segment1\P1\y=ScreenHeight/2
Segment1\P2\x=ScreenWidth/2
Segment1\P2\y=0
;Segment2
Segment2\P1\x=ScreenWidth/2
Segment2\P1\y=ScreenHeight/2
Segment2\P2\x=ScreenWidth-1
Segment2\P2\y=ScreenHeight/2
;Point à tester
Point\x=340
Point\y=100
DiametreSelection=6

Repeat
  While WindowEvent():Wend
  ClearScreen(0)
  ExamineKeyboard()
  ExamineMouse()
  ;Le triangle est modifiable à la souris en cliquant sur un point
  If MouseButton(1)
    If MemPoint=1
      Segment1\P1\x=MouseX()
      Segment1\P1\y=MouseY()
    ElseIf MemPoint=2
      Segment1\P2\x=MouseX()
      Segment1\P2\y=MouseY()
    ElseIf MemPoint=3
      Segment2\P1\x=MouseX()
      Segment2\P1\y=MouseY()
    ElseIf MemPoint=4
      Segment2\P2\x=MouseX()
      Segment2\P2\y=MouseY() 
    EndIf
  Else
    MemPoint=0
  EndIf
  If TestPoint(MouseX(),MouseY(),Segment1\P1\x,Segment1\P1\y,DiametreSelection)
    MemPoint=1
  ElseIf TestPoint(MouseX(),MouseY(),Segment1\P2\x,Segment1\P2\y,DiametreSelection)
    MemPoint=2
  ElseIf TestPoint(MouseX(),MouseY(),Segment2\P1\x,Segment2\P1\y,DiametreSelection)
    MemPoint=3
  ElseIf TestPoint(MouseX(),MouseY(),Segment2\P2\x,Segment2\P2\y,DiametreSelection)
    MemPoint=4 
  EndIf
  ;Place le point à tester sous la souris
  Point\x=MouseX()
  Point\y=MouseY()
  ;Affiche le tout
  Encadrement(@Segment1,@Segment2)
  AffPoints(@Segment1,@Segment2,@Point,MemPoint)
  FlipBuffers()
  Delay(1)
Until KeyboardPushed(#PB_Key_Escape)