Title: Transformations
Course: CPS 261: Advanced Java Concepts ~ DL & MM MASTER

Transformations

Built into Graphics2D is a coordinate transformation class known as an Affine Transformation. This function is capable of rotating Shapes, translating Shapes, and other transformations. Mathematically, an Affine transformation looks something like:

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

Don't worry we will never need to look at the mathematics involved, because useful functions are provided to do the work for us.

You can do your Affine Transformations using the built in class within the Graphics2D class. Alternatively you can construct your own AffineTransform class and do your transformations outside of the Graphics2D class.

Translation.java

Simple Translation


import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;

import javax.swing.JFrame;



public class Translation extends JFrame{
    Translation()
    {
        setSize(300, 220);
        setTitle("Translation");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }
    public void paint(Graphics g)
    {
       Graphics2D g2d = (Graphics2D) g.create();
       Rectangle2D.Double rectangle = new Rectangle2D.Double(40, 40, 80, 50);

       g2d.setPaint(Color.blue);
       g2d.fill(rectangle);

       g2d.translate(150, 50);
       g2d.setPaint(Color.red);
       g2d.fill(rectangle);

       g2d.dispose();
    }

    public static void main(String[] args)
    {
        Translation trn = new Translation();
    }

}





Rotations

Rotation followed by Translation.

Rotation.java

package transform;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;

import javax.swing.JFrame;

public class Rotation extends JFrame{
    Rotation()
    {
        setSize(600, 520);
        setTitle("Rotation");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }
    public void paint(Graphics g)
    {
        Graphics2D g2d = (Graphics2D) g.create();
        Rectangle2D.Double rectangle = new Rectangle2D.Double(300, 30, 80, 50);

        g2d.setPaint(Color.red);
        g2d.fill(rectangle);

        // Note that angles are specified as radians
        g2d.rotate(Math.PI/4); //Using Graphics2D built in AffineTransform
        g2d.setPaint(Color.blue);
        g2d.fill(rectangle);

        g2d.translate(85, 0);  //Using Graphics2D built in AffineTransform
        g2d.setPaint(Color.green);
        g2d.fill(rectangle);

        g2d.dispose();
    }

    public static void main(String[] args)
    {
        Rotation rot = new Rotation();
    }

}




Scaling.java


import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;

import javax.swing.JFrame;



public class Scaling extends JFrame{
    Scaling()
    {
        setSize(300, 220);
        setTitle("Scaling");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }
    public void paint(Graphics g)
    {
        Graphics2D g2d = (Graphics2D) g.create();
        Rectangle2D.Double rectangle = new Rectangle2D.Double(0, 0, 80, 50);

        g2d.setColor(Color.red);

        // Here we construct our own AffineTransform and plug it into Graphics2D
        AffineTransform tx1 = new AffineTransform();
        tx1.translate(20,40); // Move to (20,40)
        g2d.setTransform(tx1);
        g2d.fill(rectangle);

        tx1.translate(90, 0); // Move an additional 90 in the X-direction
        tx1.scale(0.5, 0.5);  // Scaling 0.5

        g2d.setTransform(tx1);
        g2d.setColor(Color.blue);
        g2d.fill(rectangle);

        AffineTransform tx2 = new AffineTransform();  // Start with a fresh Transform
        tx2.translate(160, 40);  // Move to (160,40)
        tx2.scale(1.5, 1.5);     /// Scaling to 1.5

        g2d.setTransform(tx2);
        g2d.setColor(Color.green);
        g2d.fill(rectangle);

        g2d.dispose();
    }

    public static void main(String[] args)
    {
        Scaling scl = new Scaling();
    }

}




Shearing.java


import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;

import javax.swing.JFrame;

public class Shearing extends JFrame{
    Shearing()
    {
        setSize(300, 520);
        setTitle("Shearing");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }
    public void paint(Graphics g)
    {
        Graphics2D g2d = (Graphics2D) g.create();
        g2d.setStroke(new BasicStroke(4));

        AffineTransform tx1 = new AffineTransform();
        tx1.translate(50, 90);

        g2d.setTransform(tx1);
        g2d.setPaint(Color.red);
        Rectangle2D.Double rectangle = new Rectangle2D.Double(0, 0, 160, 50);

        g2d.draw(rectangle);

        // Shearing:  Y increases with increasing X  .... pulling down affect

        AffineTransform tx2 = new AffineTransform();
        tx2.translate(50, 90);
        tx2.shear(0, .2);
        g2d.setTransform(tx2);
        g2d.setPaint(Color.blue);
        g2d.draw(rectangle);

        tx2.shear(0,.2);
        g2d.setTransform(tx2);
        g2d.setPaint(Color.green);
        g2d.draw(rectangle);

        // Start the second set of rectangles.

        Rectangle2D.Double secondRectangle = new Rectangle2D.Double(0, 0, 50, 160);
        // Shearing: X increases with increasing Y ..... pulling to the right effect
        AffineTransform tx3 = new AffineTransform();
        tx3.translate(50, 290);

        g2d.setTransform(tx3);
        g2d.setPaint(Color.orange);
        g2d.draw(secondRectangle);


        AffineTransform tx4 = new AffineTransform();
        tx4.translate(50, 290);
        tx4.shear(0.2, 0);
        g2d.setTransform(tx4);
        g2d.setPaint(Color.magenta);
        g2d.draw(secondRectangle);

        tx4.shear(0.2,0);
        g2d.setTransform(tx4);
        g2d.setPaint(Color.cyan);
        g2d.draw(secondRectangle);

        g2d.dispose();
    }

    public static void main(String[] args)
    {
        Shearing shr = new Shearing();
    }

}





DonutRotations.java



import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;

import javax.swing.JFrame;

public class DonutRotations extends JFrame{
    DonutRotations()
    {
        setSize(300, 520);
        setTitle("DonutRotations");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }
    public void paint(Graphics g)
    {
        Graphics2D g2d = (Graphics2D) g.create();

        RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);

        rh.put(RenderingHints.KEY_RENDERING,
                RenderingHints.VALUE_RENDER_QUALITY);

        g2d.setRenderingHints(rh);

        Dimension size = getSize();
        double w = size.getWidth();
        double h = size.getHeight();

        Ellipse2D ellipse = new Ellipse2D.Double(0, 0, 80, 130);
        g2d.setStroke(new BasicStroke(1));

        int colorIndex=255;
        for (double deg = 0; deg < 365; deg += 3) {
            AffineTransform affineTransform =
                    AffineTransform.getTranslateInstance(w / 2, h / 2);
            affineTransform.rotate(Math.toRadians(deg));
            g2d.setPaint(new Color(colorIndex));
            colorIndex += 230000;  // Having fun getting a range of colors
            Shape shape = affineTransform.createTransformedShape(ellipse);
            g2d.draw(shape);
        }
        g2d.dispose();
    }

    public static void main(String[] args)
    {
        DonutRotations dr = new DonutRotations();
    }

}










Last Updated: June 20, 2015 7:51 PM