adocris
Messages postés12Date d'inscriptionlundi 15 mai 2006StatutMembreDernière intervention31 mai 2007
-
30 mai 2007 à 01:25
adocris
Messages postés12Date d'inscriptionlundi 15 mai 2006StatutMembreDernière intervention31 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)
adocris
Messages postés12Date d'inscriptionlundi 15 mai 2006StatutMembreDernière intervention31 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 ... ?
jmfmarques
Messages postés7666Date d'inscriptionsamedi 5 novembre 2005StatutMembreDernière intervention22 août 201427 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
jmfmarques
Messages postés7666Date d'inscriptionsamedi 5 novembre 2005StatutMembreDernière intervention22 août 201427 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.
adocris
Messages postés12Date d'inscriptionlundi 15 mai 2006StatutMembreDernière intervention31 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
jmfmarques
Messages postés7666Date d'inscriptionsamedi 5 novembre 2005StatutMembreDernière intervention22 août 201427 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
adocris
Messages postés12Date d'inscriptionlundi 15 mai 2006StatutMembreDernière intervention31 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