You are on page 1of 32

SCO 305 Computer Graphics

Transformations in 2 Dimensions

One of the most common and important tasks in computer graphics is to transform the
coordinates (position, orientation, and size) of either objects within the graphical scene or the
camera that is viewing the scene. It is also frequently necessary to transform coordinates from
one coordinate system to another, (e.g. world coordinates to viewpoint coordinates to screen
coordinates.)

All of these transformations can be efficiently and succinctly handled using some simple matrix
representations, which can be particularly useful for combining multiple transformations into a
single composite transform matrix.

This section deals with simple translation, scaling, and rotation in 2D, then extend our results to
3D, and finally see how multiple transformations can be easily combined into a composite
transform.

Translation in 2D

A translation is a function that moves every point a constant distance in a specified direction.
(Also in Euclidean geometry a transformation is a one to one correspondence between two sets
of points or a mapping from one plane to another

Point (X, Y) is to be translated by amount Dx and Dy to a new location (X',Y')

X' = Dx + X
Y' = Dy + Y

or P' = T + P where

_ _
P' = | X' |
| Y' |
- -
_ _
T = | Dx |
| Dy |
- -
_ _
P =| X |
| Y |
- -

1
CK
SCO 305 Computer Graphics

Scaling in 2D

Scaling is a linear transformation that enlarges (increases) or shrinks (diminishes) objects by a


scale factor that is the same in all directions. The result of uniform scaling is similar (in the
geometric sense) to the original

Point (X, Y) is to be scaled by amount Sx and Sy to location (X', Y)

X' = Sx * X
Y' = Sy * Y

Or P' = S * P where

_ _
P' = | X' |
| Y' |
- -
_ _
S = | Sx 0 |
| 0 Sy |
- -
_ _
P =| X |
| Y |
- -

Scaling is performed about the origin (0, 0) not about the center of the line/polygon/whatever

Scale > 1 enlarge the object and move it away from the origin.
Scale = 1 leave the object alone
Scale< 1 shrink the object and move it towards the origin.

Uniform scaling: Sx = Sy
differential scaling Sx != Sy -> alters proportions

The following example describes a simple translation.


Translation.java

package com.zetcode;

import java.awt.Color;

2
CK
SCO 305 Computer Graphics

import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

class Surface extends JPanel {

private void doDrawing(Graphics g) {

Graphics2D g2d = (Graphics2D) g;

g2d.setColor(new Color(150, 150, 150));


g2d.fillRect(20, 20, 80, 50);
g2d.translate(150, 50);
g2d.fillRect(20, 20, 80, 50);
}

@Override
public void paintComponent(Graphics g) {

super.paintComponent(g);
doDrawing(g);
}
}

public class Translation extends JFrame {

public Translation() {

initUI();
}

private void initUI() {

setTitle("Translation");

add(new Surface());

setSize(300, 200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}
3
CK
SCO 305 Computer Graphics

public static void main(String[] args) {

SwingUtilities.invokeLater(new Runnable() {

@Override
public void run() {

Translation trl = new Translation();


trl.setVisible(true);
}
});
}
}

The example draws a rectangle. Then we do a translation and draw the same rectangle again.

g2d.translate(150, 50);

This line moves the origin of the Graphics2D context to a new point.

Figure: Translation

Rotation in 2D

A rotation is a circular movement of an object around a center (or point) of rotation. A three-
dimensional object always rotates around an imaginary line called a rotation axis. If the axis
passes through the body's center of mass, the body is said to rotate upon itself, or spin

4
CK
SCO 305 Computer Graphics

Point (X, Y) is to be rotated about the origin by angle theta to location (X', Y)

X' = X * cos(theta) - Y * sin(theta)


Y' = X * sin(theta) + Y *cos(theta)

Note: this does involve sin and cos which are much more costly than addition or multiplication

or P' = R * P where

_ _
P' = | X' |
| Y' |
- -
_ _
R = | cos(theta) -sin(theta) |
| sin(theta) cos(theta) |
- -
_ _
P =| X |
| Y |
- -

Rotation is performed about the origin (0, 0) not about the center of the line/polygon/whatever

Derivation of the 2D Rotation Equations

Where does this matrix come from?

(X, Y) is located r away from (0, 0) at a CCW angle of phi from the X axis.
(X', Y) is located r away from (0, 0) at a CCW angle of theta + phi from the X axis.

Since rotation is about the origin, (X',Y') must be the same distance from the origin as (X,Y).

from trigonometry we have:

X = r * cos(phi)
Y = r * sin(phi)

and

X' = r * cos(theta+phi)
Y' = r * sin(theta+phi)

Now making use of the following trigonometric identities:


5
CK
SCO 305 Computer Graphics

cos(a+b) = cos(a) * cos(b) - sin(a) * sin(b)


sin(a+b) = sin(a) * cos(b) + cos(a) * sin(b)

and substituting in for the above equations for X' and Y', we get:

X' = r * cos(theta) * cos(phi) - r * sin(theta) * sin(phi)


Y' = r * sin(theta) * cos(phi) + r * cos(theta) * sin(phi)

Then we substitute in X and Y from their definitions above, and the final result simplifies to:

X' = X * cos(theta) - Y * sin(theta)


Y' = X * sin(theta) + Y * cos(theta)

Homogeneous Coordinates in 2 Dimensions

Scaling and rotations are both handled using matrix multiplication, which can be combined. The
translations cause a difficulty, however, since they use addition instead of multiplication.

We want to be able to treat all 3 transformations (translation, scaling, and rotation) in the same
way - as multiplications.

The solution is to give each point a third coordinate (X, Y, W), which will allow translations to be
handled as a multiplication also.

(Note that we are not really moving into the third dimension yet. The third coordinate is being
added to the mathematics solely in order to combine the addition and multiplication of 2-D
coordinates. )

Two triples (X, Y, W) and (X', Y, W) represent the same point if they are multiples of each other
e.g. (1, 2, 3) and (2, 4, 6).

At least one of the three coordinates must be nonzero.

If W is 0 then the point is at infinity. This situation will rarely occur in practice in computer
graphics.

If W is nonzero we can divide the triple by W to get the Cartesian coordinates of X and Y which
will be identical for triples representing the same point (X/W, Y/W, 1). This step can be considered
as mapping the point from 3-D space onto the plane W=1.

Conversely, if the 2-D Cartesian coordinates of a point are known as ( X, Y ), then the homogenous
coordinates can be given as ( X, Y, 1 )
6
CK
SCO 305 Computer Graphics

The next example demonstrates a rotation.

Rotation.java

package com.zetcode;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

class Surface extends JPanel {

private void doDrawing(Graphics g) {

Graphics2D g2d = (Graphics2D) g;

g2d.setColor(new Color(150, 150, 150));


g2d.fillRect(20, 20, 80, 50);
g2d.translate(180, -50);
g2d.rotate(Math.PI/4);
g2d.fillRect(80, 80, 80, 50);
}

@Override
public void paintComponent(Graphics g) {

super.paintComponent(g);
doDrawing(g);
}
}

public class Rotation extends JFrame {

public Rotation() {

initUI();
}

7
CK
SCO 305 Computer Graphics

private void initUI() {

setTitle("Rotation");

add(new Surface());

setSize(300, 200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}

public static void main(String[] args) {

SwingUtilities.invokeLater(new Runnable() {

@Override
public void run() {

Rotation rt = new Rotation();


rt.setVisible(true);
}
});
}
}

The example draws a rectangle, performs a translation and a rotation and draws the
same rectangle again.

g2d.rotate(Math.PI/4);

The rotate() method performs rotation. Note that the rotation parameter is in radians.

8
CK
SCO 305 Computer Graphics

Figure: Rotation

Translation of 2D Homogenous Coordinates

Point (X, Y) is to be translated by amount Dx and Dy to location (X', Y)

X' = Dx + X
Y' = Dy + Y

or P' = T * P where

_ _
P' = | X' |
| Y' |
| 1 |
- -
_ _
T = | 1 0 Dx | = T(Dx,Dy)
| 0 1 Dy |
| 00 1 |
- -
_ _
P =| X |
| Y |
| 1 |
- -

Hey Look! Translation is now a multiplication instead of an addition!

Scaling of 2D Homogenous Coordinates

9
CK
SCO 305 Computer Graphics

P' = S * P where
_ _
P' = | X' |
| Y' |
| 1 |
- -
_ _
S = | Sx 0 0 | = S(Sx,Sy)
| 0 Sy 0 |
| 0 01 |
- -
_ _
P =| X |
| Y |
| 1 |
- -

Rotation of 2D Homogenous Coordinates

P' = R * P where
_ _
P' = | X' |
| Y' |
| 1 |
- -
_ _
R = | cos(theta) -sin(theta) 0 | = R(theta)
| sin(theta) cos(theta) 0 |
| 0 0 1|
- -
_ _
P =| X |
| Y |
| 1 |
- -

Composition of 2D Transformations

There are many situations in which the final transformation of a point is a combination of several
(often many) individual transformations. For example, the position of the finger of a robot might
be a function of the rotation of the robots hand, arm, and torso, as well as the position of the
robot on the railroad train and the position of the train in the world, and the rotation of the
planet around the sun, etc.
10
CK
SCO 305 Computer Graphics

Applying each transformation individually to all points in a model would take a lot of time. Instead
of applying several transformations matrices to each point we want to combine the
transformations to produce 1 matrix which can be applied to each point.

In the simplest case we want to apply the same type of transformation (translation, rotation,
scaling) more than once.

Translation is additive as expected


scaling is multiplicative as expected
rotation is additive as expected

But what if we want to combine different types of transformations?

A very common reason for doing this is to rotate a polygon about an arbitrary point (e.g. the
center of the polygon) rather than around the origin.

Translate so that P1 is at the origin T(-Dx,-Dy)


Rotate R(theta)
Translate so that the point at the origin is at P1 T(Dx,Dy)

Note: the order of operations here is right to left:

P' = T(Dx,Dy) * R(theta) * T(-Dx,-Dy) * P


i.e.
P' = T(Dx,Dy) * { R(theta) * [ T(-Dx,-Dy) * P ] }
i.e.
P' = [ T(Dx,Dy) * R(theta) * T(-Dx,-Dy) ] * P

The matrix that results from these 3 steps can then be applied to all of the points in the
polygon.

Another common reason for doing this is to scale a polygon about an arbitrary point (e.g. the
center of the polygon) rather than around the origin.

Translate so that P1 is at the origin


Scale
Translate so that the point at the origin is at P1

How do we determine the 'center' of the polygon?

specifically define the center (e.h. the center of mass)


average the location of all the vertices
take the center of the bounding box of the polygon

11
CK
SCO 305 Computer Graphics

Window to Viewport

Generally user's prefer to work in world-coordinates.

1 unit can be 1 micron


1 unit can be 1 meter
1 unit can be 1 kilometer
1 unit can be 1 mile

These coordinates must then be translated to screen coordinates to be displayed in a


rectangular region of the screen called the viewport

The objects are in world coordinates (with n dimensions)


The viewport is in screen coordinates (with n=2)

Want one matrix that can be applied to all points:


rectangular area of world from (Xmin,Ymin) to (Xmax,Ymax) - world-coordinate window
rectangular area of screen from (Umin,Vmin) to (Umax,Vmax) - viewport

Need to rescale the world-coordinate rectangle to the screen rectangle

1. Translate world-coordinate window to the origin of the world coordinate system.


2. Rescale the window to the size and aspect ratio of the viewport.
3. Translate the viewport to its position on the screen in the screen coordinate system.

Pscreen = M * Pworld
M = T(Umin,Vmin) * S(deltaU/deltaX, deltaV/deltaY) * T(-Xmin, -Ymin)

2D Transformations

Transformations are a fundamental part of computer graphics. Transformations are used to


position objects, to shape objects, to change viewing positions, and even to change how
something is viewed (e.g. the type of perspective that is used).

12
CK
SCO 305 Computer Graphics

In 3D graphics, we must use 3D transformations. However, 3D transformations can be quite


confusing so it helps to first start with 2D.

There are 4 main types of transformations that one can perform in 2 dimensions:

i. Translations
ii. Scaling
iii. Rotation
iv. Shearing

These basic transformations can also be combined to obtain more complex transformations. In
order to make the representation of these complex transformations easier to understand and
more efficient, we introduce the idea of homogeneous coordinates.

Representation of Points/Objects

13
CK
SCO 305 Computer Graphics

A point p in 2D is represented as a pair of numbers: p= (x, y) where x is the x-coordinate of the


point p and y is the y-coordinate of p. 2D objects are often represented as a set of points
(vertices), {p1, p2,...,pn}, and an associated set of edges {e1,e2,...,em}.

edge is defined as a pair of points e = {pi,pj}. What are the points and edges of the triangle below?

We can also write points in vector/matrix notation as

Translations

Assume you are given a point at (x,y)=(2,1). Where will the point be if you move it 3 units to the
right and 1 unit up? Ans: (x',y') = (5,2). How was this obtained? - (x',y') = (x+3,y+1). That is, to
move a point by some amount dx to the right and dy up, you must add dx to the x-coordinate and
add dy to the y-coordinate.

What was the required transformation to move the green triangle to the red triangle? Here the
green triangle is represented by 3 points

Triangle = {p1= (1, 0), p2= (2, 0), p3= (1.5, 2)}

14
CK
SCO 305 Computer Graphics

What are the points and edges in this picture of a house? What are the transformation is required
to move this house so that the peak of the roof is at the origin? What is required to move the
house as shown in animation?

Matrix/Vector Representation of Translations

A translation can also be represented by a pair of numbers, t= (tx,ty) where tx is the change in the
x-coordinate and ty is the change in y coordinate. To translate the point p by t, we simply add to
obtain the new (translated) point q = p + t.

q=p+t= + =

Scaling

Suppose we want to double the size of a 2-D object. What do we mean by double? Double in size,
width only, height only, along some line only? When we talk about scaling we usually mean some

15
CK
SCO 305 Computer Graphics

amount of scaling along each dimension. That is, we must specify how much to change the size
along each dimension. Below we see a triangle and a house that have been doubled in both width
and height (note, the area is more than doubled).

The scaling for the x dimension does not have to be the same as the y dimension. If these are
different, then the object is distorted. What is the scaling in each dimension of the pictures
below?

16
CK
SCO 305 Computer Graphics

And if we double the size, where is the resulting object? In the pictures above, the scaled object
is always shifted to the right. This is because it is scaled with respect to the origin. That is, the
point at the origin is left fixed. Thus scaling by more than 1 moves the object away from the origin
and scaling of less than 1 moves the object toward the origin. This can be seen in the animation
below.

17
CK
SCO 305 Computer Graphics

This is because of how basic scaling is done. The above objects have been scaled simply by
multiplying each of its points by the appropriate scaling factor. For example, the point p= (1.5, 2)
has been scaled by 2 along x and .5 along y. Thus, the new point is

q = (2*1.5, .5*2) = (3, 1).

Matrix/Vector Representation of Translations

Scaling transformations are represented by matrices. For example, the above scaling of 2 and .5
is represented as a matrix:

Scale matrix: s = =

New point: q = s*p = =

Scaling about a Particular Point

What do we do if we want to scale the objects about their center as show below?

18
CK
SCO 305 Computer Graphics

The next example demonstrates scaling of an object. Scaling is done with the scale() method. In
this method, we provide two parameters. They are the x scale and y scale factor, by which
coordinates are scaled along the x or y axis respectively.

Scaling.java

package com.zetcode;

import java.awt.Color;
import java.awt.Graphics;
19
CK
SCO 305 Computer Graphics

import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

class Surface extends JPanel {

private void doDrawing(Graphics g) {

Graphics2D g2d = (Graphics2D) g;

g2d.setColor(new Color(150, 150, 150));


g2d.fillRect(20, 20, 80, 50);

AffineTransform tx1 = new AffineTransform();


tx1.translate(110, 22);
tx1.scale(0.5, 0.5);

g2d.setTransform(tx1);
g2d.fillRect(0, 0, 80, 50);

AffineTransform tx2 = new AffineTransform();


tx2.translate(170, 20);
tx2.scale(1.5, 1.5);

g2d.setTransform(tx2);
g2d.fillRect(0, 0, 80, 50);
}

@Override
public void paintComponent(Graphics g) {

super.paintComponent(g);
doDrawing(g);
}
}

public class Scaling extends JFrame {

public Scaling() {

initUI();
20
CK
SCO 305 Computer Graphics

private void initUI() {

setTitle("Scaling");

add(new Surface());

setSize(330, 160);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}

public static void main(String[] args) {

SwingUtilities.invokeLater(new Runnable() {

@Override
public void run() {

Scaling sc = new Scaling();


sc.setVisible(true);
}
});
}
}

We have a rectangle. First we scale it down and then we scale it up a bit.

AffineTransform tx2 = new AffineTransform();


tx2.translate(170, 20);
tx2.scale(1.5, 1.5);

Another scaling would be added to the first one. So we need to create and apply a new affine
transform.

21
CK
SCO 305 Computer Graphics

Figure: Scaling

Rotation

Below, we see objects that have been rotated by 25 degrees.

22
CK
SCO 305 Computer Graphics

Again, we see that basic rotations are with respect to the origin:

Matrix/Vector Representation of Translations

23
CK
SCO 305 Computer Graphics

Counterclockwise rotation of a degrees =

Shear

Matrix/Vector Representation of Translations

Shear along x axis =

Shear along y axis =

In the following example we perform shearing. We use the share() method.

Scale.java

package com.zetcode;

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;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

class Surface extends JPanel {

24
CK
SCO 305 Computer Graphics

private void doDrawing(Graphics g) {

Graphics2D g2d = (Graphics2D) g;

AffineTransform tx1 = new AffineTransform();


tx1.translate(50, 90);

g2d.setTransform(tx1);
g2d.setColor(Color.green);
g2d.drawRect(0, 0, 160, 50);

AffineTransform tx2 = new AffineTransform();


tx2.translate(50, 90);
tx2.shear(0, 1);

g2d.setTransform(tx2);
g2d.setColor(Color.blue);

g2d.draw(new Rectangle(0, 0, 80, 50));

AffineTransform tx3 = new AffineTransform();


tx3.translate(130, 10);
tx3.shear(0, 1);

g2d.setTransform(tx3);
g2d.setColor(Color.red);
g2d.drawRect(0, 0, 80, 50);
}

@Override
public void paintComponent(Graphics g) {

super.paintComponent(g);
doDrawing(g);
}
}

public class Shearing extends JFrame {

public Shearing() {

initUI();
25
CK
SCO 305 Computer Graphics

private void initUI() {

setTitle("Shearing");

add(new Surface());

setSize(330, 270);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}

public static void main(String[] args) {

SwingUtilities.invokeLater(new Runnable() {

@Override
public void run() {

Shearing sh = new Shearing();


sh.setVisible(true);
}
});
}
}

In this example, we draw three rectangles in three different colors. They form a structure. Two
of them are sheared.

tx2.shear(0, 1);

The two parameters are multipliers by which coordinates are shifted in the direction of the x
and y axis.

26
CK
SCO 305 Computer Graphics

Figure: Shearing

Combining Transformations

We saw that the basic scaling and rotating transformations are always with respect to the origin.
To scale or rotate about a particular point (the fixed point) we must first translate the object so
that the fixed point is at the origin. We then perform the scaling or rotation and then the inverse
of the original translation to move the fixed point back to its original position. For example, if we
want to scale the triangle by 2 in each direction about the point fp = (1.5, 1), we first translate all
the points of the triangle by T = (-1.5,-1), scale by 2 (S), and then translate back by -T= (1.5, 1).
Mathematically this looks like

q= = ( + )+

Order Matters!

Notice the order in which these transformations are performed. The first (rightmost)
transformation is T and the last (leftmost) is -T. If you apply these transformations in a different
order then you will get very different results. For example, what happens when you first apply T
followed by -T followed by S? Here T and -T cancel each other out and you are simply left with S

.Sometimes (but be careful) order does not matter, For example, if you apply multiple 2D
rotations, order makes no difference:

R1 R2 = R2 R1

27
CK
SCO 305 Computer Graphics

But this will not necessarily be true in 3D!!

Homogeneous Coordinates

In general, when you want to perform a complex transformation, you usually make it by
combining a number of basic transformations. The above equation for q, however, is awkward
to read because scaling is done by matrix multiplication and translation is done by vector
addition. In order to represent all transformations in the same form, computer scientists have
devised what are called homogeneous coordinates. Do not try to apply any exotic interpretation
to them. They are simply a mathematical trick to make the representation be more consistent
and easier to use.

Homogeneous coordinates (HC) add an extra virtual dimension. Thus 2D HC are actually 3D and
3D HC are 4D. Consider a 2D point p = (x,y). In HC, we represent p as p = (x, y, 1). An extra
coordinate is added whose value is always 1. This may seem odd but it allows us to now represent
translations as matrix multiplication instead of as vector addition. A translation (dx, dy) which
would normally be performed as q = (x,y) + (dx, dy) now is written as

q=Tp= =

Now, we can write the scaling about a fixed point as simply a matrix multiplication:

q = (-T) S T p = A p,

Where A = (-T) S T

The matrix A can be calculated once and then applied to all the points in the object. This is much
more efficient than our previous representation. It is also easier to identify the transformations
and their order when everything is in the form of matrix multiplication.

The matrix for scaling in HC is

S=

and the matrix for rotation is

28
CK
SCO 305 Computer Graphics

R=

Transformations coding

This part of the Java 2D programming tutorial, talks about transformations.

An affine transform is composed of zero or more linear transformations (rotation, scaling or


shear) and translation (shift). Several linear transformations can be combined into a single matrix.
A rotation is a transformation that moves a rigid body around a fixed point. A scaling is a
transformation that enlarges or diminishes objects. The scale factor is the same in all directions.
A translation is a transformation that moves every point a constant distance in a specified
direction. A shear is a transformation that moves an object perpendicular to a given axis, with
greater value on one side of the axis than the other.

The AffineTransform is the class in Java 2D to perform affine transformations.

In the following example we create an complex shape by rotating an ellipse.

Donut.java

package com.zetcode;

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.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import javax.swing.JFrame;
29
CK
SCO 305 Computer Graphics

import javax.swing.JPanel;
import javax.swing.SwingUtilities;

class Surface extends JPanel {

private void doDrawing(Graphics g) {

Graphics2D g2 = (Graphics2D) g;

RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING,


RenderingHints.VALUE_ANTIALIAS_ON);

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

g2.setRenderingHints(rh);

Dimension size = getSize();


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

Ellipse2D e = new Ellipse2D.Double(0, 0, 80, 130);


g2.setStroke(new BasicStroke(1));
g2.setColor(Color.gray);

for (double deg = 0; deg < 360; deg += 5) {


AffineTransform at =
AffineTransform.getTranslateInstance(w / 2, h / 2);
at.rotate(Math.toRadians(deg));
g2.draw(at.createTransformedShape(e));
}
}

@Override
public void paintComponent(Graphics g) {

super.paintComponent(g);
doDrawing(g);
}
}

public class Donut extends JFrame {


30
CK
SCO 305 Computer Graphics

public Donut() {

initUI();
}

private void initUI() {

setTitle("Donut");

add(new Surface());

setSize(370, 320);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}

public static void main(String[] args) {

SwingUtilities.invokeLater(new Runnable() {

@Override
public void run() {

Donut dn = new Donut();


dn.setVisible(true);
}
});
}
}

In this example, we create a donut shape.

Ellipse2D e = new Ellipse2D.Double(0, 0, 80, 130);


g2.setStroke(new BasicStroke(1));
g2.setColor(Color.gray);

In the beginning there was an ellipse.

for (double deg = 0; deg < 360; deg += 5) {


AffineTransform at =
AffineTransform.getTranslateInstance(w / 2, h / 2);
31
CK
SCO 305 Computer Graphics

at.rotate(Math.toRadians(deg));
g2.draw(at.createTransformedShape(e));
}

After several rotations, there is a donut.

In this part of the Java 2D tutorial, we have talked about transformations.

32
CK

You might also like