Etirer une ligne à 45 degré (ou multiple de)

Résolu
Signaler
Messages postés
12
Date d'inscription
lundi 15 mai 2006
Statut
Membre
Dernière intervention
31 mai 2007
-
Messages postés
12
Date d'inscription
lundi 15 mai 2006
Statut
Membre
Dernière intervention
31 mai 2007
-
Bonjour,

Je suis très embêté par un problème :
J'aimerais pouvoir dessiner une ligne à la souris (dans une picture) mais selon des angles défini, c.à.d : horizontale, verticale, et 45-315-225-135 degrés.
C'est ce que l'on trouve souvent dans les prog de dessin en appuyant sur la touche ctrl ou shift pour brider l'angle d'un traçage de ligne.
Comment faire ???
(pour horizontal et vertical pas de problème .... mais pour les autres je me perds dans la trigo)

Merci de votre généreuse aide !

9 réponses

Messages postés
12
Date d'inscription
lundi 15 mai 2006
Statut
Membre
Dernière intervention
31 mai 2007

Re jfmmarques,


J'ai testé ton approche mais finalement elle ne correspond pas à mes attentes.
En effet, comme on dessine la ligne finale dans le mouseup la précision n'est pas au rendez-vous.
(c'est très important pour moi puisqu'il s'agit de coter des photos de microscopie !)
J'ai finalement pu tout intégrer dans le mousemove ce qui me permet de controler
directement la position de fin de ligne, même si le pointeur est à côté.
Mais tes conseils m'ont mis sur la bonne voie


A: j'ai une sub (appelée dans mousemove) qui me calcul en
permanence l'angle et la longueur de la ligne


B: Dans le mousemove
------------------------------
Private Sub picImage_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
    If Button = 1 Then
        picImage.Cls   


    'calcul l'angle et la longueur de la ligne
        Call CalculAngle(X, Y) 
       
                ' *** DESSINER LIGNE
                If chkBriderLigne.Value = 1 Then 'si option accrochage
                    Call BriderLigne(.mX1, .mY1)
                Else
                    picImage.Line (.mX1, .mY1)-(X, Y) 'sinon ligne libre
                End If
etc ....
               
               
C: La sub qui me positionne la ligne en fonction de la position de la souris
'Accrocher sur les multiples de 45°
--------------------------------------------------------
Private Sub BriderLigne(X As Single, Y As Single)
    Dim Angle As Double
    Dim Accrochage As Integer
    Dim x1 As Single
    Dim y1 As Single
    Dim x2 As Single
    Dim y2 As Single
    Const AC As Integer = 30    'accrochage selon angle +/- X°

    With mLignePointage        If (.Angle < 90 + AC And .Angle >90 - AC) Then Accrochage 90        If (.Angle < 45 + AC And .Angle >45 - AC) Then Accrochage 45
        If (.Angle < AC And .Angle >= 0) Or (.Angle < 360 And .Angle >= 360 - AC) Then Accrochage = 0        If (.Angle < 315 + AC And .Angle >315 - AC) Then Accrochage 315        If (.Angle < 270 + AC And .Angle >270 - AC) Then Accrochage 270        If (.Angle < 225 + AC And .Angle >225 - AC) Then Accrochage 225        If (.Angle < 180 + AC And .Angle >180 - AC) Then Accrochage 180        If (.Angle < 135 + AC And .Angle >135 - AC) Then Accrochage 135


        x1 = X    '.mX1
        y1 = Y    '.mY1
        Angle = (Accrochage * Pi) / 180
        x2 = x1 + .LongueurLigne * Cos(Angle)
        y2 = y1 - .LongueurLigne * Sin(Angle)
        picImage.Line (x1, y1)-(x2, y2)
        .mX3 = x2    'mémoriser fin de ligne bridée
        .mY3 = y2
        .Angle = Accrochage
    End With 
End Sub
------------
   
Voilà, ça pourra peut-être servir à d'autres ... ?   
Messages postés
7668
Date d'inscription
samedi 5 novembre 2005
Statut
Membre
Dernière intervention
22 août 2014
27
Bonjour,

Si c'est la trigo qui te gêne, voilà de quoi comprentre comment un donne un angle.
A toi de comprendre, d'en tirer ce dont tu as besoin et de te construire à partir de celà ce que tu veux...

Une Form et un contrôle timer Timer1

Option Explicit
Private Const diametre As Integer = 100
Private cy As Integer
Private cx As Integer
Private ancY As Single
Private ancx As Single
Private angle As Double




Private Sub Form_Activate()
    Me.ScaleMode = vbPixels
    Me.AutoRedraw = True
    cx = Me.ScaleWidth / 2
    cy = Me.ScaleHeight / 2
    Me.Circle (cx, cy), diametre, vbWhite
    Timer1.Interval = 100
End Sub


Private Sub Timer1_Timer()
  Dim pi As Double, toto As Double
  pi = 4 * Atn(1)
  toto = (angle / 180) * pi
  Me.Line (cx, cy)-(ancx, ancY), Me.BackColor
  ancY = cy + Sin(toto - (0.5 * pi)) * diametre
  ancx = cx + Cos(toto - (0.5 * pi)) * diametre
  Me.Line (cx, cy)-(ancx, ancY)
  angle = angle + 1
End Sub


 
Messages postés
4525
Date d'inscription
dimanche 29 septembre 2002
Statut
Modérateur
Dernière intervention
22 avril 2019
9
Il sufftit de decouper ta feuille en grille.

@+

E.B.
Messages postés
7668
Date d'inscription
samedi 5 novembre 2005
Statut
Membre
Dernière intervention
22 août 2014
27
Bonjour EBartSoft,

et bien viser au centre des cases, alors, ou, en fonction du click, rectifier par rapport au centre de la case (à calculer par code) ...

A moins qu'il ne dessine d'abord la "grille" d'aide et qu'il ne clique (avec une loupe ?) juste sur des intersections...

Je plaisante, bien évidemment....
Messages postés
12
Date d'inscription
lundi 15 mai 2006
Statut
Membre
Dernière intervention
31 mai 2007

Re bonjour,<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /??>





Merci pour vos réponses.





jfmmarques,





J’arrive bien à dessiner un ligne par le code (avec un angle et une taille défini )





Ce que je n’arrive pas faire, c’est de la tracer directement à la souris sur des multiples de 45° …





ps : Je trace mes lignes dans un Mouse_Move.





EbArtSoft :





Découper en grille ?





Je ne vois pas du tout comment faire ?





As tu un départ de réponse à me donner ?





 





Merci de votre aide




Chris
Messages postés
7668
Date d'inscription
samedi 5 novembre 2005
Statut
Membre
Dernière intervention
22 août 2014
27
adocris,
il me semble que ce que tu dois faire est ceci :
au mousemove : dessiner "à peu près"
au mouseup : corriger les coordonnées de la dexième extrêmité pour qu'elles correspondent à celles du point le plus proche qui, relié à la 1ère extrêmité, formerait l'angle de valeur (multiple de 45) la plus proche possible de l'angle que tu as tracé "à peu près".
Exemple : tu pas de A et trace au mousmove une ligne d'angle de 80 ° . 80 étant plus proche de 90 que de 45, tu fais cette comparaison au mouseup, décide que c'est 90 qui est plus proche, et corrige donc ton angle de 80 en angle de 90.Le code que je t'ai donné plus haut te permet de faire la chose puisque cela revient à dire que le point A est le centre d'un cercle de diamètre 2 fois la distance AB (calculable par l'application du théorème de pythagore) et qu'il reste donc uniquement à placer le point B en lui appliquant (dans la formule que tu trouve dans le Timer dans mon code) angle 90 ===>> la formule te donne alors les coordonnées du point B et il te suffit de relier alors A à B.


Il te faut bien évidemment jouer avec la propriété autoredraw et Cls, de sorte à :


1) rendre "volatile" ta ligne tracée "à peu près"


2) décider (comme exposé) de la véritable position corrigée du point B


3) effacer (CLS) ce qui est encore "volatile"


4) remettre à True la propriété Autoredraw


4) dessiner la ligne corrigée


Voilà ! tu as là tous les éléments dont tu as besoin.


Aller plus loin serait carrément t'écrire tout ton code et je ne pense pas que ce soit le but du jeu.


Pour te donner du courage : ce n'est pas difficile ! Il te faut simplement être méthodique et méticuleux.


Bon travail.
Messages postés
12
Date d'inscription
lundi 15 mai 2006
Statut
Membre
Dernière intervention
31 mai 2007

Merci beaucoup jfmmarques, c'est sympa de ta part !
Je pense qu'avec ces conseils je pourrai m'en sortir.
(je me laisse une petite porte ici au cas où :) )
Chris
Messages postés
7668
Date d'inscription
samedi 5 novembre 2005
Statut
Membre
Dernière intervention
22 août 2014
27
C'est bien et je suis content pour toi, mais
J'y avais également pensé mais n'ai pas voulu te le proposer pour la raison suivante :

En bridant ton angle au MouseMove, tu as intérêt à ne pas rater ton angle approximatif dès le début du tracé de ta ligne
Si tu ne te montre pas très adroit dans cette approximation de départ (dès les premiers pixels), tu te retrouves bridé sur un angle qui n'est pas forcément celui que tu voulais
C'est la raison pour laquelle j'ai préféré de suggérer de ne brider (corriger) qu'au mouseUp, ce qui te laissait la possibilité, à main levée, de corriger ton angle "à peu près" puis d'affiner au MouseUP en fonction de la dernière position à main levée
La chose est parfaitement réalisable
Mais si tu es très adroit, ta solution est certes bonne (faut pas trembler au départ du tracé, alors)
Amitiés
Messages postés
12
Date d'inscription
lundi 15 mai 2006
Statut
Membre
Dernière intervention
31 mai 2007

Re,
Non non, c'est très agréable et ne demande pas d'être particulièrement adroit,
à moins de dessiner de très petite ligne, genre 4-5 pixels, mais dans mon appli cela ne servirait à rien.
On étire et la ligne vers le point voulu, celle-ci continue avec l'angle le plus proche ou saute si on déplace la souris.
Ca fonctionne impec !
Amicalement