## Examples of AffineTransform

• ae.java.awt.geom.AffineTransform
The `AffineTransform` class represents a 2D affine transform that performs a linear mapping from 2D coordinates to other 2D coordinates that preserves the "straightness" and "parallelness" of lines. Affine transformations can be constructed using sequences of translations, scales, flips, rotations, and shears.

Such a coordinate transformation can be represented by a 3 row by 3 column matrix with an implied last row of [ 0 0 1 ]. This matrix transforms source coordinates {@code (x,y)} intodestination coordinates {@code (x',y')} by consideringthem to be a column vector and multiplying the coordinate vector by the matrix according to the following process:

` [ x']   [  m00  m01  m02  ] [ x ]   [ m00x + m01y + m02 ] [ y'] = [  m10  m11  m12  ] [ y ] = [ m10x + m11y + m12 ] [ 1 ]   [   0    0    1   ] [ 1 ]   [         1         ] `

#### Handling 90-Degree Rotations

In some variations of the `rotate` methods in the `AffineTransform` class, a double-precision argument specifies the angle of rotation in radians. These methods have special handling for rotations of approximately 90 degrees (including multiples such as 180, 270, and 360 degrees), so that the common case of quadrant rotation is handled more efficiently. This special handling can cause angles very close to multiples of 90 degrees to be treated as if they were exact multiples of 90 degrees. For small multiples of 90 degrees the range of angles treated as a quadrant rotation is approximately 0.00000121 degrees wide. This section explains why such special care is needed and how it is implemented.

Since 90 degrees is represented as `PI/2` in radians, and since PI is a transcendental (and therefore irrational) number, it is not possible to exactly represent a multiple of 90 degrees as an exact double precision value measured in radians. As a result it is theoretically impossible to describe quadrant rotations (90, 180, 270 or 360 degrees) using these values. Double precision floating point values can get very close to non-zero multiples of `PI/2` but never close enough for the sine or cosine to be exactly 0.0, 1.0 or -1.0. The implementations of `Math.sin()` and `Math.cos()` correspondingly never return 0.0 for any case other than `Math.sin(0.0)`. These same implementations do, however, return exactly 1.0 and -1.0 for some range of numbers around each multiple of 90 degrees since the correct answer is so close to 1.0 or -1.0 that the double precision significand cannot represent the difference as accurately as it can for numbers that are near 0.0.

The net result of these issues is that if the `Math.sin()` and `Math.cos()` methods are used to directly generate the values for the matrix modifications during these radian-based rotation operations then the resulting transform is never strictly classifiable as a quadrant rotation even for a simple case like `rotate(Math.PI/2.0)`, due to minor variations in the matrix caused by the non-0.0 values obtained for the sine and cosine. If these transforms are not classified as quadrant rotations then subsequent code which attempts to optimize further operations based upon the type of the transform will be relegated to its most general implementation.

Because quadrant rotations are fairly common, this class should handle these cases reasonably quickly, both in applying the rotations to the transform and in applying the resulting transform to the coordinates. To facilitate this optimal handling, the methods which take an angle of rotation measured in radians attempt to detect angles that are intended to be quadrant rotations and treat them as such. These methods therefore treat an angle theta as a quadrant rotation if either `Math.sin(theta)` or `Math.cos(theta)` returns exactly 1.0 or -1.0. As a rule of thumb, this property holds true for a range of approximately 0.0000000211 radians (or 0.00000121 degrees) around small multiples of `Math.PI/2.0`. @author Jim Graham @since 1.2

• chunmap.model.crs.transf.AffineTransform
仿射变换 @author chunquedong
• com.itextpdf.awt.geom.AffineTransform
• com.jgraph.gaeawt.java.awt.geom.AffineTransform
• com.sk89q.worldedit.math.transform.AffineTransform

• java.awt.geom.AffineTransform
The `AffineTransform` class represents a 2D affine transform that performs a linear mapping from 2D coordinates to other 2D coordinates that preserves the "straightness" and "parallelness" of lines. Affine transformations can be constructed using sequences of translations, scales, flips, rotations, and shears.

Such a coordinate transformation can be represented by a 3 row by 3 column matrix with an implied last row of [ 0 0 1 ]. This matrix transforms source coordinates {@code (x,y)} intodestination coordinates {@code (x',y')} by consideringthem to be a column vector and multiplying the coordinate vector by the matrix according to the following process:

` [ x']   [  m00  m01  m02  ] [ x ]   [ m00x + m01y + m02 ] [ y'] = [  m10  m11  m12  ] [ y ] = [ m10x + m11y + m12 ] [ 1 ]   [   0    0    1   ] [ 1 ]   [         1         ] `

#### Handling 90-Degree Rotations

In some variations of the `rotate` methods in the `AffineTransform` class, a double-precision argument specifies the angle of rotation in radians. These methods have special handling for rotations of approximately 90 degrees (including multiples such as 180, 270, and 360 degrees), so that the common case of quadrant rotation is handled more efficiently. This special handling can cause angles very close to multiples of 90 degrees to be treated as if they were exact multiples of 90 degrees. For small multiples of 90 degrees the range of angles treated as a quadrant rotation is approximately 0.00000121 degrees wide. This section explains why such special care is needed and how it is implemented.

Since 90 degrees is represented as `PI/2` in radians, and since PI is a transcendental (and therefore irrational) number, it is not possible to exactly represent a multiple of 90 degrees as an exact double precision value measured in radians. As a result it is theoretically impossible to describe quadrant rotations (90, 180, 270 or 360 degrees) using these values. Double precision floating point values can get very close to non-zero multiples of `PI/2` but never close enough for the sine or cosine to be exactly 0.0, 1.0 or -1.0. The implementations of `Math.sin()` and `Math.cos()` correspondingly never return 0.0 for any case other than `Math.sin(0.0)`. These same implementations do, however, return exactly 1.0 and -1.0 for some range of numbers around each multiple of 90 degrees since the correct answer is so close to 1.0 or -1.0 that the double precision significand cannot represent the difference as accurately as it can for numbers that are near 0.0.

The net result of these issues is that if the `Math.sin()` and `Math.cos()` methods are used to directly generate the values for the matrix modifications during these radian-based rotation operations then the resulting transform is never strictly classifiable as a quadrant rotation even for a simple case like `rotate(Math.PI/2.0)`, due to minor variations in the matrix caused by the non-0.0 values obtained for the sine and cosine. If these transforms are not classified as quadrant rotations then subsequent code which attempts to optimize further operations based upon the type of the transform will be relegated to its most general implementation.

Because quadrant rotations are fairly common, this class should handle these cases reasonably quickly, both in applying the rotations to the transform and in applying the resulting transform to the coordinates. To facilitate this optimal handling, the methods which take an angle of rotation measured in radians attempt to detect angles that are intended to be quadrant rotations and treat them as such. These methods therefore treat an angle theta as a quadrant rotation if either `Math.sin(theta)` or `Math.cos(theta)` returns exactly 1.0 or -1.0. As a rule of thumb, this property holds true for a range of approximately 0.0000000211 radians (or 0.00000121 degrees) around small multiples of `Math.PI/2.0`. @version 1.77, 03/09/06 @author Jim Graham @since 1.2

• pythagoras.f.AffineTransform
Implements an affine (3x2 matrix) transform. The transformation matrix has the form:
` {@code [ m00, m10, tx ] [ m01, m11, ty ] [   0,   0,  1 ]}`

### Examples of java.awt.geom.AffineTransform

 `139013911392139313941395139613971398139914001401` ```    final double scalex = dwidth / swidth;     final double scaley = dheight / sheight;     final double transx = sx1 * scalex;     final double transy = sy1 * scaley;     final AffineTransform tx = AffineTransform.getTranslateInstance(dx1 - transx, dy1 - transy);     tx.scale(scalex, scaley);     final BufferedImage mask = new BufferedImage(img.getWidth(observer), img.getHeight(observer),         BufferedImage.TYPE_BYTE_BINARY);     final Graphics g = mask.getGraphics();     g.fillRect(sx1, sy1, (int) swidth, (int) sheight); ```
View Full Code Here

### Examples of java.awt.geom.AffineTransform

 `1583158415851586158715881589159015911592159315941595` ```  }   private AffineTransform normalizeMatrix()   {     final double[] mx = new double[6];     AffineTransform result = AffineTransform.getTranslateInstance(0, 0);     result.getMatrix(mx);     mx[3] = -1;     mx[5] = height;     result = new AffineTransform(mx);     result.concatenate(transform);     return result;   } ```
View Full Code Here

### Examples of java.awt.geom.AffineTransform

 `164416451646164716481649165016511652165316541655` ```    }     xform.translate(0, img.getHeight(obs));     xform.scale(img.getWidth(obs), img.getHeight(obs));     final AffineTransform inverse = this.normalizeMatrix();     final AffineTransform flipper = FLIP_TRANSFORM;     inverse.concatenate(xform);     inverse.concatenate(flipper);     try     { ```
View Full Code Here

### Examples of java.awt.geom.AffineTransform

 `1779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836` ```        final TexturePaint tp = (TexturePaint)paint;         final BufferedImage img = tp.getImage();         final Rectangle2D rect = tp.getAnchorRect();         final com.lowagie.text.Image image = com.lowagie.text.Image.getInstance(img, null);         final PdfPatternPainter pattern = cb.createPattern(image.getWidth(), image.getHeight());         final AffineTransform inverse = this.normalizeMatrix();         inverse.translate(rect.getX(), rect.getY());         inverse.scale(rect.getWidth() / image.getWidth(), -rect.getHeight() / image.getHeight());         final double[] mx = new double[6];         inverse.getMatrix(mx);         pattern.setPatternMatrix((float)mx[0], (float)mx[1], (float)mx[2], (float)mx[3], (float)mx[4], (float)mx[5]) ;         image.setAbsolutePosition(0,0);         pattern.addImage(image);         if (fill)             cb.setPatternFill(pattern);         else             cb.setPatternStroke(pattern);       }       catch (Exception ex)       {         if (fill)         {           cb.setColorFill(Color.gray);         }         else         {           cb.setColorStroke(Color.gray);         }       }     }     else     {       try       {         int type = BufferedImage.TYPE_4BYTE_ABGR;         if (paint.getTransparency() == Transparency.OPAQUE)         {           type = BufferedImage.TYPE_3BYTE_BGR;         }         final BufferedImage img = new BufferedImage((int) width, (int) height, type);         final Graphics2D g = (Graphics2D) img.getGraphics();         g.transform(transform);         final AffineTransform inv = transform.createInverse();         Shape fillRect = new Rectangle2D.Double(0, 0, img.getWidth(), img.getHeight());         fillRect = inv.createTransformedShape(fillRect);         g.setPaint(paint);         g.fill(fillRect);         if (invert)         {           final AffineTransform tx = new AffineTransform();           tx.scale(1, -1);           tx.translate(-xoffset, -yoffset);           g.drawImage(img, tx, null);         }         g.dispose();         // g = null;         final com.lowagie.text.Image image = com.lowagie.text.Image.getInstance(img, null); ```
View Full Code Here

### Examples of java.awt.geom.AffineTransform

 `208209210211212213214215216217218219` ```    }         final String attributeText = String.valueOf(attribute);     final PdfAction action = PdfAction.javaScript(attributeText, writer, false);     final AffineTransform affineTransform = getGraphics().getTransform();     final float translateX = (float) affineTransform.getTranslateX();     final float leftX = translateX + (float) (StrictGeomUtility.toExternalValue(box.getX()));     final float rightX = translateX + (float) (StrictGeomUtility.toExternalValue(box.getX() + box.getWidth()));     final float lowerY = (float) (globalHeight - StrictGeomUtility.toExternalValue(box.getY() + box.getHeight()));     final float upperY = (float) (globalHeight - StrictGeomUtility.toExternalValue(box.getY())); ```
View Full Code Here

### Examples of java.awt.geom.AffineTransform

 `231232233234235236237238239240241242` ```    final String anchorName = (String) content.getStyleSheet().getStyleProperty(ElementStyleKeys.ANCHOR_NAME);     if (anchorName == null)     {       return;     }     final AffineTransform affineTransform = getGraphics().getTransform();     final float translateX = (float) affineTransform.getTranslateX();     final float upperY = translateX + (float) (globalHeight - StrictGeomUtility.toExternalValue(content.getY()));     final float leftX = (float) (StrictGeomUtility.toExternalValue(content.getX()));     final PdfDestination dest = new PdfDestination(PdfDestination.FIT, leftX, upperY, 0);     writer.getDirectContent().localDestination(anchorName, dest); ```
View Full Code Here

### Examples of java.awt.geom.AffineTransform

 `248249250251252253254255256257258259` ```    {       return;     }     final PdfOutline root = writer.getDirectContent().getRootOutline();     final AffineTransform affineTransform = getGraphics().getTransform();     final float translateX = (float) affineTransform.getTranslateX();     final float upperY = translateX + (float) (globalHeight - StrictGeomUtility.toExternalValue(box.getY()));     final float leftX = (float) (StrictGeomUtility.toExternalValue(box.getX()));     final PdfDestination dest = new PdfDestination(PdfDestination.FIT, leftX, upperY, 0);     new PdfOutline(root, dest, bookmark); ```
View Full Code Here

### Examples of java.awt.geom.AffineTransform

 `268269270271272273274275276277278279` ```      return;     }     final PdfAction action = createActionForLink(target);     final AffineTransform affineTransform = getGraphics().getTransform();     final float translateX = (float) affineTransform.getTranslateX();     final float leftX = translateX + (float) (StrictGeomUtility.toExternalValue(box.getX()));     final float rightX = translateX + (float) (StrictGeomUtility.toExternalValue(box.getX() + box.getWidth()));     final float lowerY = (float) (globalHeight - StrictGeomUtility.toExternalValue(box.getY() + box.getHeight()));     final float upperY = (float) (globalHeight - StrictGeomUtility.toExternalValue(box.getY())); ```
View Full Code Here

### Examples of java.awt.geom.AffineTransform

 `320321322323324325326327328329330331332333334335336337338` ```  {     /**      * Apply the normalisation shape transform ... bring the shape to pos (0,0)      */     final Rectangle2D bounds = shape.getBounds2D();     final AffineTransform translateTransform         = AffineTransform.getTranslateInstance(0 - bounds.getX(), 0 - bounds.getY());     // apply normalisation translation ...     final Shape translatedShape = translateTransform.createTransformedShape(shape);     final AffineTransform scaleTransform = AffineTransform.getScaleInstance(scaleX, scaleY);     // apply scaling ...     final Shape scaledShape = scaleTransform.createTransformedShape(translatedShape);     // now retranslate the shape to its original position ...     final AffineTransform translateBackTransform =         AffineTransform.getTranslateInstance(bounds.getX(), bounds.getY());     return translateBackTransform.createTransformedShape(scaledShape);   } ```
View Full Code Here

### Examples of java.awt.geom.AffineTransform

 `362363364365366367368369` ```      retval.setLine(retval.getX1() + x, retval.getY1() + y,           retval.getX2() + x, retval.getY2() + y);       return retval;     }     final AffineTransform af = AffineTransform.getTranslateInstance(x, y);     return af.createTransformedShape(s);   } ```
View Full Code Here