La classe AffineTransform décrit une fonction de transformation affine bidimensionnelle, qui est une transformation linéaire de coordonnées bidimensionnelles en coordonnées bidimensionnelles, maintenant la « rectitude » des graphiques bidimensionnels (Traduction : rectitude, c'est-à-dire la ligne droite après transformation) C'est toujours une ligne droite sans flexion, et un arc est toujours arc) et « parallélisme » (Annotation : parallélisme, fait en fait référence au maintien de la relation de position relative entre les figures bidimensionnelles inchangée, les lignes parallèles sont toujours des lignes parallèles et les angles d'intersection des lignes droites sécantes restent inchangés. Variables complexes apprises en deuxième année , " Rappelez-vous "Conformal Transformation/Conformal Transformation", les mathématiques sont reines !). La transformation affine peut être obtenue grâce à une combinaison d'une série de transformations atomiques, notamment : translation, échelle, retournement, rotation et cisaillement.
Ce type de transformation peut être représenté par une matrice 3×3, dont la dernière ligne est (0, 0, 1). Cette matrice de transformation transforme les coordonnées d'origine (x, y) en nouvelles coordonnées (x', y'). Ici, les coordonnées d'origine et les nouvelles coordonnées sont considérées comme le vecteur colonne tridimensionnel de la dernière ligne (1). le vecteur colonne d'origine est transformé par multiplication à gauche. La matrice obtient de nouveaux vecteurs colonnes :
[x'] [m00 m01 m02] [x] [m00*x+m01*y+m02] [y'] = [m10 m11 m12] [y] = [m10*x+m11*y+m12] [1 ] [ 0 0 1 ] [1] [ 1 ]
Plusieurs transformations affines typiques :
public statique AffineTransform getTranslateInstance (double tx, double ty)
Transformation de translation, déplacez chaque point vers (x+tx, y+ty), la matrice de transformation est :
[ 1 0 tx ] [ 0 1 ty ] [ 0 0 1 ]
(Annotation : La transformation de traduction est une sorte de « transformation de corps rigide ». Quiconque a étudié la physique au collège sait ce qu'est un « corps rigide ». C'est un objet idéal qui ne se déformera pas. Bien sûr, la traduction ne changera pas. les graphiques bidimensionnels. De la même manière, la « transformation de rotation » ci-dessous est également une transformation de corps rigide, et la « mise à l'échelle » et la « coupe transversale » changeront la forme du graphique.)
public statique AffineTransform getScaleInstance (double sx, double sy)
La transformation de mise à l'échelle agrandit (réduit) l'abscisse de chaque point à sx fois et agrandit (réduit) l'ordonnée à sy fois. La matrice de transformation est :
[ sx 0 0 ] [ 0 sy 0 ] [ 0 0 1 ]
public statique AffineTransform getShearInstance (double shx, double timide)
Transformation de cisaillement, la matrice de transformation est :
[ 1 shx 0 ] [ timide 1 0 ] [ 0 0 1 ]
Équivalent à une combinaison d'un cisaillement transversal et d'un cisaillement longitudinal
[ 1 0 0 ][ 1 shx 0 ] [ timide 1 0 ][ 0 1 0 ] [ 0 0 1 ][ 0 0 1 ]
(Note de traduction : la « transformation par cisaillement » est également appelée « transformation par erreur de coupe », qui fait référence à des propriétés similaires à l'instabilité du quadrilatère. Avez-vous déjà vu les portes coulissantes en fer dans les petits magasins de la rue ? Imaginez les barres de fer ci-dessus. Le processus du losange tirer est le processus de "mauvaise coupe").
public statique AffineTransform getRotateInstance (double thêta)
Transformation de rotation, le graphique cible fait pivoter les thêta radians dans le sens des aiguilles d'une montre autour de l'origine, la matrice de transformation est :
[ cos(thêta) -sin(thêta) 0 ] [ péché(thêta) cos(thêta) 0 ] [ 0 0 1 ]
public statique AffineTransform getRotateInstance (double thêta, double x, double y)
Transformation de rotation. Le graphique cible est pivoté dans le sens des aiguilles d'une montre de thêta radians avec (x, y) comme axe. La matrice de transformation est :
[ cos(theta) -sin(theta) xx*cos+y*sin] [ sin(theta) cos(theta) yx*sin-y*cos ] [ 0 0 1 ]
C'est équivalent au composite de deux transformations de translation et d'une transformation de rotation d'origine :
[1 0 -x][cos(theta) -sin(theta) 0][1 0 x] [0 1 -y][sin(theta) cos(theta) 0][0 1 y] [0 0 1 ] [0 0 1][0 0 1]
En géométrie, une transformation linéaire d'un espace vectoriel est suivie d'une translation. Ce processus est appelé transformation affine ou cartographie radiale.
Il peut être exprimé simplement comme suit : y = Ax + b, où la lettre en indice représente un vecteur et la lettre en gras A représente une matrice.
Ce n'est pas grave si vous n'arrivez pas à le comprendre pour le moment (je ne le comprends pas non plus ^_^#), ce n'est pas grave, nous n'en utilisons ici que quelques cas particuliers : translation et rotation transformation.
Comme d'habitude, publions l'intégralité du code ci-dessous :
importer java.applet.Applet; importer java.awt.BorderLayout; importer java.awt.Checkbox; importer java.awt.CheckboxGroup; importer java.awt.Color; importer java.awt.Graphics; importer java.awt.Graphics2D; importer java.awt.Panel; importer java.awt.event.ItemEvent; importer java.awt.event.ItemListener; importer java.awt.geom.AffineTransform; importer java.awt.geom.Rectangle2D; importer java.util.Random; classe publique AffineTest étend l'applet implémente ItemListener {privé Rectangle2D rect; privé Case à cocher rotateFirst privé; Case à cocher TranslateFirst ; public void init() { setLayout(new BorderLayout()); CheckboxGroup cbg = new CheckboxGroup(); Panel p = new Panel(); rotateFirst = new Checkbox("rotate, translation", rotateFirst.addItemListener(this); ("traduire, faire pivoter", cbg, false); translationFirst.addItemListener(this); BorderLayout.SOUTH); rect = new Rectangle2D.Float (-0.5f, -0.5f, 1.0f, 1.0f); } public void paint (Graphics g) { Graphics2D g2d = (Graphics2D) g; final AffineTransform identifier = new AffineTransform (); boolean rotate = rotateFirst.getState(); Random r = new Random final(); oneRadian = Math.toRadians(1.0); pour(double radians = 0.0; radians < 2.0*Math.PI ; radians += oneRadian) { g2d.setTransform(identifier); if(rotate) { g2d.translate(100, 100) ; g2d.rotate(radians); } else { g2d.rotate(radians); g2d.translate(100, 100); } g2d.scale(100, 100); g2d.setColor(new Color(r.nextInt())); g2d.fill(rect); arg0) { // TODO Stub de méthode généré automatiquement repaint(); java.applet.Applet; importer java.awt.BorderLayout; importer java.awt.Checkbox; importer java.awt.CheckboxGroup; importer java.awt.Color; importer java.awt.Graphics; importer java.awt.Graphics2D; importer java .awt.Panel; importer java.awt.event.ItemEvent; importer java.awt.event.ItemListener; importer java.awt.geom.AffineTransform; importer java.awt.geom.Rectangle2D; importer java.util.Random; classe publique AffineTest étend l'applet implémente ItemListener {privé Rectangle2D rect; privé Case à cocher rotateFirst privé; Case à cocher TranslateFirst ; public void init() { setLayout(new BorderLayout()); CheckboxGroup cbg = new CheckboxGroup(); Panel p = new Panel(); rotateFirst = new Checkbox("rotate, translation", rotateFirst.addItemListener(this); ("traduire, faire pivoter", cbg, false); translationFirst.addItemListener(this); BorderLayout.SOUTH); rect = new Rectangle2D.Float (-0.5f, -0.5f, 1.0f, 1.0f); } public void paint (Graphics g) { Graphics2D g2d = (Graphics2D) g; final AffineTransform identifier = new AffineTransform (); boolean rotate = rotateFirst.getState(); Random r = new Random final(); oneRadian = Math.toRadians(1.0); pour(double radians = 0.0; radians < 2.0*Math.PI ; radians += oneRadian) { g2d.setTransform(identifier); if(rotate) { g2d.translate(100, 100) ; g2d.rotate(radians); } else { g2d.rotate(radians); g2d.translate(100, 100); } g2d.scale(100, 100); g2d.setColor(new Color(r.nextInt())); g2d.fill(rect); arg0) { // TODO Stub de méthode généré automatiquement repaint();
Par comparaison, on peut voir que l'ordre de transformation affine ne peut pas être échangé avec désinvolture.