Vb6 - déplacement d'un contrôle sur un segment de droite délimité par deux points de coordonnées connues

Contenu du snippet

Une très récente discussion me donne à penser que cette petite "démo" de l'utilisation de l'algèbre n'est pas inutile.
On traite ici :
- de la détermination de l'équation d'une droite passant par deux points connus
- du déplacement d'un objet (contrôle de votre choix) sur le segment dont il s'agit et :
---- cas particulier de l'horizontale ou de la verticale
---- choix de la coordonnée à faire varier en vue de la recherche d'une "modération" de la vitesse de parcours
NOTA BENE : j'ai voulu me concentrer sur le déplacement en soi, sans autres considérations que celles de l'algèbre :
--- C'est la raison pour laquelle :
1) je n'ai pas alourdi par un timer
2) je ne traite pas du "double buffering" qui n'aurait pas directement grand-chose à voir dans cette démo d'utilisation de l'algèbre pour le déplacement (seul considéré ici)

J'ajoute que je suis allé au plus simple (et c'est apparemment beaucoup pour certains) pour que ce soit à la portée d'un plus grand nombre. Je n'ai pas voulu, dans cet esprit, traiter la vitesse d'avancement comme je le fais pour moi-même, c'est à dire non, comme ici, en fonction d'une progression d'une ordonnée, mais en fonction de "distances intermédiaires" parcourues dans la boucle d'avancement.
J'ajoute que je me suis également abstenu de traiter d'autres aspects plus complexes, que je traite pour certaines de mes applis, tels la ligne d'horizon, les "fuyantes", la profondeur, les dimensions (les aspects de la perspective, quoi !)

En Bref : vous n'avez là que l'essentiel de la compréhension de l'adaptation de l'algèbre au cas le plus simple : celui_ du déplacement dans un seul plan, que vous "regardez" à la perpendiculaire d'une distance suffisamment grande pour que l'on puisse considérer que vous êtes à la verticale de chacun des points de votre plan.

Je ne mets pas de "zip" complètement inutile !
Voilà ce dont vous avez besoin :
Un form Form1 sur lequel vous "posez" un contrôle Line "Line1" et un contrôle Shape "témoin". C'est tout ! et le code qui suit :
Lancer : le reste deviendra évident.

Source / Exemple :


Option Explicit
Private Type mes_params
  coef As Single
  constante As Single
  incli As String
  sensx As Integer
  sensy As Integer
End Type
Private encours As Boolean

Private Sub Form_Activate()
   'tout ce qui estr ici est sans intérêt : juste pour initialiser chaque chose.
   With Me
     .AutoRedraw = True
     .ScaleMode = vbPixels
     DoEvents
     .WindowState = vbMaximized
  End With
  With temoin
   .Move 100, 100, 20, 20
   .BackColor = vbWhite
   .BackStyle = 1
   End With
   With Line1
     .BorderStyle = 1
     .BorderColor = vbBlack
     .BorderWidth = 1
     .x1 = 0
     .y1 = 200
   End With

   Me.Print "Chaque fois que vous cliquerez sur ce Form :"
  Me.Print "vous déplacerez laz seconde extrêmité de la ligne Line1"
  Me.Print "le coin supérieur gauche du petit carré blanc (shape temoin) se mettra alors à parcourir le chemin ainsi défini"
  Me.Print "attendez la fin du parcours puis cliquez à nouveau où vous voulez"
  Me.Print "un nouveau chemin, du dernier point, vers un nouveau point, sera celui qui sera maintenant parcouru, etc..."
  
End Sub

Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
'chaque fois que l'on clique sur le form, on modifie la position de l'extrêmité et on donne à la première les coordonées de la précédente
    If encours Then Exit Sub
    Line1.x1 = Line1.x2
    Line1.y1 = Line1.y2
    Line1.x2 = X
    Line1.y2 = Y
    allons
End Sub
Private Sub allons()
  ' on utilise ici les résultats algébriques (mais aussi autres) de la fonction param_droite
  encours = True
  Dim x1 As Integer, x2 As Integer, y1 As Integer, y2 As Integer, i As Integer, duree As Double, pas As Integer
  x1 = Line1.x1
  x2 = Line1.x2
  y1 = Line1.y1
  y2 = Line1.y2
  '============================réglages vitesse ==============
  duree = 0.005 'durée d'attente entre deux positions, en secondes
  pas = 5 ' pas d'avancement sur le segment
  '======================================================
  With param_droite(x1, x2, y1, y2)
    Select Case .incli
      Case "V" ' on traite bien évidemment différemment le cas d'une droite parfaitement verticale
        For i = y1 To y2 Step pas * .sensy
          If Not encours Then Exit Sub
          temoin.Left = x1
          temoin.Top = i
          attente duree
        Next
        encours = False
      Case "H" ' ' on traite bien évidemment différemment le cas d'une droite parfaitement horizontale
        For i = x1 To x2 Step pas * .sensx
        If Not encours Then Exit Sub
          temoin.Left = i
          temoin.Top = y1
          attente duree
        Next
        encours = False
      Case Else
        ' pour "modérer" la vitesse, on va détermier le "décalage"  le plus important : celui des ordonnées ou celui des abscisses ?
        If Abs(x1 - x2) >= Abs(y1 - y2) Then ' si décalage abscisses plus important ; on fit varier les abscisses
          For i = x1 To x2 Step pas * .sensx ' sensx = -1 ou +1 selon que abscisses décroissantes ou croissantes
            If Not encours Then Exit Sub
            temoin.Left = i
            temoin.Top = (.coef * i) + .constante
            attente duree
          Next
        Else ' si décalage ordonnées plus important, on fait varier les ordonnées
          For i = y1 To y2 Step pas * .sensy ' sensx = -1 ou +1 selon que ordonnées décroissantes ou croissantes
            If Not encours Then Exit Sub
            temoin.Top = i
            temoin.Left = (i - .constante) / .coef
            attente duree
          Next
        End If
    End Select
  End With
  temoin.Move x2, y2
  encours = False
End Sub

Private Function param_droite(x1 As Integer, x2 As Integer, y1 As Integer, y2 As Integer) As mes_params
  'voilà la seule fonction intéressante : celle qui utilise l'algèbre
  ' et traite les cas particuliers (horizontale et verticales pures)
  With param_droite
   .sensx = 1
   .sensy = 1
    If x1 = x2 Then
      .coef = 0
      .constante = 0
      .incli = "V"
    If y2 < y1 Then .sensy = -1
  Else
    If y1 = y2 Then .incli = "H"
    .coef = (y1 - y2) / (x1 - x2)
    .constante = y1 - (.coef * x1)
    If x2 < x1 Then .sensx = -1 ' on est dans le cas d'abscisses décroissantes
    If y2 < y1 Then .sensy = -1 ' on est dans le cas d'ordonnées décroissantes
  End If
  End With
End Function

Private Sub attente(duree As Double)
  'ce n'est là qu'un petit "tempo" pour éviter d'ajouter un timer
  Dim deb As Single
  deb = Timer
  Do While Timer < deb + duree
    DoEvents
    Loop
  End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
  encours = False
End Sub

Conclusion :


Je donne à ce code le niveau "débutant" . C'est celui qu'il mérite en ce qui concerne le code.
Et je ne vois pas d'autres type d'appréciation du niveau ...

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.