USERCONTROL PERMETTANT D'AFFICHER UNE CARTE (OU N'IMPORTE QUELLE IMG) ET DE PLAC
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 2021
-
10 août 2007 à 08:03
ppphil
Messages postés2Date d'inscriptionmardi 31 mai 2005StatutMembreDernière intervention 6 septembre 2007
-
6 sept. 2007 à 14:15
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.
ppphil
Messages postés2Date d'inscriptionmardi 31 mai 2005StatutMembreDernière intervention 6 septembre 2007 6 sept. 2007 à 14:15
Encore deux petites améliorations :
Lorsque tu commence de déplacer tes images elles sautent en positionnant leur centre sur la souris. Normal puisque
Top = Top + e.Y - Height / 2; //idem pour left
Si sur le MouseDown tu enregistre deux champs StartX et StartY avec e.X et e.Y et que tu modifie le code du MouseMove en :
Top = Top + e.Y - StartY; c'est beaucoup plus propre, surtout si tu as de grandes images.
Pour ce qui est du décalage des images lors du redimentionnement de l'image de fond, il ne s'agit pas du tout de l'arrondi entre double et int comme je l'ai dis dans le précédent commentaire. C'est simplement que le coin haut gauche reste toujours à la même place sur l'image mais que la taille de l'image ne suit pas celle du fond. Cela donne une impression de décalage. Pour palier à cela je définis deux champs supplémentaire à mon image soit fTopC et fLeftC. Je définis des propriétés TopC et LeftC sur le Set desquelles je recalcule de Top et le Left en fonction de la taille de l'image soit (bon c'est du C# mais ça ne doit pas être difficile à traduire...)
private int fTopC;
private int fLeftC;
public int TopC
{
get
{
return fTopC;
}
set
{
fTopC = value;
Top = Convert.ToInt32(fTopC - (Height / 2));
}
}
public int LeftC
{
get
{
return fLeftC;
}
set
{
fLeftC = value;
Left = Convert.ToInt32(fLeftC - (Width / 2));
}
}
puis tu modifie le code du MouseMove en :
TopC = TopC + e.Y - StartY;
le MouseUp :
VRate = (double)TopC / Parent.Height;
HRate = (double)LeftC / Parent.Width; //enregistrement des rapports en image de font et punaise (voir commentaire précédent)
BtnOn = false;
Cursor.Current = Cursors.Default;
et la fonction pour déplacer l'image de la punaise :
public void MoveOnResize()
{
TopC = Convert.ToInt32(Parent.Height * VRate);
LeftC = Convert.ToInt32(Parent.Width * HRate);
}
ppphil
Messages postés2Date d'inscriptionmardi 31 mai 2005StatutMembreDernière intervention 6 septembre 2007 4 sept. 2007 à 11:24
Pour faire suivre tes punaises lors du changement de dimension de ton image de base tu peux jouer sur les rapports entre le Top et Left de chaque punaise et le Heigth et Width de l'image de base.
Pour tester j'ai fait une classe dérivée de PictureBox à laquelle j'ai ajouté deux champs soit pCentH et pCentV de type double (pour les punaises).
Lors du déplacement d'une punaise, sur le MouseUp tu mets à jour ces champs en divisant le Top de la punaise par le Height de l'image de base et idem pour le Left avec le Width.
Lors du redimentionnement de l'image de base, tu reprends les Height et Width de l'image et tu les multiplie par les pCentV et pCentH pour obtenir les nouveaux Top et Left des punaises.
Ca joue pas mal sauf que l'on se retrouve avec un petit décalage du aux arrondissements entre les double (pCentV-H) et les entiers (Top-Left).
cs_Bidou
Messages postés5487Date d'inscriptiondimanche 4 août 2002StatutMembreDernière intervention20 juin 201361 13 août 2007 à 15:17
Trimballer une instance de PictureBox pour chaque point... très mauvaise idée !
T'as meilleurs temps de définir toi-même ton object qui sera dessiner et qui représentera un tel point, sera bien plus performant (et plus modularisé par la même occasion).
anthonygego
Messages postés48Date d'inscriptionlundi 1 août 2005StatutMembreDernière intervention10 juillet 20081 11 août 2007 à 15:45
Je me disais bien que ça venais de l'image mais je n'avais pas pensé à ça ^^
preventionhs
Messages postés2Date d'inscriptionmardi 22 juillet 2003StatutMembreDernière intervention10 août 2007 10 août 2007 à 20:51
Merci pour vos commentaires.
Je me suis effectivement rapidement rendu compte du problème de la taille des images ... j'y travaille.
Pour ce qui est de mon problème, je viens de le résoudre avec la boucle suivante ... et ca marche !:
Dim aControl As Control
For Each aControl In Me.FondCarte.Controls
acontrol.Top .....
Next
Ces valeurs correspondent aux coordonnées de la pointe représentée sur l'image.
Je mets à jour les sources ASAP.
anthonygego
Messages postés48Date d'inscriptionlundi 1 août 2005StatutMembreDernière intervention10 juillet 20081 10 août 2007 à 12:26
J'ai un peu ragrdé à ton problème.
D'abord je te conseille de faire une collection qui contiendrait les PictureBox.
--> Private Pts As New Collection(Of PictureBox)
De plus, ça te permettrais d'ajouter des points d'intérets pendant l'utilisation, ensuite, pour le zoom, tu fais :
For Each Pt As PictureBox In Pts
Pt.Left = Pt.Left * 1.5
Pt.Top = Pt.Top * 1.5
Next
Seulement, en le faisant, j'ai rencontré un petit problème de décalage de quelques pixels (beacoup moins important que la décalage actuel) dont je n'ai pas de solution à te proposer :s
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 10 août 2007 à 08:03
l'image m'a l'air fait d'un seul bloc, c'est contre-performant...
stockes là sous forme de petites images, que tu recolleras facon mosaique. ta RAM te remerciera, et le temps d'execution s'en ressentira pour des cartes rpidement trop grandes pour ton code actuel.
6 sept. 2007 à 14:15
Lorsque tu commence de déplacer tes images elles sautent en positionnant leur centre sur la souris. Normal puisque
Top = Top + e.Y - Height / 2; //idem pour left
Si sur le MouseDown tu enregistre deux champs StartX et StartY avec e.X et e.Y et que tu modifie le code du MouseMove en :
Top = Top + e.Y - StartY; c'est beaucoup plus propre, surtout si tu as de grandes images.
Pour ce qui est du décalage des images lors du redimentionnement de l'image de fond, il ne s'agit pas du tout de l'arrondi entre double et int comme je l'ai dis dans le précédent commentaire. C'est simplement que le coin haut gauche reste toujours à la même place sur l'image mais que la taille de l'image ne suit pas celle du fond. Cela donne une impression de décalage. Pour palier à cela je définis deux champs supplémentaire à mon image soit fTopC et fLeftC. Je définis des propriétés TopC et LeftC sur le Set desquelles je recalcule de Top et le Left en fonction de la taille de l'image soit (bon c'est du C# mais ça ne doit pas être difficile à traduire...)
private int fTopC;
private int fLeftC;
public int TopC
{
get
{
return fTopC;
}
set
{
fTopC = value;
Top = Convert.ToInt32(fTopC - (Height / 2));
}
}
public int LeftC
{
get
{
return fLeftC;
}
set
{
fLeftC = value;
Left = Convert.ToInt32(fLeftC - (Width / 2));
}
}
puis tu modifie le code du MouseMove en :
TopC = TopC + e.Y - StartY;
le MouseUp :
VRate = (double)TopC / Parent.Height;
HRate = (double)LeftC / Parent.Width; //enregistrement des rapports en image de font et punaise (voir commentaire précédent)
BtnOn = false;
Cursor.Current = Cursors.Default;
et la fonction pour déplacer l'image de la punaise :
public void MoveOnResize()
{
TopC = Convert.ToInt32(Parent.Height * VRate);
LeftC = Convert.ToInt32(Parent.Width * HRate);
}
4 sept. 2007 à 11:24
Pour tester j'ai fait une classe dérivée de PictureBox à laquelle j'ai ajouté deux champs soit pCentH et pCentV de type double (pour les punaises).
Lors du déplacement d'une punaise, sur le MouseUp tu mets à jour ces champs en divisant le Top de la punaise par le Height de l'image de base et idem pour le Left avec le Width.
Lors du redimentionnement de l'image de base, tu reprends les Height et Width de l'image et tu les multiplie par les pCentV et pCentH pour obtenir les nouveaux Top et Left des punaises.
Ca joue pas mal sauf que l'on se retrouve avec un petit décalage du aux arrondissements entre les double (pCentV-H) et les entiers (Top-Left).
13 août 2007 à 15:17
T'as meilleurs temps de définir toi-même ton object qui sera dessiner et qui représentera un tel point, sera bien plus performant (et plus modularisé par la même occasion).
11 août 2007 à 15:45
10 août 2007 à 20:51
Je me suis effectivement rapidement rendu compte du problème de la taille des images ... j'y travaille.
Pour ce qui est de mon problème, je viens de le résoudre avec la boucle suivante ... et ca marche !:
Dim aControl As Control
For Each aControl In Me.FondCarte.Controls
acontrol.Top .....
Next
Pour ce qui est du décalage, j'ai la solution :
aControl.Left = (aControl.Left + PointeurPicto_X) * 1.5 - PointeurPicto_X
où pointeurPicto_X = 4
et pointeurPicto_Y = 31
Ces valeurs correspondent aux coordonnées de la pointe représentée sur l'image.
Je mets à jour les sources ASAP.
10 août 2007 à 12:26
D'abord je te conseille de faire une collection qui contiendrait les PictureBox.
--> Private Pts As New Collection(Of PictureBox)
De plus, ça te permettrais d'ajouter des points d'intérets pendant l'utilisation, ensuite, pour le zoom, tu fais :
For Each Pt As PictureBox In Pts
Pt.Left = Pt.Left * 1.5
Pt.Top = Pt.Top * 1.5
Next
Seulement, en le faisant, j'ai rencontré un petit problème de décalage de quelques pixels (beacoup moins important que la décalage actuel) dont je n'ai pas de solution à te proposer :s
10 août 2007 à 08:03
stockes là sous forme de petites images, que tu recolleras facon mosaique. ta RAM te remerciera, et le temps d'execution s'en ressentira pour des cartes rpidement trop grandes pour ton code actuel.