bon, j'en ai un peu bavé avec les pointeurs *vector, difficile (pour moi) à voir le contenu dans le deboggueur, je suis passé par tout un tas de variables intermédiaires...
- cas des segments se chevauchant ou alignés -> coef. directeur identique
- cas ou les segments ne se croisent pas. -> segment parallèle
- cas ou les segment se croisent mais ou le point d'intersection se trouvent au delà de la limite de la longueur des segments -> intersection projetée
voilou ma petite contrib. petit code depuis bien bien longtemps.
Code : Tout sélectionner
;Patrick88 - 06/03/2018 - Recherche de du point d'intersection de 2 segments d'après
; http://www.purebasic.fr/french/viewtopic.php?f=1&t=17175
;Niveau de difficulté : *
;Structure d'un vecteur
Structure Vector
x.f ;Position x
y.f ;Position y
EndStructure
;Points A, B et *pt
Global A.Vector, B.Vector, C.Vector, D.Vector, *pt.vector ; pt = pt d'intersection
;Afficher un texte
Global SpriteText, Buffer.s = "Intersection de 2 segments [A B] et [C D]", TextWidth, TextHeight
;Marge affichage texte
Global Margin = 6
;Plan de l'application
Declare GameStart()
Declare GameUpdate()
Declare GameEnd()
;Math
Declare.i inter2DPoint(*P1.Vector, *P2.Vector ,*P3.Vector, *P4.Vector)
GameStart()
Procedure GameStart()
If InitSprite()
InitKeyboard()
InitMouse()
;Définition du point A
A\x = 100
A\y = 150
;Définition du point B
B\x = 575
B\y = 525
;Définition du point A
C\x = 150
C\y = 573
;Définition du point B
D\x = 585
D\y = 50
*pt = Inter2DPoint(A, B, C, D)
OpenWindow(0, 0, 0, 800, 600, "Jeu de Math : Intersection de 2 segments [A B] et [C D]", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
BindEvent(#PB_Event_CloseWindow, @GameEnd())
OpenWindowedScreen(WindowID(0), 0, 0, 800, 600)
;Creation du sprite text à afficher
SpriteText = CreateSprite(#PB_Any, 120, 24, #PB_Sprite_AlphaBlending)
StartDrawing(SpriteOutput(SpriteText))
TextWidth = TextWidth(Buffer)
textHeight = TextHeight(Buffer)
;Fond
DrawingMode(#PB_2DDrawing_AllChannels)
Box(0, 0, 120, 24, RGBA(0, 0, 0, 0))
DrawingMode(#PB_2DDrawing_AlphaBlend)
RoundBox(0, 0, 120, 24, 6, 6, RGBA(218, 165, 32, 255))
;Text
DrawingMode(#PB_2DDrawing_Transparent)
DrawText((120 - TextWidth)/2, (24 - TextHeight)/2, Buffer, RGBA(0, 0, 0, 255))
;Contour
DrawingMode(#PB_2DDrawing_Outlined)
RoundBox(0, 0, 120, 24, 6, 6, RGBA(0, 0, 0, 255))
StopDrawing()
GameUpdate()
Else
GameEnd()
EndIf
EndProcedure
Procedure GameUpdate()
Repeat : Repeat : Until WindowEvent() = 0
ClearScreen(RGB(255,255,255))
;Affichage des point A B C D
StartDrawing(ScreenOutput())
DrawingMode(#PB_2DDrawing_Transparent)
;Affichage point A
Circle(A\x, A\y, 2, RGB(255, 0, 0))
DrawText(A\x - Margin*2, A\y - Margin*2, "A", RGB(0, 0, 0))
;Affichage point B
Circle(B\x, B\y, 2, RGB(255, 0, 0))
DrawText(B\x + Margin, B\y - Margin*2, "B", RGB(0, 0, 0))
;Affichage point C
Circle(C\x, C\y, 2, RGB(255, 0, 0))
DrawText(C\x + Margin, C\y - Margin*2, "C", RGB(0, 0, 0))
;Affichage point D
Circle(D\x, D\y, 2, RGB(255, 0, 0))
DrawText(D\x + Margin, D\y - Margin*2, "D", RGB(0, 0, 0))
;Ligne entre A et B
LineXY(A\x, A\y, B\x, B\y, RGB(0, 0, 0))
;Ligne entre C et D
LineXY(C\x, C\y, D\x, D\y, RGB(0, 0, 0))
;Affichage point D'intersection
Circle(*pt\x, *pt\y, 2, RGB(255, 0, 0))
DrawText(*pt\x + Margin, *pt\y - Margin*2, "Intersection", RGB(0, 0, 0))
StopDrawing()
ExamineKeyboard()
FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)
EndProcedure
Procedure GameEnd()
End
EndProcedure
;Retourne l'intersection de deux vecteurs (Points 2D)
Procedure.i inter2DPoint(*P1.Vector, *P2.Vector ,*P3.Vector, *P4.Vector)
Protected *Result.Vector = AllocateMemory(SizeOf(Point))
Protected coef_S1.f, coef_S2.f ; coef directeur ou tangente alpha en radian
Protected ord_S1.f, ord_S2.f ; point sur l'ordonné
coef_S1 = (*P2\y - *P1\y) / (*P2\x - *P1\x)
coef_S2 = (*P4\y - *P3\y) / (*P4\x - *P3\x)
ord_S1 = *P1\y - coef_S1 * *P1\x
ord_S2 = *P3\y - coef_S2 * *P3\x
*Result\x = (ord_S2 - ord_S1) / (coef_S1 - coef_S2)
*Result\y = coef_S1 * *Result\x + ord_S1
ProcedureReturn *Result
EndProcedure