PDF Computer Graphics For Java Programmers 3rd Edition Leen Ammeraal Download
PDF Computer Graphics For Java Programmers 3rd Edition Leen Ammeraal Download
com
https://textbookfull.com/product/computer-
graphics-for-java-programmers-3rd-edition-leen-
ammeraal/
https://textbookfull.com/product/computer-graphics-programming-in-
opengl-with-java-gordon/
textbookfull.com
https://textbookfull.com/product/computer-graphics-programming-in-
opengl-with-java-2nd-edition-v-scott-gordon/
textbookfull.com
https://textbookfull.com/product/java-8-pocket-guide-instant-help-for-
java-programmers-1st-edition-liguori-robert-liguori-patricia/
textbookfull.com
https://textbookfull.com/product/introduction-to-software-
engineering-2nd-edition-ronald-j-leach/
textbookfull.com
https://textbookfull.com/product/politics-of-translation-in-
international-relations-zeynep-gulsah-capan-editor/
textbookfull.com
https://textbookfull.com/product/ritualized-writing-buddhist-practice-
and-scriptural-cultures-in-ancient-japan-bryan-d-lowe/
textbookfull.com
https://textbookfull.com/product/the-law-of-journalism-and-mass-
communication-7th-edition-susan-d-ross-amy-l-reynolds-robert-e-trager/
textbookfull.com
Bitten The Secret History of Lyme Disease and Biological
Warfare Kris Newby
https://textbookfull.com/product/bitten-the-secret-history-of-lyme-
disease-and-biological-warfare-kris-newby/
textbookfull.com
Leen Ammeraal · Kang Zhang
Computer
Graphics
for Java
Programmers
Third Edition
Computer Graphics for Java Programmers
Leen Ammeraal • Kang Zhang
It has been 10 years since the publication of the second edition. The programming
language, Java, has now developed into its maturity, being the language of choice in
many industrial and business domains. Yet the skills of developing computer
graphics applications using Java are surprisingly lacked in the computer science
curricula. Though no longer active in classroom teaching, the first author has
developed and published several Android applications using Java, the main lan-
guage for Android developers. The second author has taught Computer Graphics at
his current university for the past 17 years using the first and second editions of
this textbook, apart from his previous years in Australia using different textbooks.
We feel strongly a need for updating the book.
This third edition continues the main theme of the first two editions, that is,
graphics programming in Java, with all the source code, except those for exercises,
available to the reader. Major updates in this new edition include the following:
1. The contents of all chapters are updated according to the authors’ years of
classroom experiences and recent feedback from our students.
2. Hidden-line elimination and hidden-face elimination are merged into a single
chapter.
3. A new chapter on color, texture, and lighting is added, as Chap. 7.
4. The companion software package, CGDemo, that demonstrates the working of
different algorithms and concepts introduced in the book, is enhanced with two
new algorithms added and a few bugs fixed.
5. A set of 37 video sessions (7–11 min each) in MOOC (Massive Open Online
Course) style, covering all the topics of the textbook, is supplemented.
6. A major exercise, split into four parts, on implementing the game of Tetris is
added at the end of four relevant chapters.
Many application examples illustrated in this book could be readily
implemented using Java 3D or OpenGL without any understanding of the internal
working of the implementation, which we consider undesirable for computer
science students. We therefore believe that this textbook continues to serve as an
indispensable introduction to the foundation of computer graphics, and more
v
vi Preface
importantly, how various classic algorithms are designed. It is essential for com-
puter science students to learn the skills on how to optimize time-critical algorithms
and how to develop elegant algorithmic solutions.
The example programs can be downloaded from the Internet at:
http://home.kpn.nl/ammeraal/
or at:
http://www.utdallas.edu/~kzhang/BookCG/
Finally, we would like to thank the UT-Dallas colleague Pushpa Kumar, who has
been using this textbook to teach undergraduate Computer Graphics class and
provided valuable feedback. We are grateful to Susan Lagerstrom-Fife of Springer
for her enthusiastic support and assistance in publishing this edition.
1 Elementary Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.1 Pixels and Device Coordinates . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2 Logical Coordinates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.3 Anisotropic and Isotropic Mapping Modes . . . . . . . . . . . . . . . . . 12
1.4 Defining a Polygon Through Mouse Interaction . . . . . . . . . . . . . 19
Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2 Applied Geometry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
2.1 Vectors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
2.2 Inner Product and Vector Product . . . . . . . . . . . . . . . . . . . . . . . 31
2.3 The Orientation of Three Points . . . . . . . . . . . . . . . . . . . . . . . . 34
2.4 Polygons and Their Areas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
2.5 Point-in-Polygon Test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
2.6 Triangulation of Polygons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
2.7 Point-on-Line Test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
2.8 Projection of a Point on a Line . . . . . . . . . . . . . . . . . . . . . . . . . 55
2.9 Distance Between a Point and a Line . . . . . . . . . . . . . . . . . . . . . 57
Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
3 Geometrical Transformations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
3.1 Matrix Multiplication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
3.2 Linear Transformations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
3.3 Translations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
3.4 Homogeneous Coordinates . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
3.5 Inverse Transformations and Matrix Inversion . . . . . . . . . . . . . . 72
3.6 Rotation About an Arbitrary Point . . . . . . . . . . . . . . . . . . . . . . . 73
3.7 Changing the Coordinate System . . . . . . . . . . . . . . . . . . . . . . . . 78
3.8 Rotations About 3D Coordinate Axes . . . . . . . . . . . . . . . . . . . . 79
3.9 Rotation About an Arbitrary Axis . . . . . . . . . . . . . . . . . . . . . . . 80
Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
vii
viii Contents
4 Classic 2D Algorithms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
4.1 Bresenham Line Drawing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
4.2 Doubling the Line-Drawing Speed . . . . . . . . . . . . . . . . . . . . . . . 97
4.3 Circle Drawing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
4.4 Cohen–Sutherland Line Clipping . . . . . . . . . . . . . . . . . . . . . . . . 106
4.5 Sutherland–Hodgman Polygon Clipping . . . . . . . . . . . . . . . . . . 112
4.6 Bézier Curves . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
4.7 B-Spline Curve Fitting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
5 Perspective and 3D Data Structure . . . . . . . . . . . . . . . . . . . . . . . . . 137
5.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
5.2 Viewing Transformation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
5.3 Perspective Transformation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
5.4 A Cube in Perspective . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
5.5 Specification and Representation of 3D Objects . . . . . . . . . . . . . 149
5.6 Some Useful Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
5.7 A Program for Wireframe Models . . . . . . . . . . . . . . . . . . . . . . . 172
5.8 Automatic Generation of Object Specification . . . . . . . . . . . . . . 177
Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
6 Hidden-Line and Hidden-Face Removal . . . . . . . . . . . . . . . . . . . . . 191
6.1 Hidden-Line Algorithm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
6.2 Backface Culling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
6.3 Painter’s Algorithm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200
6.4 Z-Buffer Algorithm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220
7 Color, Texture, and Shading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225
7.1 Color Theories . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225
7.2 Additive and Subtractive Colors . . . . . . . . . . . . . . . . . . . . . . . . 227
7.3 RGB Representation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230
7.4 HSV and HSL Color Models . . . . . . . . . . . . . . . . . . . . . . . . . . . 234
7.5 Transparency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237
7.6 Texture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
7.7 Surface Shading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242
Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251
8 Fractals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253
8.1 Koch Curves . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253
8.2 String Grammars . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257
8.3 Mandelbrot Set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268
8.4 Julia Set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278
Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279
Contents ix
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 385
Chapter 1
Elementary Concepts
This book is primarily about computer graphics programming and related mathe-
matics. Rather than discussing general graphics subjects for end users or how to use
graphics software, we will cover 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 coordi-
nates. In many applications, logical coordinates are more convenient, provided we
can convert them to device coordinates before displaying on the screen. With input
from a mouse, we would also need the inverse conversion, i.e. converting device
coordinates to logical coordinates, as we will see at the end of this chapter.
We will now use statements such as the above 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). If you are not yet familiar with Java, you should
consult other books, such as those mentioned in the Bibliography. This book
assumes you to be fluent in basic Java programming.
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.*;
RedRect() {
super("RedRect");
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {Sytem.exit(0);}
});
setSize(300, 150);
add("Center", new CvRedRect());
setVisible(true);
}
}
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
1.1 Pixels and Device Coordinates 3
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 following program segment:
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {System.exit(0);}
});
which enables the user of the program to terminate it in the normal way. 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 program seg-
ment, the argument of addWindowListener denotes an object of an anonymous
subclass of WindowAdapter. In this subclass we override the method
windowClosing.
The RedRect constructor shows that the frame size is set to 400 200. If we do
not modify this size (by dragging a corner or an edge of the window), the canvas
size is somewhat smaller than the frame. After compilation, we run the program by
typing the command
java RedRect
which, with the given frame size, produces the largest possible red rectangle, shown
in Fig. 1.1 just inside the frame.
The blank area in a frame, which we use for graphics output, is referred to as a
canvas, 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 the top and bottom borders. Since these numbers may differ on 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 to obtain the canvas dimensions and
how to interpret them:
Dimension d = getSize();
int maxX = d.width - 1, maxY = d.height - 1;
the highest possible index value is 7, not 8. In such cases, the “index” is always one
less than “size”. 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);
g.drawRect(x, y, w, h);
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 method:
g.drawLine(x, y, x, y);
A much easier but still non-trivial problem, illustrated in Fig. 1.3b, is filling 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);
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);
As Fig. 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, that starts at the top and increases y as we go to the next line of text.
However, this direction of the y-axis is different from typical mathematical practice
and therefore often inconvenient in graphics applications. For example, in a dis-
cussion about a line with a positive slope, we expect to go upward when moving
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 0 ¼ maxY y
Instead of the discrete (integer) coordinates at the lower, device oriented level, we
often wish 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: rounding and truncating, even in the simple case in which
increasing a logical coordinate by one results in increasing the device coordinate
also by one. We wish to write the following methods:
iX(x), iY( y): converting the logical coordinates x and y to device coordinates;
fx(x), fy( y): converting the device coordinates X and Y to logical coordinates.
One may notice that we have used lower-case letters to represent logical coordi-
nates and capital letters to represent device coordinates. This will be the convention
used throughout this book. With regard to x-coordinates, the rounding solution
could be:
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 x < 8:5
13:5 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 point C at the top. Then, using
q ¼ 0:05
p ¼ 1 q ¼ 0:95,
we compute the new points A0 , B0 and C0 near A, B and C and lying on the sides AB,
BC and CA, respectively, writing:
xA1 = p * xA + q * xB;
yA1 = p * yA + q * yB;
xB1 = p * xB + q * xC;
yB1 = p * yB + q * yC;
xC1 = p * xC + q * xA;
yC1 = p * yC + q * yA;
We then draw the triangle A0 B0 C0 , which is slightly smaller than ABC and turned
a little counter-clockwise. Applying the same principle to triangle A0 B0 C0 to obtain
a third triangle, A00 B00 C00 , and so on, until 50 triangles have been drawn, the result
will be as shown in Fig. 1.5.
Triangles() {
super("Triangles: 50 triangles inside each other");
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {System.exit(0);}
});
setSize(600, 400);
add("Center", new CvTriangles());
setVisible(true);
}
}
void initgr() {
Dimension d = getSize();
maxX = d.width - 1; maxY = d.height - 1;
minMaxXY = Math.min(maxX, maxY);
xCenter = maxX / 2; yCenter = maxY / 2;
}
In the canvas class CvTriangles there is a method initgr. Together with the other
program lines that precede the paint method in this class, initgr may also be useful
in other programs.
It is important to notice that, on each triangle edge, the computed floating-point
coordinates, not the integer device coordinates derived from them, are used for
further computations. This principle, which applies to many graphics applications,
can be depicted as follows:
which is in contrast to the following scheme, which we should avoid. Here int
device coordinates containing rounding-off errors are used not only for graphics
output but also for further computations, so that such errors will accumulate:
In summary, we compare and contrast the logical and device coordinate systems in
the following table, in terms of (1) the convention used in the text, but not in Java
programs, of this book, (2) the data types of the programming language, (3) the
coordinate value domain, and (4) the direction of positive y-axis:
to the set of integer device coordinates {0, 1, 2, . . ., 9}. Unfortunately, the method:
used in the previous section, is not suitable for this purpose because for any
x greater than 9.5 (and not greater than 10) it returns 10, which does not belong
to the allowed sequence 0, 1, ..., 9. In particular, it gives:
ix(10.0) = 10
while we want:
ix(10.0) = 9
maxX = n - 1;
pixelWidth = rWidth/maxX;
1.3 Anisotropic and Isotropic Mapping Modes 13
9 ´ pixel Width
Pixel number X 0 1 2 3 4 5 6 7 8 9
Logical x 0 1 2 3 4 5 6 7 8 9 10
10 logical units
In the above example the integer n is equal to the interval length rWidth, but it is
often desirable to use logical coordinates x and y satisfying
0 x rWidth
0 y rHeight
where rWidth and rHeight are real numbers, such as 10.0 and 7.5, respectively,
which are quite different from the numbers of pixels that lie on horizontal and
vertical lines. It will then be important to distinguish between isotropic and
anisotropic mapping modes, as we will discuss in a moment.
As for the simpler method:
of the previous section, this can be regarded as a special case of the improved one
we have just seen, provided we use pixelWidth ¼ 1, that is rWidth ¼ maxX, or
rWidth ¼ n 1. For example, if the drawing rectangle is 100 pixels wide, so that
n ¼ 100 and we can use the pixels 0, 1, 2, . . ., 99 ¼ maxX on a horizontal line, this
simpler method iX works correctly if it is applied to logical x-coordinates satisfying
0 x rWidth ¼ 99:0
The point to be noticed is that, due to the value pixelWidth ¼ 1, the logical width is
99.0 here although the number of available pixels is 100.
The term anisotropic mapping mode implies that the scale factors for x and y are not
necessarily equal, as the following code segment shows:
14 1 Elementary Concepts
Dimension d = getSize();
maxX = d.width - 1; maxY = d.height - 1;
pixelWidth = rWidth/maxX;
pixelHeight = rHeight/maxY;
...
int iX(float x){return Math.round(x/pixelWidth);}
int iY(float y){return maxY - Math.round(y/pixelHeight);}
float fx(int x){return x * pixelWidth;}
float fy(int y){return (maxY - y) * pixelHeight;}
Anisotr() {
super("Anisotropic mapping mode");
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {System.exit(0);}
});
setSize(400, 300);
add("Center", new CvAnisotr());
setCursor(Cursor.getPredefinedCursor(
Cursor.CROSSHAIR_CURSOR));
setVisible(true);
}
}
CvAnisotr() {
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent evt) {
xP = fx(evt.getX()); yP = fy(evt.getY());
repaint();
}
});
}
void initgr() {
Dimension d = getSize();
maxX = d.width - 1; maxY = d.height - 1;
pixelWidth = rWidth / maxX; pixelHeight = rHeight / maxY;
}
With the anisotropic mapping mode, the actual length of a vertical unit can be
different from that of a horizontal unit. This is the case in Fig. 1.7: although the
rectangle is 10 units wide and 7.5 units high, its real height is less than 0.75 of its
width. In particular, the anisotropic mapping mode is not suitable for drawing
squares, circles and other shapes that require equal units in the horizontal and
vertical directions.
We can arrange for horizontal and vertical units to be equal in terms of their real
size by using the same scale factor for x and y. Let us use the term drawing
rectangle for the rectangle with dimensions rWidth and rHeight, in which we
normally draw graphical output. Since these logical dimensions are constant, so is
their ratio, which is not the case with that of the canvas dimensions. It follows that,
with the isotropic mapping mode, the drawing rectangle will in general not be
identical with the canvas. Depending on the current window size, either the top and
bottom or the left and right edges of the drawing rectangle lie on those of the
canvas.
Since it is normally desirable for a drawing to appear in the center of the canvas,
it is often convenient with the isotropic mapping mode to place the origin of the
logical coordinate system in that center. This implies that we will use the following
logical-coordinate intervals:
½rWidth x þ½rWidth
½rHeight y þ½rHeight
Random documents with unrelated
content Scribd suggests to you:
often the stimulus starts only a reflex action, usually at the place of
application.
A stimulus acting for but a short time produces no lasting effect
on the idioplasm. A person stung by a wasp suffers no permanent
effect from the injury. But if a stimulus acts for a long time, and
through a large number of generations, then it may, even if of small
strength, so change the idioplasm, that a tendency or disposition
capable of being seen may be the result. This appears to be the case
in regard to the action of light, which causes certain parts of the
plant to turn toward it and others away from it; also for the action of
gravity, which determines the downward direction of the roots. It
may be claimed, perhaps, that these are the results of direct
influence and not of an internal response, but this is not the case;
for some plants act in exactly the opposite way, and send a stem
downward, as in the case of the cleistogamous flowers of Cardamine
chenopodifolia; and other plants turn away from the light. This
means that the idioplasm behaves differently in different plants in
response to the same stimulus.
Concerning the more visible effects of adaptation, Nägeli states
that in regard to some of them there can be no question as to how
they must have arisen. Protection against cold, by the formation of a
thick coat of hair, is the direct result of the action of the cold on the
skin of the animal. The different weapons of offence and of defence,
horns, spurs, tusks, etc., have arisen, he maintains, through stimulus
to those parts of the body where these structures arise.
The causes of the other adaptations, especially of those occurring
in plants, are less obvious. Land plants protect themselves from
drying by forming a layer of cork over the surface. The most
primitive plants were water plants, which acclimated themselves
little by little to moist, and then to dry, air. When they first emerged
from the water the drying acted as a stimulus on the surface, and
caused it to harden in the same way as a drop of glue hardens. This
hardening in turn acted as a stimulus, causing a chemical
transformation of the surface into a corky substance. This effect was
inherited, and in this way the power to form cork originated.
Land plants have, in addition to the soft parts, the hard bast and
wood which serves the mechanical purpose of supporting the soft
tissues and protecting them from being injured. The arrangement of
the hard parts is such as to suggest that they are the result of the
action of pressures and tensions on the plant, for the strongest cells
are found where there is most need for them. It is easy to imagine,
Nägeli adds, that this important arrangement of the tissues is the
result of external forces which brought about the result in these
parts.
Nägeli accounts for the origin of twining plants as follows. Being
overshadowed by other plants, the stem will grow rapidly in the
damp air. Coming in contact with the stems of other plants, the
delicate stem is stimulated on one side, and grows around the point
of contact. This tendency becomes inherited, and the habit to twine
is ultimately established.
The difference in the two sides of leaves is explained by Nägeli as
the result of the difference in the illumination of the two sides. This
influence of light on the leaf has been inherited. The formation of
the tubular corolla that is seen in many plants visited by insects is
explained as the result of the stimulus produced by the insects in
looking for the pollen. The increase in the length of the proboscis of
the insect is the result of the animal straining to reach the bottom of
the ever elongating tube of the corolla. “The tubular corolla and the
proboscis of the insect appear as though made for each other. Both
have slowly developed to their present condition, the long tube from
a short tube and the long proboscis from a short one.” Thus, by
purely Lamarckian principles, Nägeli attempts to account for many of
the adaptations between the organism and the outer world. But if
this takes place, where is there left any room for the action for his
so-called perfecting principle? Nägeli proceeds to show how he
supposes that the two work together.
As a result of inner causes the organism would pass through a
series of perfectly definite stages, J, J1, J2. But if, at any stage,
external influences produced an effect on the organism so that the
arrangement of the idioplasm changes in response, a new
adaptation is produced. In this way new characters, not inherent in
the idioplasm, may be added, and old ones be changed or lost. “In
order not to be misunderstood in regard to the completing or
perfecting principle I will add, that I ascribe to it no determinate
action in the organism, neither in producing the long neck of the
giraffe, nor the prehensile tail of the ape, neither the claws of the
crab, nor the decoration of the bird of paradise. These structures are
the outcome of both factors. I cannot picture to myself how external
causes alone, and just as little how internal causes alone, could have
changed a monad into a man.” But Nägeli goes on to say, that if at
any stage of organization one of the two causes should cease to act,
the other could only produce certain limited results. Thus, if external
causes alone acted, the organization would remain at the same
stage of completeness, but might become adapted to all kinds of
external conditions—a worm, for instance, would not develop into a
fish, but would remain a worm forever, although it might change its
worm structure in many ways in response to external stimuli. If, on
the other hand, only the completing principle acted, then without
changing its adaptations the number of the cells and the size of the
organs might be increased, and functions that were formerly united
might become separated. Thus, without altering the character of the
organism, a more highly developed (in the sense of being more
specialized) organism would appear.
Nägeli, as we have just seen, has attempted to build up a
conception of nature based on two assumptions, neither of which
has been demonstrated to be an actual principle of development. His
hypothesis appears, therefore, entirely arbitrary and speculative to a
high degree. Even if it were conceivable that two such principles as
these control the evolution of organisms, it still requires a good deal
of imagination to conceive how the two go on working together.
Moreover, it is highly probable that whole groups have evolved in the
direction of greater simplification, as seen especially in the case of
those groups that have become degenerate. To what principle can
we refer processes of this sort?
It is certainly a strange conclusion this, at which Nägeli finally
arrives, for, after strenuously combating the idea that the external
factors of climate and of food have influence in producing new
species, he does not hesitate to ascribe all sorts of imaginary
influences to other external causes. The apparent contradiction is
due, perhaps, to the fact that his experience with actual species led
him to deny that the direct action of the environment produces
permanent changes, while in theory he saw the necessity of adding
to his perfecting principle some other factor to explain the
adaptations of the new forms produced by inner causes. Nägeli
seems to have felt strongly the impossibility of explaining the
process of evolution and of adaptation as the outcome of the
selection of chance variations, now in this direction, now in that. He
seems to have felt that there must be something within the
organism that is driving it ever upward, and he attempts to avoid the
teleological element, which such a conception is almost certain to
introduce, by postulating the inheritance of the effects of long-
continued action of the environment, in so far as certain factors in
the environment produce a response in the organism. Nevertheless,
this combination is not one that is likely to commend itself, aside
from the fact that the assumptions have no evidence to support
them. Despite Nägeli’s protest that his principles are purely physical,
and that there is nothing mystical in his point of view, it must be
admitted that his conception, as a whole, is so vague and difficult in
its application that it probably deserves the neglect which it
generally receives.
Nägeli’s wide experience with living plants convinced him that
there is something in the organism over and beyond the influence of
the external world that causes organisms to change; and we cannot
afford, I think, to despise his judgment on this point, although we
need not follow him to the length of supposing that this internal
influence is a “force” driving the organism forward in the direction of
ever greater complexity. A more moderate estimate would be that
the organism often changes through influences that appear to us to
be internal, and while some of the changes are merely fluctuating or
chance variations, there are others that appear to be more limited in
number, but perfectly definite and permanent in character. It is the
latter, which, I believe, we can safely accredit to internal factors, and
which may be compared to Nägeli’s internal causes, but this is far
from assuming that these changes are in the direction of greater
completeness or perfection, or that evolution would take place
independently of the action of external agencies.
CHAPTER X