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

Résolu
adocris Messages postés 12 Date d'inscription lundi 15 mai 2006 Statut Membre Dernière intervention 31 mai 2007 - 30 mai 2007 à 01:25
adocris Messages postés 12 Date d'inscription lundi 15 mai 2006 Statut Membre Dernière intervention 31 mai 2007 - 31 mai 2007 à 18:05
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

adocris Messages postés 12 Date d'inscription lundi 15 mai 2006 Statut Membre Dernière intervention 31 mai 2007
31 mai 2007 à 10:25
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 ... ?   
3
jmfmarques Messages postés 7666 Date d'inscription samedi 5 novembre 2005 Statut Membre Dernière intervention 22 août 2014 27
30 mai 2007 à 07:20
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


 
0
cs_EBArtSoft Messages postés 4525 Date d'inscription dimanche 29 septembre 2002 Statut Modérateur Dernière intervention 22 avril 2019 9
30 mai 2007 à 08:36
Il sufftit de decouper ta feuille en grille.

@+

E.B.
0
jmfmarques Messages postés 7666 Date d'inscription samedi 5 novembre 2005 Statut Membre Dernière intervention 22 août 2014 27
30 mai 2007 à 08:46
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....
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
adocris Messages postés 12 Date d'inscription lundi 15 mai 2006 Statut Membre Dernière intervention 31 mai 2007
30 mai 2007 à 13:52
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
0
jmfmarques Messages postés 7666 Date d'inscription samedi 5 novembre 2005 Statut Membre Dernière intervention 22 août 2014 27
30 mai 2007 à 17:55
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.
0
adocris Messages postés 12 Date d'inscription lundi 15 mai 2006 Statut Membre Dernière intervention 31 mai 2007
30 mai 2007 à 19:05
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
0
jmfmarques Messages postés 7666 Date d'inscription samedi 5 novembre 2005 Statut Membre Dernière intervention 22 août 2014 27
31 mai 2007 à 11:05
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
0
adocris Messages postés 12 Date d'inscription lundi 15 mai 2006 Statut Membre Dernière intervention 31 mai 2007
31 mai 2007 à 18:05
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
0
Rejoignez-nous