The book covers elementary concepts, from how to produce simple graphical objects using logical coordinates to producing filled regions. The book reinforces concepts with useful and simple examples, then progresses to applied geometry (vectors, polygons) and then onto how to perform rotations and other transformations of graphical objects.
In a logical progression of ideas, the reader is introduced to some of the classic graphics algorithms and finally to chapters which cover particular effects such as perspective drawings and hidden-face and hidden-line elimination.
The book also provides a host of ready-to-run programs and worked examples to illuminate general principles and geometric techniques for the creation of both 2D and 3D graphical objects.
"synopsis" may belong to another edition of this title.
Leen Ammeraal is a retired lecturer of Hogeschool Utrecht, The Netherlands, where he was employed from 1977 to 1998. He has a degree (ir.) in mathematics at University of Technology Delft, The Netherlands. He worked as a programmer and mathematician at Akzo Research and Engineering, Arnhem, The Netherlands, from 1961 to 1972 and did research work on compilers from 1972 to 1977 at Mathematical Centre, Amsterdam. He wrote many books for Wiley (as well as for the Dutch publisher Academic Service). Some of his Wiley books have been translated into other languages (Japanese, Russian, Italian, French, German, Greek, Danish, Portuguese, Bulgarian).
Kang Zhang is a Professor in Computer Science and Director of Visual Computing Lab at the University of Texas at Dallas. He received his B.Eng. in Computer Engineering from the University of Electronic Science and Technology, China, in 1982; and Ph.D. from the University of Brighton, UK, in 1990. He held academic positions in the UK and Australia, prior to joining UTD. Zhang's current research interests are in the areas of visual languages, graphical visualization, and Web engineering; and has published over 130 papers in these areas. He has taught computer graphics and related subjects at both graduate and undergraduate levels for many years. Zhang was also an editor of two books on software visualization.
A great many varied and interesting visual effects can be achieved with computer graphics, for which a fundamental understanding of the underlying mathematical concepts – and a knowledge of how they can be implemented in a particular programming language – is essential.
Computer Graphics for Java Programmers, 2nd edition covers elementary concepts in creating and manipulating 2D and 3D graphical objects, covering topics from classic graphics algorithms to perspective drawings and hidden-line elimination.
Completely revised and updated throughout, the second edition of this highly popular textbook contains a host of ready-to-run-programs and worked examples, illuminating general principles and geometric techniques. Ideal for classroom use or self-study, it provides a perfect foundation for programming computer graphics using Java.
A great many varied and interesting visual effects can be achieved with computer graphics, for which a fundamental understanding of the underlying mathematical concepts – and a knowledge of how they can be implemented in a particular programming language – is essential.
Computer Graphics for Java Programmers, 2nd edition covers elementary concepts in creating and manipulating 2D and 3D graphical objects, covering topics from classic graphics algorithms to perspective drawings and hidden-line elimination.
Completely revised and updated throughout, the second edition of this highly popular textbook contains a host of ready-to-run-programs and worked examples, illuminating general principles and geometric techniques. Ideal for classroom use or self-study, it provides a perfect foundation for programming computer graphics using Java.
This book is primarily about graphics programming and mathematics. Rather than discussing general graphics subjects for end users or how to use graphics software, we will deal with more fundamental subjects, required for graphics programming. In this chapter, we will first understand and appreciate the nature of discreteness of displayed graphics on computer screens. We will then see that x- and y-coordinates need not necessarily be pixel numbers, also known as device coordinates. In many applications logical coordinates are more convenient, provided we can convert them to device coordinates. Especially with input from a mouse, we also need the inverse conversion, as we will see at the end of this chapter.
1.1 LINES, COORDINATES AND PIXELS
The most convenient way of specifying a line segment on a computer screen is by providing the coordinates of its two endpoints. In mathematics, coordinates are real numbers, but primitive line-drawing routines may require these to be integers. This is the case, for example, in the Java language, which we will use in this book. The Java Abstract Windows Toolkit (AWT) provides the class Graphics containing the method drawLine, which we use as follows to draw the line segment connecting A and B:
g.drawLine(xA, yA, xB, yB);
The graphics context g in front of the method is normally supplied as a parameter of the paint method we are using, and the four arguments of drawLine are integers, ranging from zero to some maximum value. The above call to drawLine produces exactly the same line as this one:
g.drawLine(xB, yB, xA, yA);
We will now use statements such as the above one in a complete Java program. Fortunately, you need not type these programs yourself, since they are available from the Internet, as specified in the Preface. It will also be necessary to install the Java Development Kit (JDK), which you can also download, using the following Web page:
http://java.sun.com/
If you are not yet familiar with Java, you should consult other books, such as some mentioned in the Bibliography, besides this one.
The following program draws the largest possible rectangle in a canvas. The color red is used to distinguish this rectangle from the frame border:
// RedRect.java: The largest possible rectangle in red. import java.awt.*; import java.awt.event.*;
public class RedRect extends Frame { public static void main(String args){new RedRect();}
RedRect() { super("RedRect"); addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e){System.exit(0);}}); setSize (200, 100); add("Center", new CvRedRect()); show(); } }
class CvRedRect extends Canvas { public void paint(Graphics g) { Dimension d = getSize(); int maxX = d.width - 1, maxY = d.height - 1; g.drawString("d.width = " + d.width, 10, 30); g.drawString("d.height = " + d.height, 10, 60); g.setColor(Color.red); g.drawRect(0, 0, maxX, maxY); } }
The call to drawRect almost at the end of this program has the same effect as these four lines:
g.drawLine(0, 0, maxX, 0); // Top edge g.drawLine(maxX, 0, maxX, maxY); // Right edge g.drawLine(maxX, maxY, 0, maxY); // Bottom edge g.drawLine(0, maxY, 0, 0); // Left edge
The program contains two classes:
RedRect: The class for the frame, also used to close the application.
CvRedRect: The class for the canvas, in which we display graphics output.
However, after compiling the program by entering the command
javac RedRect.java
we notice that three class files have been generated: RedRect.class, CvRedRect.class and RedRect$1. class. The third one is referred to as an anonymous class since it has no name in the program. It is produced by the two program lines
addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e){System.exit(0);}});
which enable the user of the program to terminate it in the normal way. We could have written the same program code as
addWindowListener ( new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } } );
to show more clearly the structure of this fragment. The argument of the method addWindowListener must be an object of a class that implements the interface WindowListener. This implies that this class must define seven methods, one of which is windowClosing. The base class WindowAdapter defines these seven methods as do-nothing functions. In the above fragment, the argument of addWindowListener denotes an object of an anonymous subclass of WindowAdapter. In this subclass we override the method windowClosing. A further discussion of this compact program code for event handling can be found in Appendix B.
The RedRect constructor shows that the frame size is set to 200 100. If we do not modify this size (by dragging a corner or an edge of the window), the canvas size is somewhat less. After compilation, we run the program by typing the command
java RedRect
which produces the output shown in Figure 1.1.
The blank area in a frame, which we use for graphics output, is referred to as a client rectangle in Microsoft Windows programming. We will consistently use a canvas for it, which is a subclass, such as CvRedRect in program RedRect.java, of the AWT class Canvas. If, instead, we displayed the output directly in the frame, we would have a problem with the coordinate system: its origin would be in the top-left corner of the frame; in other words, the x-coordinates increase from left to right and y-coordinates from top to bottom. Although there is a method getInsets to obtain the widths of all four borders of a frame so that we could compute the dimensions of the client rectangle ourselves, we prefer to use a canvas.
The tiny screen elements that we can assign a color are called pixels (short for picture elements), and the integer x- and y-values used for them are referred to as device coordinates. Although there are 200 pixels on a horizontal line in the entire frame, only 192 of these lie on the canvas, the remaining 8 being used for the left and right borders. On a vertical line, there are 100 pixels for the whole frame, but only 73 for the canvas. Apparently, the remaining 27 pixels are used for the title bar and for the top and bottom borders. Since these numbers may differ in different Java implementations and the user can change the window size, it is desirable that our program can determine the canvas dimensions. We do this by using the getSize method of the class Component, which is a superclass of Canvas. The following program lines in the paint method show how we obtain the canvas dimensions and how we interpret them:
Dimension d = getSize(); int maxX = d.width - 1, maxY = d.height - 1;
The getSize method of Component (a superclass of Canvas) supplies us with the numbers of pixels on horizontal and vertical lines of the canvas. Since we begin counting at zero, the highest pixel numbers, maxX and maxY, on these lines are one less than these numbers of pixels. Remember that this is similar with arrays in Java and C. For example, if we write
int a = new int[8];
the highest possible index value is 7, not 8. Figure 1.2 illustrates this for a very small canvas, which is only 8 pixels wide and 4 high, showing a much-enlarged screen grid structure. It also shows that the line connecting the points (0, 0) and (7, 3) is approximated by a set of eight pixels.
The big dots approximating the line denote pixels that are set to the foreground color. By default, this foreground color is black, while the background color is white. These eight pixels are made black as a result of this call:
g.drawLine (0, 0, 7, 3);
In the program RedRect.java, we used the following call to the drawRect method (instead of four calls to drawLine):
g.drawRect(0, 0, maxX, maxY);
In general, the call
g.drawRect(x, y, w, h);
draws a rectangle with (x, y) as its top-left and (x + w, y + h) as its bottom-right corners. In other words, the third and fourth arguments of the drawRect method specify the width and height, rather than the bottom-right corner, of the rectangle to be drawn. Note that this rectangle is w + 1 pixels wide and h + 1 pixels high. The smallest possible square, consisting of 2 2 pixels, is drawn by this call
g.drawRect(x, y, 1, 1);
To put only one pixel on the screen, we cannot use drawRect, because nothing at all appears if we try to set the third and fourth arguments of this method to zero. Curiously enough, Java does not provide a special method for this purpose, so we have to use this call:
g.drawLine(x, y, x, y);
Note that the call
g.drawLine(xA, y, xB, y);
draws a horizontal line consisting of | xB - xA | +1 pixels.
1.2 THE BOUNDARIES OF FILLED REGIONS
In mathematics, lines are continuous and have no thickness, but they are discrete and at least one pixel thick in our graphics output. This difference in the interpretation of the notion of lines may not cause any problems if the pixels are very small in comparison with what we are drawing. However, we should be aware that there may be such problems in special cases, as Figure 1.3(a) illustrates. Suppose that we have to draw a filled square ABCD of, say, 44 pixels, consisting of the bottom-right triangle ABC and the upper-left triangle ACD, which we want to paint in dark gray and light gray, respectively, without drawing any lines. Strangely enough, it is not clear how this can be done: if we make the diagonal AC light gray, triangle ABC contains fewer pixels than triangle ACD; if we make it dark gray, it is the other way round.
A much easier but still non-trivial problem, illustrated by Figure 1.3(b), is filling the squares of a checker-board with, say, dark and light gray squares instead of black and white ones. Unlike squares in mathematics, those on the computer screen deserve special attention with regard to the edges belonging or not belonging to the filled regions. We have seen that the call
g.drawRect(x, y, w, h);
draws a rectangle with corners (x, y) and (x + w, y + h). The method fillRect, on the other hand, fills a slightly smaller rectangle. The call
g.fillRect(x, y, w, h);
assigns the current foreground color to a rectangle consisting of w h pixels. This rectangle has (x, y) as its top-left and (x + w - 1, y + h - 1) as its bottom-right corner. To obtain a generalization of Figure 1.3(b), the following method, checker, draws an n n checker board, with (x, y) as its top-left corner and with dark gray and light gray squares, each consisting of w w pixels. The bottom-left square will always be dark gray because for this square we have i = 0 and j = n - 1, so that i + n - j = 1:
void checker(Graphics g, int x, int y, int n, int w) { for (int i=0; i
If we wanted to draw only the edges of each square, also in dark gray and light gray, we would have to replace the above call to fillRect with
g.drawRect(x + i * w, y + j * w, w - 1, w - 1);
in which the last two arguments are w - 1 instead of w.
1.3 LOGICAL COORDINATES
1.3.1 The Direction of the Y-axis
As Figure 1.2 shows, the origin of the device-coordinate systems lies at the top-left corner of the canvas, so that the positive y-axis points downward. This is reasonable for text output, where we start at the top and increase y as we go to the next line of text. However, this direction of the y-axis is different from normal mathematical practice and therefore often inconvenient in graphics applications. For example, in a discussion about a line with a positive slope, we expect to go upward when we move along this line from left to right. Fortunately, we can arrange for the positive y direction to be reversed by performing this simple transformation:
y' = maxY - y
1.3.2 Continuous vs. Discrete Coordinates
Instead of the discrete (integer) coordinates we are using at the lower, device-oriented level, we want to use continuous (floating-point) coordinates at the higher, problem-oriented level. Other usual terms are device and logical coordinates, respectively. Writing conversion routines to compute device coordinates from the corresponding logical ones and vice versa is a bit tricky. We must be aware that there are two solutions to this problem, even in the simple case in which increasing a logical coordinate by one results in increasing the device coordinate also by one. We want to write the following methods:
iX(x), iY(y): the device coordinates of the point with logical coordinates x and y;
fx(x), fy(y): the logical coordinates of the point with device coordinates x and y.
With regard to x-coordinates, the first solution is based on rounding:
int iX(float x){return Math.round(x);} float fx(int x){return (float)x;}
For example, with this solution we have
iX(2.8) = 3 and fx(3) = 3.0
The second solution is based on truncating:
int iX(float x){return (int)x;} // Not used in float fx(int x){return (float)x + 0.5F;} // this book.
With these conversion functions, we would have
iX(2.8) = 2 and fx(2) = 2.5
With both solutions, the difference between any value x and fx(iX(x)) is not greater than 0.5. We will use the first solution throughout this book, since it is the better one if logical coordinates frequently happen to be integer values. In these cases the practice of truncating floating-point numbers will often lead to worse results than we would have with rounding.
Besides the above methods iX and fx (based on the first solution) for x-coordinates, we need similar methods for y-coordinates, taking into account the opposite directions of the two y-axes. At the bottom of the canvas the device y-coordinate is maxY while the logical y-coordinate is 0, which may explain the two expressions of the form maxY - ... in the following methods:
int iX(float x){return Math.round(x);} int iY(float y){return maxY - Math.round(y);} float fx(int x){return (float)x;} float fy(int y){return (float)(maxY - y);}
The pixels are denoted as black dots, each placed in the center of a square of dashed lines. In this discussion and elsewhere in this book, let us write x and y for logical and X and Y for device coordinates. (Since it is customary in Java to use lower-case letters at the beginning of variable names, we will not write X and Y in program text.) In Figure 1.4, the device-coordinates (X, Y) are placed between parentheses near each dot. For example, the pixel with device coordinates (8, 2), at the upper-right corner of this canvas fragment, has logical coordinates (8.0, 14.0). We have
iX (8.0) = Math.round (8.0) = 8 iY (14.0) = 16 - Math.round (14.0) = 2 fx (8) = (float)8 = 8.0 fy (2) = (float) (16 - 2) = 14.0
The dashed square around this dot denotes all points (x, y) satisfying
7.5 [less than or equal to] x < 8.5
13.5 [less than or equal to] y < 14.5
All these points are converted to the pixel (8, 2) by our methods iX and iY.
Let us demonstrate this way of converting floating-point logical coordinates to integer device coordinates in a program that begins by drawing an equilateral triangle ABC, with the side AB at the bottom and the point C at the top. Then, using
q = 0.05 p = 1 - q = 0.95
(Continues...)
Excerpted from Computer Graphics for Java Programmersby Leen Ammeraal Kang Zhang Copyright © 2007 by John Wiley & Sons, Ltd. Excerpted by permission.
All rights reserved. No part of this excerpt may be reproduced or reprinted without permission in writing from the publisher.
Excerpts are provided by Dial-A-Book Inc. solely for the personal use of visitors to this web site.
"About this title" may belong to another edition of this title.
FREE shipping within U.S.A.
Destination, rates & speedsUS$ 7.97 shipping from United Kingdom to U.S.A.
Destination, rates & speedsSeller: BooksRun, Philadelphia, PA, U.S.A.
Paperback. Condition: Good. 2. Ship within 24hrs. Satisfaction 100% guaranteed. APO/FPO addresses supported. Seller Inventory # 0470031603-11-1
Quantity: 1 available
Seller: SecondSale, Montgomery, IL, U.S.A.
Condition: Very Good. Item in good condition. Textbooks may not include supplemental items i.e. CDs, access codes etc. Seller Inventory # 00042566830
Quantity: 1 available
Seller: SecondSale, Montgomery, IL, U.S.A.
Condition: Good. Item in good condition. Textbooks may not include supplemental items i.e. CDs, access codes etc. Seller Inventory # 00054518718
Quantity: 1 available
Seller: Wonder Book, Frederick, MD, U.S.A.
Condition: Good. Good condition. 2nd edition. A copy that has been read but remains intact. May contain markings such as bookplates, stamps, limited notes and highlighting, or a few light stains. Seller Inventory # N14M-02511
Quantity: 1 available
Seller: ThriftBooks-Atlanta, AUSTELL, GA, U.S.A.
Paperback. Condition: Very Good. No Jacket. May have limited writing in cover pages. Pages are unmarked. ~ ThriftBooks: Read More, Spend Less 1.6. Seller Inventory # G0470031603I4N00
Quantity: 1 available
Seller: Better World Books, Mishawaka, IN, U.S.A.
Condition: Good. 2 Edition. Used book that is in clean, average condition without any missing pages. Seller Inventory # 14684731-6
Quantity: 2 available
Seller: HPB-Red, Dallas, TX, U.S.A.
Paperback. Condition: Good. Connecting readers with great books since 1972! Used textbooks may not include companion materials such as access codes, etc. May have some wear or writing/highlighting. We ship orders daily and Customer Service is our top priority! Seller Inventory # S_350905180
Quantity: 1 available
Seller: Phatpocket Limited, Waltham Abbey, HERTS, United Kingdom
Condition: Good. Your purchase helps support Sri Lankan Children's Charity 'The Rainbow Centre'. Ex-library, so some stamps and wear, but in good overall condition. Our donations to The Rainbow Centre have helped provide an education and a safe haven to hundreds of children who live in appalling conditions. Seller Inventory # Z1-L-004-01193
Quantity: 1 available
Seller: GreatBookPrices, Columbia, MD, U.S.A.
Condition: As New. Unread book in perfect condition. Seller Inventory # 4121810
Quantity: Over 20 available
Seller: PBShop.store UK, Fairford, GLOS, United Kingdom
PAP. Condition: New. New Book. Shipped from UK. Established seller since 2000. Seller Inventory # FW-9780470031605
Quantity: 15 available