IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Interfaces Graphiques en Java Discussion :

Zoom puis translation avec AffineTransform


Sujet :

Interfaces Graphiques en Java

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    142
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 142
    Points : 93
    Points
    93
    Par défaut Zoom puis translation avec AffineTransform
    Bonjour tout le monde,

    J'ai cherché sur le forum mais je n'ai pas trouvé de solution à mon problème alors désolée si je relance un vieux sujet.....

    J'ai une appli qui fait du dessin assez simple (trait, rond, etc...) et qui charge en fond une image SVG à l'aide de la librairie batik. Je fais des zooms et des translations sur mon dessin sans utiliser AffineTransform mais en recalculant la position des éléments de mon dessin ce qui se passent très bien.

    Mon soucis est que je dois faire des zooms et des translations également sur mon image de fond. J'ai voulu utiliser Affine Transform qui me parait bien adaptée à mon problème car il faut gérer l'image svg issue de batik.
    Mon soucis, c'est qu'une fois que j'ai fait un zoom, mes translations deviennent "fausses".

    Je m'explique :

    Quand je fais des translations, tout se passe bien (mon dessin et mon image se suivent).
    Ensuite je fais un zoom (la, ca se passe bien) puis je refais une translationet ca ne fonctionnent plus. Il y a un décalage de plus en plus grand (ou petit) qui s'installe entre mon image et mon dessin.

    J'espère que c'est clair car ce n'est pas facile à expliquer....
    Je vous met le code de la classe qui gère le canvas avec l'image de fond. Ce canvas est inséré dans un JPanel où se dessine le dessin :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
     
     
    public class ZoneSVG extends JSVGCanvas implements MouseListener,MouseMotionListener,MouseWheelListener,WindowListener,KeyListener
    {
                 double tx;
    	 double ty;
                 zonedessin zd; //JPanel contenant le JSVGCanvas
    	 double rapechelle;
     
    	AffineTransform t;
     
    	public ZoneSVG(zonedessin zd)
    	{
    		this.setSize(800, 700);
    		this.zd=zd;
    	    Color bg=new Color((float)1.0,(float)1.0,(float)1.0,(float)0.0);
    	    this.setBackground(bg);	    
    	    t=new AffineTransform();
    	}
    	/**Cette fonction est la fonction de dessin sur l’interface.
             */ 
    	public void paintComponent (Graphics g) 
    	{
    		Graphics2D g2=(Graphics2D)g;
    		super.paintComponent(g2);
    	}
    	/**Cette fonction permet l'initialisation du canvas SVG.
             * Elle permet l'ajout des listener sur le JSVGCanvas.
             */
    	public void initialisation() 
    	{		
    		setPreferredSize(new Dimension(800, 700));
    		rapechelle=1.0;
    		this.setBounds(0,0,800,700);
    		addKeyListener(this);
    		addMouseMotionListener(new MouseMotionAdapter()
    				{ 
    		      		public void mouseDragged(MouseEvent e)
    		      		{ 
    		      			mouvementsouris(e);
    		      		}
    		      								); 
    		addMouseWheelListener(new MouseWheelListener()
    				{ 
    			public void mouseWheelMoved(MouseWheelEvent e)
          		{
          			mouvementmolette(e);
     
     
          		}
    		        }
    						);		
    	}
    		/**Cette fonction gère ce qui se passe lorsque la souris est déplacée tout en maintenant un bouton enfoncé.*/
    	public void mouvementsouris(MouseEvent e)
    	{
     
    //calcul de dxdepensemble et dydepensemble
    						tx=dxdepensemblesvg;
    	ty=dydepensemblesvg;
    	t.translate(tx,ty);
     
    	setRenderingTransform(t);
    		}
     
    	}	
    	/**Cette fonction gère ce qui se passe lors d’un mouvement molette.*/
    	public void mouvementmolette(MouseWheelEvent e)
    	{
    		int mvt;
    		mvt=e.getWheelRotation();
                              if(mvt<0)
                             {
    		    rapechelle=1.2;
    		    t.scale(rapechelle, rapechelle);
    		}
    		if(mvt>0)
    		{
    			rapechelle=(1/1.2);
    			t.scale(rapechelle,rapechelle);
    		}			
    	setRenderingTransform(t);
    	}
    }

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    142
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 142
    Points : 93
    Points
    93
    Par défaut
    Bon, apparemment y a pas grand monde qui peut m'aider .

    A force de m'arracher les cheveux, je suis tombée (un peu par hasard) sur la fonction createInverse. Et je m'en suis sortie avec ca .

    En fait, à chaque fois que je fais une modif, j'enregistre la fonction inverse. Et avant de faire une modif, j'applique la derniere fonction inverse enregistrée. Ce qui fait que je travaille toujours sur une base qui est la même (dans mon cas, l'origine) et comme ça, ça marche !!!!!!!

    Voila, j'espère eviter un jour à quelqu'un de trop s'arracher les cheveux.....

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 5
    Points : 6
    Points
    6
    Par défaut
    Salut

    J'ai été confronté à un problème similaire, et je suis tombé ici en cherchant une réponse.
    J'ai trouvé une autre solution. Je ne sais pas si elle est plus simple, mais je l'expose ici afin qu'elle puisse servir...

    contexte
    Je travail sur des objets SVG via Batik (Java)
    Je fais interagir l'affichage en fonction de l'utilisateur via la souris (je repère la position lors d'un click). Mais les JSVGCanvas permettent déjà de telle action (zooms, translations...). Mon repère peut donc être modifié.

    Solution
    j'utilise la fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    getRenderingTransform()
    qui permet d'obtenir une transformation permettant de passer de l'état initial (image centrée, non translatée...) à l'état actuel.
    En récupérant les différents éléments de cette transformation, je reconstruit le changement de repère convertissant la position actuelle de la souris en la position qu'elle a dans le repère de mon dessin SVG (quelques soit la transfo).

    Avec ce principe, je travail toujours dans le même repère, celui initial, et je suis transparent au changement d'affichage à l'écran, tout en récupérant des info tel que la position de la souris par rapport au dessin affiché...

    Mon dessin est un repère, et je dois donner la valeur de l'abscisse de la souris lors d'un click. Les rotations ont été désactivées.
    Voila le bout de code correspondant.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    public void goToStyletPos(float posRelatif){
        	//Des transfo étant possible sur la figure, on ne peut convertir directement
        	//la position de la souris en énergie pour positionner le styler dans le graph.
        	//(translation, zoom... les rotations sont désactivées, et les zoom sont fait
        	//avec des ratio identique selon x et y bien que y ne soit pas utilisé ici)
        	//On transforme donc cette position posRelatif pour retrouver ce qu'elle serait
        	//dans un graph non transformé.
     
        	//transformation qui permetrait du graph initial d'obtenir le graph actuel
        	AffineTransform rat = getRenderingTransform();
        	//récupération des éléments de la matrice de transfo  (cf AffineTransform.java)
        	double[] mrat = {0, 0, 0, 0, 0, 0};
        	rat.getMatrix(mrat);
        	//changement de référentiel
        	final float posAbsolue = (float) ((posRelatif-mrat[4])*((float)width/this.getWidth())*(1/mrat[0]));
     
    ...
    avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    this.getWidth() //taille actuelle de l'écran d'affichage
     
    (float)width //taille de l'écran virtuelle dans lequel est construit l'image, 
    //servant à convertir la position à l'écran en valeur physique
    Pour la signification des éléments de la matrice de transfo, se référer au sources...


    En espérant que cela te serve à toi ou quelqu'un d'autre...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. problème avec AffineTransform
    Par slim_java dans le forum 2D
    Réponses: 2
    Dernier message: 30/06/2009, 17h11
  2. Anticrénelage avec AffineTransformations
    Par a7aa7a dans le forum 2D
    Réponses: 1
    Dernier message: 26/06/2009, 05h12
  3. Réponses: 7
    Dernier message: 20/10/2008, 22h37
  4. Recherche de fichiers puis copier avec chemin
    Par domiq44 dans le forum Shell et commandes GNU
    Réponses: 13
    Dernier message: 01/06/2007, 11h54
  5. Réponses: 2
    Dernier message: 16/06/2005, 14h48

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo