java two dimensional graphics with affine transforms sasank upadrasta

57
Java Two Dimensional Graphics with Affine Transforms Sasank Upadrasta

Upload: alden-crumble

Post on 14-Dec-2015

225 views

Category:

Documents


1 download

TRANSCRIPT

Java Two Dimensional Graphics with Affine Transforms

Sasank Upadrasta

Contents

• Introduction to 2D using Java• Drawing Geometric Primitives• What are Affine Transforms• Java Frame Works – affine• References

Introduction to 2D using Java

• Java2D API includes these packages java.awt

java.awt.image java.awt.color java.awt.font java.awt.geom java.awt.print java.awt.renderable

Shapes and Areas

• Shapes - create standard shape objects and draw them in one method call instead of drawing each segment with multiple method calls. The shapes include rectangles and ellipses and also arbitrary shapes such as the Polygon class. The shape classes implement the Shape interface and provide a PathIterator that steps through the segments of the given shape.

• Areas - combine shapes in different ways to create new areas.

• Stroke - vary the thickness of a line, produce arbitrary dot-dash sequences, select how corners and line ends are shaped, etc.

• Paint - fill the interiors of shapes, as well as outlines, not just with solid colors but with – gradients of one color to another, and – textured patterns of tiled images.

Strokes and Paint

Affine Transformations

• Transformations - affine transformations (i.e. those geometrical transformations that keep parallel lines parallel) can take a shape and translate it, rotate it, shear it, compress or expand it. Multiple transformations can be compounded together.

Compositing and Clipping

• Compositing - overlay shapes and images according to several optional rules that take advantage of the alpha transparency.

• Clipping - to speed up performance, only redraw the portion of the display that lies within a given outline or clip. With Java2d one can use arbitrary clip outlines rather than just rectangles.

Text, Color and Images

• Text - vast array of text rendering capabilities that range from the basic drawString() method to creating your own editor from scratch.

• Color - lots of tools to help render colors in a consistent manner regardless of the device on which they are displayed.

• Images - use many of the above tools and techniques that are used with shapes - e.g. transformations, compositing, clipping etc. - on images.

Image Filters and Printing

• Image processing - apply image filters - edge enhancement, blurring, inversion, etc. are available.

• Printing - print the graphics display to the local printer as shown on the monitor.

Draw, then Display

• The typical Java 2D process begins with method invocations to draw shapes and strokes on what can be thought of as an off-screen image surface with arbitrarily fine resolution. A rasterizer converts this off-screen image to a 2D array of pixel or point values, which can be rendered on a monitor screen or a printer.

The Graphics class

• The vast majority of uses for the Java 2D API utilize a small subset of its capabilities encapsulated in the java.awt.Graphics class. Most methods of the Graphics class can be divided into two basic groups:

1. Draw and fill methods, enabling you to render basic shapes, text, and images

2. Attributes setting methods, which affect

how that drawing and filling appears • Methods such as setFont and setColor

define how draw and fill methods render.

Drawing method examples• drawString – For drawing text

g.drawString("Hello", 10, 10); • drawImage – For drawing images

g.drawImage(img, 0, 0, width, height, 0, 0, imageWidth, imageHeight, null);

• drawLine, drawArc, drawRect, drawOval, drawPolygon – For drawing geometric shapes g2.draw(new Line2D.Double(0, 0, 30, 40));

Image scaling

• You can choose one of several methods in the Graphics class based on whether you want to render the image at the specified location in its original size or scale it to fit inside the given rectangle

Transparency and Fill

• You can fill the transparent areas of the image with color or keep them transparent

• Fill methods apply to geometric shapes and include fillArc, fillRect, fillOval, fillPolygon.

2D Coordinates

• Whether you draw a line of text or an image, remember that in 2D graphics every point is determined by its x and y coordinates. All of

the draw and fill methods need this information

which determines where the text or image should be rendered.

Using x,y Coordinates

• For example, to draw a line, an application calls the following: java.awt.Graphics.drawLine(int x1, int y1, int x2, int y2)

In this code (x1, y1) is the start point of the line, and (x2, y2) is the end point of the line.

• So the code to draw a horizontal line is as follows: Graphics.drawLine(20, 100, 120, 100);

Weather Painter class• This code draws an image determined by using the

setupWeatherReport() method. ... origComposite = g2.getComposite(); if (alpha0 != null) g2.setComposite(alpha0); g2.drawImage(img0, 0, 0, size.width, size.height,

0, 0, img0.getWidth(null), img0.getHeight(null), null); if (img1 != null) {

if (alpha1 != null) g2.setComposite(alpha1); g2.drawImage(img1,0, 0, size.width, size.height,

0, 0, img1.getWidth(null), img1.getHeight(null), null);

} ...

Weather example (continued)

• The setFont and drawString methods render the temperature and the weather condition.

... // Freezing, Cold, Cool, Warm, Hot, // Blue, Green, Yellow, Orange, Red Font font = new Font("Serif", Font.PLAIN, 36); g.setFont(font); String tempString = feels + " " + temperature+"F"; FontRenderContext frc = ((Graphics2D)g).getFontRenderContext();...

Weather example (continued)

• The setFont and drawString methods render the temperature and the weather condition.

... g.setColor(textColor); int xTextTemp = rX-(int)boundsTemp.getX(); int yTextTemp = rY-(int)boundsTemp.getY(); g.drawString(tempString, xTextTemp, yTextTemp); int xTextCond = rX-(int)boundsCond.getX(); int yTextCond = rY-(int)boundsCond.getY() + (int)boundsTemp.getHeight(); g.drawString(condStr, xTextCond, yTextCond);

Introduction to 2D using Java (contd …)

• The fillRect method allows you to draw a rectangle filled with the specified color. ...

Rectangle2D boundsTemp = font.getStringBounds(tempString, frc); Rectangle2D boundsCond = font.getStringBounds(condStr, frc); int wText = Math.max((int)boundsTemp.getWidth(), (int)boundsCond.getWidth()); int hText = (int)boundsTemp.getHeight() + (int)boundsCond.getHeight(); int rX = (size.width-wText)/2; int rY = (size.height-hText)/2; g.setColor(Color.LIGHT_GRAY); g2.fillRect(rX, rY, wText, hText); ...

Geometric Primitives

• The Java 2D™ API provides several classes that define common geometric objects such as points, lines, curves, and rectangles. These geometry classes are part of the java.awt.geom package.

• The PathIterator interface defines methods for retrieving elements from a path.

Shape Interface

• The Shape interface provides a set of methods for describing and inspecting geometric path objects. This interface is implemented by the

GeneralPath class and other geometry classes.

Geometric Primitives

• All examples represented in this section create geometries by using java.awt.geom and then render them by using the Graphics2D class. To begin you obtain a Graphics2D object, for example by casting the Graphics parameter of the paint() method. public void paint (Graphics g) {

Graphics2D g2 = (Graphics2D) g; ...

}

Point

• The Point class creates a point representing a location in (x,y) coordinate space. The subclasses Point2D.Float and Point2D.Double provide correspondingly float and double precision for storing the coordinates of the point. //Create Point2D.Double

Point2D.Double point = new Point2D.Double(x, y);

Point Locations

• To create a point with the coordinates 0,0 you use the defaultconstructor, Point2D.Double() .You can use the setLocation method to set the position of the point as follows: setLocation(double x, double y) – To set the location of the point- defining coordinates as double values

Set Location

• setLocation(Point2D p) – To set the location of the point using the coordinates of another point. Also, the Point2D class has methods to calculate the distance between the current point and a point with given coordinates, or the distance between two points.

Line

• The Line2D class represents a line segment in (x, y) coordinate space. The Line2D.Float and Line2D.Double subclasses specify lines in float and double precision. For example: // draw Line2D.Double

g2.draw(new Line2D.Double(x1, y1, x2, y2));

Set Line methods

• This class includes several setLine() methods to define the endpoints of the line.Alternatively, the endpoints of the line could be specified by using the constructor for the Line2D.Float class as follows: – Line2D.Float(float X1, float Y1, float X2, float Y2)

– Line2D.Float(Point2D p1, Point2D p2)

• Use the Stroke object in the Graphics2D class to define the stroke for the line path.

Ellipse

• The Ellipse2d class represents an ellipse defined by a bounding rectangle. The Ellipse2D.Float and Ellipse2D.Double subclasses specify an ellipse in float and double precision. Ellipse is fully defined by a location, a width and a height. For example: // draw Ellipse2D.Double

g2.draw(new Ellipse2D.Double(x, y, rectwidth, rectheight));

Rectangle

• Classes that specify primitives represented in the following example extend the RectangularShape class, which implements the Shape interface and adds a few methods of its own. These methods enables you to get information about a shape’s location and size, to examine the center point of a rectangle, and to set the bounds of the shape.

Rectangle

• The Rectangle2D class represents a rectangle defined by a location (x, y) and dimension (w x h). The Rectangle2D.Float and Rectangle2D.Double subclasses specify a rectangle in float and double precision. For example: // draw Rectangle2D.Double g2.draw(new Rectangle2D.Double(x, y, rectwidth, rectheight));

Rounded Rectangle

• The RoundRectangle2D class represents a rectangle with rounded corners defined by a location (x, y), a dimension (w x h), and the width and height of the corner arc. The RoundRectangle2D.Float and RoundRectangle2D.Double subclasses specify a round rectangle in float and double precision.

Specifying Rounded Rectangle

• The rounded rectangle is specified with following parameters: – Location – Width – Height – Width of the corner arc – Height of the corner acr

Rounded Rectangle location

• To set the location, size, and arcs of a RoundRectangle2D object, use the method setRoundRect(double a, double y, double w, double h, double arcWidth, double arcHeight). For example: // draw RoundRectangle2D.Double

g2.draw(new RoundRectangle2D.Double(x, y, rectwidth, rectheight, 10, 10));

Drawing Geometric Primitives (Contd …)

• The example at http://java.sun.com/docs/books/tutorial/2d/geometry/examples/ShapesDemo2D.java code contains implementations off all the described geometric primitives.

• For more information about classes and methods represented in this section see the http://java.sun.com/javase/6/docs/api/java/awt/geom/package-summary.html specification.

What is an Affine Transform?

• The Affine Transform 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.

What is affine Transform (contd…)

• An Affine Transform is a linear transform, so the transformation can be expressed in the matrix notation of linear algebra.  An arbitrary Affine Transform can be mathematically expressed by six numbers in a matrix like this:

  sx shx txshy  sy ty

• The symbols or factors sx and sy are scale factors that accomplish scaling.  The factors tx and ty are scale factors that accomplish translation.  The factors shx and shy are scale factors that accomplish shear. 

What is affine Transform (contd…)

• Your graphics can be transformed in the following ways before being displayed on the output device:

Scaling Translation Shear Rotation

(rotation is a combination of scaling and shearing, so there are not separate rx and ry numbers. )

Scaling

• Scaling is perhaps the easiest of the four types of transforms to understand.  This simply means that if a point is located at a horizontal coordinate value of x in user space, it will be located at sx*x in device space, where sx is a numeric multiplier that can be either positive or negative.

Translation

Translation moves the origin of the coordinate system in device space. 

Another use of translation (in combination with scaling) is to flip the default positive direction of the vertical axis so that increasing positive values go up instead of down, which is the default. 

Shear

• Jonathan Knudsen describes shear in his book entitled Java 2D Graphics as:  “Take a stack of paper (like you might place in your laser printer) and draw a picture on the side of the stack.  Then deform the stack so that the side of the stack on which you drew the picture takes the form of a parallelogram.  Be especially careful to keep the opposite sides parallel.  Then look at your picture.  It will have been subjected to shear in one dimension.”

Affine Transform class

• public class AffineTransform extends Object implements Cloneable, Serializable

• 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.

Affine Transforms as matrix multiplications

• 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 (x, y) into destination coordinates (x', y') by considering them 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 ]

Rotation

• Rotation is easy to visualize (but the combination of rotation and shear can be very difficult to visualize).  To visualize rotation, draw a picture on a piece of paper.  Use a single tack to attach it to a bulletin board.  Then rotate the paper a few degrees around the tack.  You will have rotated the picture around the coordinates of the tack by the specified number of degrees.

Rotation in Java 2D

• Java 2D works the same way.  In the process of transforming a graphic from user space to device space, you can cause it to be rotated by a specified angle around a specified coordinate position.

• However, in Java 2D, the angle must be specified in radians instead of degrees.  If you are unfamiliar with the use of radian measure to specify an angle, just remember the following identity:

Radiand and Degrees

• PI radians = 180 degrees• PI is the numeric value you learned about in

geometry class.  • PI has a value of 3.14159...........  However, you

don’t have to remember the value of PI.  It is available as a static final constant in the Math class.  You can access the value as Math.PI.

Dividing PI Radians

• If this sounds confusing, you might also want to remember the following identities: 

• PI/2 = 90 degreesPI/4 = 45 degreesPI/8 = 22.5 degreesPI/16 = 11.25 degrees, etc.

Rotation direction

• Positive angles of rotation proceed in a clockwise direction.  This may be backwards from what you are accustomed to in various science and engineering endeavors where counter-clockwise rotation is often thought of as the positive direction of rotation.

Java Frame Works - affine

• Java's Abstract Window Toolkit (AWT) provides a Graphics class with methods for drawing lines, ovals, rectangles, text, polygons, and other shapes. A Panel, Frame, or other AWT component draws itself using the Graphics instance passed to its paint method. The GUI environment automatically calls this method whenever the component needs redrawing.

Java Frame Works – affine

• Sun added the Java 2D framework on top of the original AWT Graphics class, adding many new features to the Java core API. One important Java2D feature is known as the affine transformation. It works by transforming the coordinate system before any drawing is done on the Graphics object.

JFrame example

• To illustrate this, we'll skew the coordinates with a shearing transformation and draw some text and graphics to see how it looks with and without the transformation. First, let's draw some text, using the default coordinates, We'll do this in the paint method of a JFrame:

Example (page 1)import java.awt.Font;import java.awt.Graphics;import java.awt.Graphics2D;import javax.swing.JFrame;public class MyTransform extends JFrame {

public MyTransform(String title) { super(title);} public void paint(Graphics g) { Graphics2D g2d = (Graphics2D) g; g2d.setFont(Font.decode("arial-bold-36")); g2d.drawString("Affinity", 100, 100);

g2d.drawOval(100, 150, 35, 50); g2d.drawOval(135, 150, 35, 50);

}

Example (page 2)

public static void main(String[] args) { MyTransform aft = new MyTransform("Affinity"); aft.setSize(300,300);

aft.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); aft.setVisible(true);

}}

Java affine Frameworks

• In all affine transformations , the change affects the entire coordinate system and not just individual objects. We call the methods to apply the transforms before calling the drawing methods. Let's display the above text with a shearing transform, This is a transform where lines are shifted in a new direction but parallel lines still remain parallel. The call to the shear method happens before the drawing occurs. Here is code to perform the transform:

Modifications to Example

public void paint(Graphics g) { Graphics2D g2d = (Graphics2D) g;

g2d.shear(0.5,0.5); g2d.setFont(Font.decode("arial-bold-36"));

g2d.drawString("Affinity", 100, 100); g2d.drawOval(100, 150, 35, 50);

g2d.drawOval(135, 150, 35, 50);}

References

http://java.sun.com/http://www.developer.com/http://www.particle.kth.se/htmlnew/