Interfaces Graphiques Tracer une fonction y = f(x) avec JAVA 2D © Sofia ZAIDENBERG CNRS Mai 2007 1 Java 2D Afficher la courbe d’une fonction dans un fenêtre (un JPanel ou un JComponent) y x x y F(x) = sin(x) Espace écran : (« Device Coordinate System ») Espace utilisateur (« World Coordinate System ») Entier Borné Réel Non borné © Sofia ZAIDENBERG CNRS Mai 2007 2 Java 2D Afficher la courbe d’une fonction dans une fenêtre (un JPanel ou un JComponent) y x x y F(x) = sin(x) Espace écran : (« Device Coordinate System ») Espace utilisateur (« World Coordinate System ») 1 Définir la région de l’espace utilisateur à afficher 2 Appliquer au coordonnées exprimées dans WCS une transformation vers DCS Réel Non borné © Sofia ZAIDENBERG CNRS Entier Borné Mai 2007 3 Java 2D Définir la région de l'espace utilisateur à afficher y x xWmax yWmax . x . xWmin yWmin y DCS WCS Définition d’une fenêtre dans l’espace utilisateur : XWmin, YWmin coordonnées dans WCS du coin inférieur gauche de la fenêtre XWmax,YWmax coordonnées dans WCS du coin supérieur droit de la fenêtre © Sofia ZAIDENBERG CNRS Mai 2007 4 Java 2D Transformation coordonnées WCS coordonnées DCS y x xWmax yWmax . . . xw yw x xd yd hd . xWmin yWmin y xd yd WCS ld = T xw yw DCS T dépend de xWin, yWmin, xWmax, yWmax et de ld (largeur) et hd (hauteur) de la région d’affichage © Sofia ZAIDENBERG CNRS Mai 2007 5 Java 2D Transformation coordonnées WCS coordonnées DCS y . xWmax yWmax . . xw yw . x xd yd x hd . . xWmin yWmin y xd yd WCS T xWmin yWmin 0 hd T xWmax yWmax ld 0 © Sofia ZAIDENBERG ld = T xw yw CNRS Mai 2007 DCS 6 Java 2D Transformation coordonnées WCS coordonnées DCS y x xWmax yWmax . . . xw yw x xd yd hd . xWmin yWmin y xd yd WCS Les proportions doivent être conservées : La position relative de (xd,yd) par rapport à la région d’affichage doit être la même que la position relative de (xw,xw) par rapport à la fenêtre utilisateur xd = ld yd ld = T xw yw xw - xWmin DCS lw =(xWmax – xWmin) lw yWmax - yw = hd © Sofia ZAIDENBERG hw =(yWmax – yWmin) hw CNRS Mai 2007 7 Java 2D Transformation coordonnées WCS coordonnées DCS y x xWmax yWmax . . . xw yw x xd yd hd . xWmin yWmin y xd yd WCS ld = T xw yw DCS T xd = ld yd hd xw - xWmin lw yWmax - yw = hw ld xd = xw * lw - xWmin * ld lw hd yd = - yw * hw ld xd + yWmax * homothétie hd yd ld 0 lw = 0 hd - hw 1 translation © Sofia ZAIDENBERG CNRS 0 Mai 2007 hw 0 - xWmin * yWmax * lw hd xw * yw hw 1 1 8 Java 2D Transformation coordonnées WCS coordonnées DCS y . xWmax yWmax . . . xw yw x xd yd x hd . . xWmin yWmin y ld DCS WCS ld 0 hd 1 0 lw = 0 0 ld ld hd - hw 0 - xWmin * yWmax * lw hd * xWmin ld yWmin 0 lw = 0 hw 1 © Sofia ZAIDENBERG 1 1 CNRS ld 0 0 hd - hw 0 Mai 2007 - xWmin * yWmax * xWmax lw hd * yWmax hw 1 1 9 Java 2D Transformation WCS DCS : prise en charge par Java2D T public void paintComponent(Graphics g) { ld xd yd ld 0 lw = 1 0 0 hd - hw 0 - xWmin * yWmax * lw hd * xw super.paintComponent(g); yw Graphics2D g2 = (Graphics2D) g; 1 int ld = this.getWidth(); int hd = this.getEight(); double lw = xWmax - xWmin; ... double m00 = ld / lw; ... AffineTransform t = new AffineTransform( m00,0.0,0.0, m11,m02,m12); hw 1 T définie par un objet java.awt.AffineTransform [ x'] = [ m00 [ y'] = [ m10 [ 1 ] = [ 0 m01 m11 0 m02 ] [ x ] = [ m00x + m01y + m02 ] m12 ] [ y ] = [ m10x + m11y + m12 ] 1 ] [ 1 ] = [ 1 ] Cette transformation est combinée à la transformation courante maintenue par le contexte graphique Les coordonnées des primitives graphiques (« Shape ») sont ensuite exprimées dans WCS et seront automatiquement transformée lors du rendu. } © Sofia ZAIDENBERG CNRS g2.transform(t); ... g2.setStroke(new BasicStroke(0.0f)); ... g2.draw(aShape); Mai 2007 10 Java 2D public void paintComponent(Graphics g) { super.paintComponent(g); Échantillonnage de la courbe La courbe va être approximée par des segments de droite. Graphics2D g2 = (Graphics2D) g; int ld = this.getWidth(); int hd = this.getWidth(); double lw = xWmax - xWmin; ... double m00 = ld / lw; ... AffineTransform t = new AffineTransform( m00,0.0,0.0, m11,m02,m12); Prendre garde de ne pas tracer des primitives géométriques trop petites ( < 1 pixel) g2.transform(t); Le pas d’échantillonnage doit être fixé en fonction des dimension de l’espace d’affichage g2.setStroke(new BasicStroke(0.0f)); double pasX = lw / ld * 3.0; for (double x = xWmin; x <= xWmax; x += pasX) { tracer segment (x,f(x)) (x + pasX, f(x + pasX); } } © Sofia ZAIDENBERG CNRS Mai 2007 11