Ligne en poitillée

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
microdevweb
Messages : 1802
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Ligne en poitillée

Message par microdevweb »

Bonjour,

Existe t'il un paramètre pour le dessin 2d qui permette de mètre la ligne en pointillée. Je n'en ai personnellement pas trouvé et j'ai du faire une procédure à cette effet.

Merci
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Ligne en poitillée

Message par falsam »

Je ne suis pas l'auteur de ce code mais ça peut servir.

Code : Tout sélectionner

; Dash-Draw PB 4.40

Procedure DashDraw(P1x.l, P1y.l, P2x.l, P2y.l, DashValue.l=5, DashRad.l=1, DashColor.l=#White)
  
  Protected DashVal1, DashVal2, DashMax, iStep

  ;Test
  DashBreak = DashValue *2
  
  NextPointX.f = P1x
  NextPointY.f = P1y
  
  DistX.f = P2x - P1x
  DistY.f = P2y - P1y
  
  dx = P1x - P2x
  dy = P1y - P2y
  Distance = Sqr(dx*dx + dy*dy)
  
  While Distance > 1
    
    If DashValue > iStep
      
      For iStep = 1 To DashValue
        
        Circle(NextPointX,NextPointY,DashRad,DashColor)
        
        XSchritt.f = DistX/Distance
        YSchritt.f = DistY/Distance
        
        NextPointX = NextPointX + XSchritt
        NextPointY = NextPointY + YSchritt
        
        DistX = P2x - NextPointX
        DistY = P2y - NextPointY
        
        dxNeu.f = NextPointX - P2x
        dyNeu.f = NextPointY - P2y
        Distance = Sqr(dxNeu*dxNeu + dyNeu*dyNeu)
        
      Next
      
    Else
      
      For iStep = DashBreak To 1 Step -1
        
        XSchritt.f = DistX/Distance
        YSchritt.f = DistY/Distance
        
        NextPointX = NextPointX + XSchritt
        NextPointY = NextPointY + YSchritt
        
        DistX = P2x - NextPointX
        DistY = P2y - NextPointY
        
        dxNeu.f = NextPointX - P2x
        dyNeu.f = NextPointY - P2y
        Distance = Sqr(dxNeu*dxNeu + dyNeu*dyNeu)
        
      Next
      
    EndIf
    
  Wend
  
EndProcedure


OpenWindow(0,0,0,200,200,"DashDraw")


ImageGadget(0,10,10,180,180,0)

CreateImage(0,170,170)


StartDrawing(ImageOutput(0))
  
DashDraw(10,20,100,110)
  
StopDrawing()

SetGadgetState(0,ImageID(0))


; Mainschleife
Repeat
  Event = WindowEvent()
  
  If Event = #PB_Event_CloseWindow
    EXIT = 1
  EndIf
  
Until Exit
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Ligne en poitillée

Message par falsam »

La même chose avec les fonctions de la bibliothèque Sprite

Code : Tout sélectionner

; DashDraw PB 4.4x
EnableExplicit

If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0
  MessageRequester("Error", "Can't open DirectX 7 or later", 0)
  End
EndIf

Structure iBox
  P1.POINT
  P2.POINT
  P3.POINT
  P4.POINT
EndStructure

Procedure DrawBox(x1.i, y1.i, x2.i, y2.i, hoehe.f, icolorout.i=#White, icolorin=#White)
  
  Protected Distance.i, Winkel.i, myBox.iBox, DiffX.i
  Protected fWinkelM.f, fWinkelP.f, PickPoint.POINT
  
  PickPoint\x = (x1+x2)/2: PickPoint\y = (y1+y2)/2 ; Punkt in der Mitte für Fillarea
  hoehe = hoehe/2 ;die Höhe wird zu beiden Seiten zugerechnet, also hat eine Seite nur die halbe Höhe
  DiffX = x2-x1
  
  Distance = Sqr((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1))
  
  Winkel = ACos(DiffX/Distance)*57.29577 +90
  If y1<y2 : Winkel=360-Winkel : EndIf
  
  fWinkelP =(Winkel +90) *(2*3.14159265/360);positiver Winkel
  fWinkelM =(Winkel -90) *(2*3.14159265/360);negativer Winkel
  
  myBox\P1\x = Round(x1 + (hoehe * Sin(fWinkelP)),0)
  myBox\P1\y = Round(y1 + (hoehe * Cos(fWinkelP)),0)
  
  myBox\P2\x = Round(x1 + (hoehe * Sin(fWinkelM)),0)
  myBox\P2\y = Round(y1 + (hoehe * Cos(fWinkelM)),0)
  
  myBox\P3\x = Round(x2 + (hoehe * Sin(fWinkelM)),0)
  myBox\P3\y = Round(y2 + (hoehe * Cos(fWinkelM)),0)
  
  myBox\P4\x = Round(x2 + (hoehe * Sin(fWinkelP)),0)
  myBox\P4\y = Round(y2 + (hoehe * Cos(fWinkelP)),0)
  
  LineXY(myBox\P1\x,myBox\P1\y,myBox\P2\x,myBox\P2\y,icolorout)
  LineXY(myBox\P2\x,myBox\P2\y,myBox\P3\x,myBox\P3\y,icolorout)
  LineXY(myBox\P3\x,myBox\P3\y,myBox\P4\x,myBox\P4\y,icolorout)
  LineXY(myBox\P4\x,myBox\P4\y,myBox\P1\x,myBox\P1\y,icolorout)
  If Distance >= 1
    FillArea(PickPoint\x,PickPoint\y,-1,icolorin)
  EndIf
  
EndProcedure

Procedure SlimLine(x1.i,y1.i,x2.i,y2.i,color.i=#White)
  
  Protected Distance.i, DiffX.i, DiffY.i, iStep.f, a.f, b.f, i.i
  Protected NextPoint.POINT, PlotPoint.POINT, fWinkelM.f, fWinkelP.f,Winkel.i
  
  a = 1: b = 1 - a
  DiffX = x2-x1
  DiffY = y2 -y1 
  Distance = Sqr(DiffX*DiffX+DiffY*DiffY)
  iStep = 1/Distance
  
  Winkel = ACos(DiffX/Distance)*57.29577 +90
  If y1<y2 : Winkel=360-Winkel : EndIf
  
  fWinkelP =(Winkel +90) *(2*3.14159265/360);positiver Winkel
  fWinkelM =(Winkel -90) *(2*3.14159265/360);negativer Winkel
  
  For i = 1 To Distance
    
    NextPoint\x = x1*a+x2*b
    NextPoint\y = y1*a+y2*b
    
    Plot(NextPoint\x,NextPoint\y,Color)
    
    PlotPoint\x = Round(NextPoint\x + (Sin(fWinkelP)),0)
    PlotPoint\y = Round(NextPoint\y + (Cos(fWinkelP)),0)
    If PlotPoint\x<0 Or PlotPoint\y<0
    Else
      Plot(PlotPoint\x,PlotPoint\y,Color)
    EndIf 
    
    PlotPoint\x = Round(NextPoint\x + (Sin(fWinkelM)),0)
    PlotPoint\y = Round(NextPoint\y + (Cos(fWinkelM)),0)
    If PlotPoint\x<0 Or PlotPoint\y<0
    Else
      Plot(PlotPoint\x,PlotPoint\y,Color)
    EndIf
    
    a = a - iStep
    b = 1 - a
    
  Next
  
EndProcedure

Procedure DashDraw(x1.i,y1.i,x2.i,y2.i,DashValue.i=5,DashWidth.i=3,DashColor.i=#White)
  
  Protected Distance.i, DiffX.i, DiffY.i, a.f, b.f
  Protected DashStepMax.f, DashCount.f, PrevPoint.POINT, NextPoint.POINT
  Protected ZahlStr.s, Zahl2.i, Odd.i, OddZahl.f
  
  DiffX = x2-x1
  DiffY = y2 -y1 
  Distance = Sqr(DiffX*DiffX+DiffY*DiffY)
  DashCount = Distance/(DashValue*2)
  
  ;Prüfen auf Nachkommastellen
  ZahlStr = StrF(DashCount)
  Zahl2 = Val(ZahlStr) 
  If Zahl2 <> DashCount
    Odd = #True
    OddZahl = DashCount - Zahl2
  EndIf
  
  DashStepMax = 1/(DashCount*2)

  If Odd = #True

    a = 1 - (DashStepMax*OddZahl)
    b = 1 - a
    
    NextPoint\x = x1*a+x2*b
    NextPoint\y = y1*a+y2*b
    
    If DashWidth > 2 
      DrawBox(x1,y1,NextPoint\x,NextPoint\y,DashWidth,DashColor,DashColor) 
    ElseIf DashWidth = 2
      SlimLine(x1,y1,NextPoint\x,NextPoint\y,DashColor)
    Else
      LineXY(x1,y1,NextPoint\x,NextPoint\y,DashColor)
    EndIf
    
    a = a - DashStepMax: b = 1 - a
  Else
    a=1:b=1-a
  EndIf
  
  While a > DashStepMax
    
    PrevPoint\x = x1*a+x2*b
    PrevPoint\y = y1*a+y2*b
    
    a = a - DashStepMax: b = 1 - a
    
    NextPoint\x = x1*a+x2*b
    NextPoint\y = y1*a+y2*b
    
    If DashWidth > 2 
      DrawBox(PrevPoint\x,PrevPoint\y,NextPoint\x,NextPoint\y,DashWidth,DashColor,DashColor) 
    ElseIf DashWidth = 2
      SlimLine(PrevPoint\x,PrevPoint\y,NextPoint\x,NextPoint\y,DashColor)
    Else
      LineXY(PrevPoint\x,PrevPoint\y,NextPoint\x,NextPoint\y,DashColor)
    EndIf
    
    a = a - (DashStepMax): b = 1 - a
    
  Wend
  
  If Odd = #False And a>0
    
    NextPoint\x = x1*a+x2*b
    NextPoint\y = y1*a+y2*b
    
    If DashWidth > 2 
      DrawBox(NextPoint\x,NextPoint\y,x2,y2,DashWidth,DashColor,DashColor) 
    ElseIf DashWidth = 2
      SlimLine(NextPoint\x,NextPoint\y,x2,y2,DashColor)
    Else
      LineXY(NextPoint\x,NextPoint\y,x2,y2,DashColor)
    EndIf

  EndIf
  
EndProcedure


; Test

Define POINTA.POINT, POINTB.POINT
Define Hoehe.i, hwnd.i, Event.i
Define WinX.i, WinY.i, WinWidth.i, WinHeight.i 
Define ScreenX.i, ScreenY.i, ScreenWidth.i, ScreenHeight.i

WinX = 0: WinY = 0: WinWidth = 300: WinHeight = 300
ScreenX = 0: ScreenY = 0: ScreenWidth = WinWidth: ScreenHeight = WinHeight

POINTA\x = 98: POINTA\y = 150
POINTB\x = ScreenWidth/2: POINTB\y = ScreenHeight/2 


hwnd = OpenWindow(0, WinX, WinY, WinWidth, WinHeight, "test", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
If OpenWindowedScreen(hwnd,ScreenX,ScreenY,ScreenWidth,ScreenHeight,0,0,0)

  Repeat
    
    Repeat
      Select WindowEvent ()
        Case #PB_Event_CloseWindow
          End
        Case #Null
          Break
      EndSelect
    ForEver
    
    ClearScreen($000000)
    ExamineKeyboard()
    ExamineMouse()
    
    POINTA\x = MouseX(): POINTA\y = MouseY()
    
    StartDrawing(ScreenOutput())
      DashDraw(POINTA\x,POINTA\y,POINTB\x,POINTB\y,20,4)
    StopDrawing() 
    
    FlipBuffers()
    
  Until Event = #PB_Event_CloseWindow Or KeyboardPushed(#PB_Key_Escape)
  
  End
  
Else
  
  MessageRequester("Fehler","Konnte Screen nicht öffnen")
  End 
  
EndIf
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: Ligne en poitillée

Message par G-Rom »

Bonjour, si tu veut le faire à la main , tu as l'algo de Bresenham, tu pourras tracer des lignes , cercles & cie.
si tu comprends l'algorithme , tu pourras faire se que tu veut , dont les pointillés. ;)

@+
Avatar de l’utilisateur
microdevweb
Messages : 1802
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Re: Ligne en poitillée

Message par microdevweb »

Bonsoir,

Merci pour vos réponses... Voici perso la petites procédure que j'ai pondu tout à fait finie mais enfin.

Code : Tout sélectionner

Procedure Ligne_Pointille(x,y,w,h,TP.s)
  largeur=3
  Select TP
    Case "H"
      R=w/(largeur*2)
      For N=0 To R
        x1=x+((largeur*2)*N)
        Box(x1,y,largeur,h,$696969)
      Next
    Case "V"
  EndSelect
EndProcedure
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Ligne en poitillée

Message par djes »

Il y a aussi des codes windows qui utilisent GDI+, avec gestion de l'antialias et d'autres choses. Il faut chercher sur le(s) forum(s) et remonter assez loin dans le temps !
Répondre