+ All Categories
Home > Documents > University of Leicester Department of Physics and ... · 15.2 Task - class Mandelbrot ... This...

University of Leicester Department of Physics and ... · 15.2 Task - class Mandelbrot ... This...

Date post: 11-May-2018
Category:
Upload: nguyentuong
View: 215 times
Download: 3 times
Share this document with a friend
96
University of Leicester Department of Physics and Astronomy Third/Fourth Year Computing Workshop Object-Oriented Programming Prof. R. Willingale October 3, 2012 1
Transcript

University of LeicesterDepartment of Physics and Astronomy

Third/Fourth Year Computing WorkshopObject-Oriented Programming

Prof. R. Willingale

October 3, 2012

1

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 2

Contents

1 Books and reference material 6

2 Recapitulation and jargon 7

3 Concepts in object-oriented programming 8

4 Fortran 90, C, C++ and Java 11

5 Problems and programming 11

6 A suitable problem for OOP 12

7 Using Java on SPECTRE 14

8 Getting started with Java 15

8.1 Task - application First . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

9 A walk through the First program 17

9.1 Task - class Proton . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

10 Expressions, control and exceptions 23

10.1 Task - application Second . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

11 A walk through the Second program 28

11.1 Task - class Vector . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

11.2 Task - scope, this and super . . . . . . . . . . . . . . . . . . . . . . . . . . 31

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 3

12 Abstract classes and interfaces 33

12.1 Task - application Third . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

12.2 Task - class Annulabound . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

13 Graphics 43

13.1 Task - application Fourth . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

14 Applets 50

14.1 Task - applet Fifth . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

15 Writing your own Java Program 52

15.1 Task - interface ComplexSet . . . . . . . . . . . . . . . . . . . . . . . . . . 52

15.2 Task - class Mandelbrot . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

15.3 Task - class RenderSet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

15.4 Task - application Sixth . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

15.5 Task - class Julia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

16 Surface quality in the ray tracing problem 56

16.1 Task - class Detector . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60

16.2 Task - defining a source, a mirror and a detector . . . . . . . . . . . . . . . 61

17 Completing the ray tracing problem 61

17.1 Task - class PlotLocal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65

17.2 Task - application Seventh . . . . . . . . . . . . . . . . . . . . . . . . . . . 66

18 Introducing interactive graphics 68

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 4

18.1 Task - class SurfaceQM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73

18.2 Task - using class SurfaceQM . . . . . . . . . . . . . . . . . . . . . . . . . 73

18.3 Task - applet Eighth . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73

19 Ray tracing spherical surfaces 75

19.1 Task - class SphereQM, application Ninth . . . . . . . . . . . . . . . . . . 79

20 Further interaction 79

20.1 Task - applet Tenth . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82

20.2 Task - class Choice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83

21 Threads and multi-tasking 83

21.1 Task - application Eleventh . . . . . . . . . . . . . . . . . . . . . . . . . . 87

21.2 Task - class SlideSurfaceQM . . . . . . . . . . . . . . . . . . . . . . . . . . 88

21.3 Task - wobbling the source and mirror simultaneously . . . . . . . . . . . . 88

22 Using the classes available 89

22.1 Task - application Twelfth . . . . . . . . . . . . . . . . . . . . . . . . . . . 89

23 Into the unknown 90

23.1 Task - Cellular Automata . . . . . . . . . . . . . . . . . . . . . . . . . . . 91

23.2 Task - Recusive Triangles . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92

24 Quick Java reference 93

24.1 Primitive types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93

24.2 Character escape sequences . . . . . . . . . . . . . . . . . . . . . . . . . . 93

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 5

24.3 Arithmetic operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93

24.4 Relational and conditional operators . . . . . . . . . . . . . . . . . . . . . 94

24.5 Logical operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94

24.6 Bitwise operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94

24.7 class Math methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94

24.8 Repetition and control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95

24.9 class String . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 6

1 Books and reference material

We shall be using Java as an example of a programming language which embodies object-oriented syntax. The emphasis will be on the techniques of object-oriented programmingrather than features specific to Java. There are many, many books on the wonders ofJava. Here is a selection:

• “The Java Programming Language”, Ken Arnold and James Gosling, Addison-Wesley, 1996. This is the book I used to write the workshop. It is one of “The JavaSeries ...from the Source”; books written by members of the JavaSoft team at SunMicrosystems who developed the language. It provides a good introduction to thelanguage itself rather than giving details about its application and wider use.

• “The Complete Guide to Java”, Andrew Cobley, Computer Step, 1997. This is apractical book aimed at people who want to learn Java programming for use on theWorld Wide Web. It is very helpful if the more professional documentation becomesincomprehensible!

• “Just Java”, Peter van der Linden, SunSoft Press, 1996. A more formal but ratherexpensive introduction.

• “Exploring Java”, Patrick Niemeyer and Joshua Peck, 2nd Ed., O’Reilly &Associates, Inc., 1997. A good book which is aimed at World Wide Web applicationof Java.

• “Developing Java Software”, Russel Winder and Grahman Roberts, John Wiley &Sons, 1998. A more comprehensive text about writing large systems in Java code.

• “Java for Students”, Douglas Bell and Mike Parr, Prentice Hall Europe, 1998. Agood introduction with emphasis on graphical user interfaces right from the start.

• “Java API for Dummies”, S.D. Lockwood and M. Siddalingaiah, IDG Books, 1997.A very handy reference book for more advanced applications programming in Javawhich lists all the classes and associated methods available in the ApplicationProgramming Interface (API).

• “Graphic Java Mastering the AWT” D.M. Geary and A.L.McClellan, Sunsoft Press,1997. A more complete description of the Java Abstract Window Toolkit (AWT).Not a book for beginners but a useful reference once you understand what is goingon.

• “The C++ Programming Language”, Bjarne Stroustrup, Addison-Wesley, 2nd Ed.,1991. Another well know language which embodies object-oriented programmingsyntax is C++. The definitive book on C++ is by the head of the research groupat AT&T Bell Laboratories in New Jersey who developed the language. This is not

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 7

a book for the faint hearted. It is excellent if you are familiar with the jargon andalready have a good understanding of programming in general and it does have agood introduction which puts the ideas of object-oriented programming in context.

There are many useful links on the WWW which provide excellent documentationand information on Java. For example the index of documentation provided by SunMicrosystems

http://java.sun.com/docs/

http://java.sun.com/docs/books/tutorial/

We shall be running Java under Linux A quick reference for UNIX/Linux commands canbe found at

http://www.star.le.ac.uk/~rw/compshop

2 Recapitulation and jargon

Before we launch into object-oriented programming it will be a good idea to review whatyou already know about programming from experience with C or Fortran in the 1st/2ndyears.

A C program consists of a set of ordered instructions. This is called “imperative”programming. The sequence of these instructions is most important.

“Control structures”, loops and ifs etc., are used to determine the flow through theinstructions.

Values of numbers and more complicated data manipulated by the program are stored in“variables”. Such variables are given names within the program. Variables can be updatedas the program proceeds. This updating or changing of a variable is called assignment.

The actual flow depends on the “state” of the program. The state is determined by thevalues of variables in the program at a given time.

Variables have a “type”, integer, real, complex etc.. As the types available become morecomplicated then it is important that the compiler performs type checking to avoid illegalexpressions involving mixed types.

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 8

Groups of instructions can be wrapped up into “procedures” with a simple well definedinterface. This process is known as “abstraction” because we are highlighting the essentialdetails of something (in the form of an interface) and hiding the nitty-gritty details (thesequence of instructions required). Procedures like C functions provide abstraction overinstructions.

Abstraction is closely related to the concept of “encapsulation” such that things havea well defined inside and outside. Again C subroutines perform encapsulation. Theinner workings of a subroutine are protected from the outside. The only contact withthe rest of the program is the interface which is defined by a set of arguments. Such“encapsulation” often helps to free the software designer and programmer from thecomplexities of implementation.

C is an example of a “procedural” programming language. The method of proceduralprogramming requires the programmer to draw a flow diagram (now very much outof fashion but still most useful) indicating the steps required for the computation andthe data or variables required for each step. The flow diagram shows how variousdata elements pass through a series of operations and this flow defines the procedureor procedures required. In C the key programming elements are functions or subroutines,modules or procedures which do things. The programmer decides which data elementsmust be passed to these modules to carry out the algorithm or sequence of operationsrequired.

In C you can define data structures. These are complicated data types which comprisemany components welded together and refered to by a single name. This is called “dataabstraction”, a process in which a simple name is used to refer to and hide the unnecessarynitty-gritty details of a complicated entity.

Programming with heavy use of data structures is sometimes referred to as “data-oriented”programming.

The concept of a “data object” is central to “Object-Oriented” Programming (OOP). Itinvolves a further level of abstraction and encapsulation over and above C functions andC structures. A data object is an abstraction which encapsulates both the instructionsAND the data. At present this will seem to be just words but when you have completedthe workshop you should have a better idea of what this means.

3 Concepts in object-oriented programming

Object-Oriented Programming (OOP) is a different way of programming not a differentway of computing. At the bottom level what the machine actually does when it is

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 9

running the program is likely to be almost the same whether procedural or object-orientedprogramming were used. So the two approaches are just a different way of telling thecomputer what to do. To switch from a procedural style to an object-oriented style youmust stop thinking about subroutines, functions and variables and start thinking aboutdata objects and the way in which they interact. The syntax of OOP provides a uniformway to describe the data structures AND the operations required on elements of thosedata structures.

Just as a flow diagram is a natural way of describing a procedural style so a Venn diagramor hierarchical tree diagram is more appropriate for OOP. The idea is to group togetherrelated functions and data so that they can be described in an economical way. This isachieved by “abstraction” and “encapsulation” of both instructions and state. What youdo is wrap up functions or operations with collections of data. This “abstraction” and“encapsulation” is described by a hierarchical “class” structure.

This is present in a primitive and latent form in C and most other languages. Alllanguages handle variables and some of these variables are numbers. All numbers can beadded and subtracted and so on, but in practice they are divided into two classes REALand INTEGER. These are sub-divided further into SINGLE and DOUBLE precisiondepending on the number of bits used to represent them. Furthermore some of thesenumbers can be designated constants, variables that in fact should never change andcannot, therefore, appear on the left hand side of an assignment.

variables

|

--------------------

| |

numbers characters

|

----------------

| |

real integer

| |

-------- -------

| | | |

single double short long

In an object-oriented language such hierarchical structures can be defined by theprogrammer to construct very complicated data objects in an efficient way. The hierarchyshould be dictated by the operations or functions which are to be performed on the datacomponents.

A hierarchical structure is by no means unique and the art of successful OOP is to invent

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 10

the best class structure for the problem in hand. It is often the case that separatehierarchical trees overlap and the overall class structure can become rather complicated.For example a fundamental class concept in all programming is the array. You can havearrays of almost any sort of data object. For example, a complex number is a two elementarray consisting of two real numbers.

In order to make an object-oriented syntax work efficiently we must employ“polymorphism” for naming operations or functions. The word is derived from the Greekfor “many forms” and the concept is already present in C and other procedural languagesand is prevalent in mathematics. For example we can refer to the addition of two integers,two real numbers, two complex numbers or even two vectors. In each case the word“addition” is used to describe a different set of operations which are related. Similarlywe can take the sine function of a real number or a complex number or even all theelements of a vector. Again the word sine is used to describe different operations thatare mathematically related. We may write SIN(A) for all these where the operationdepends on the type of object A. This is polymorphism. Those of you who have someexperience with C++ may have come across “operator overloading”. This is also a formof polymorphism.

A final element which is essential to making object-oriented syntax efficient is“inheritance”. This too is present in a primitive form in Fortran 90. For example thereal and imaginary part of a complex number inherit the properties of real numbers. Inobject-oriented code all the objects of a particular class which are extensions of a moreprimitive class will inherit the properties of that more primitive class. This provides anenormous gain in efficiency and reliability because once a particular class of properties isdefined it can be incorporated into new and more complicated classes with the minimumof effort and without the possibility of error. Because the functions are embedded in theclass structure these are inherited as well. Class definitions further down the tree structureactually inherit code which is defined and present above them in the tree structure.

In summary OOP makes use of “encapsulation”, “polymorphism” and “inheritance” allof which are present in Fortran 90. However what Fortran 90 does not have is a syntaxwhich presents all three of these to the programmer in a flexible way.

The concepts of “class”, “type” and “instance” are important when describing OOP. An“instance” is a particular occurrence of a data object “type”. At run time it exists inthe computer as a collection of real code and data. A data object “type” is a definitionwhich can be used to create an instance of a data object. Data types can be arrangedin a hierarchical structure of classes so a “class” may in fact be a type but it may be anabstract idea which groups together a number of types. For example in Fortran an arrayis a “class” of variable but it is not a “type” since you can’t have an “instance” of justan array, it has to be an array of something. On the other hand an array of integers is a“type” of variable. An integer scalar is both a “class” and a “type”. Finally an integerdeclared in some subroutine is an “instance” of the integer “type”.

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 11

4 Fortran 90, C, C++ and Java

Fortran 90 offers one of the best scientific programming environments that has beenhoned over more than 20 years to provide the tools required by physicists and scientiststo perform computations or formula transformations as the original derivation of theword Fortran suggests. Fortran 90 is an excellent example of a procedural programminglanguage.

C++ is probably the most widely used object-oriented programming language. It isan extension of the popular C programming language developed from 1985 to 1991 andprovides the three key elements described above. C is a low level procedural languageand C++ adds on object-oriented syntax. Unfortunately reasonable familiarity with C isrequired to provide an understanding of the ++ bits. It would be impossible to give acomprehensive C and C++ course in the time available for a 3rd/4th year workshop.

Java was developed by Sun Microsystems in the period 1990-1995 and the first properrelease, version 1.0, was in 1996. It is a kind of rationalisation of the ++ bits of C++. Itis entirely based on OOP syntax and is uncluttered by pointers and other complicationspresent in C. It also includes a more user friendly implementation of arrays like Fortranrather than the awkward definitions of arrays available in C. Java implementations areinterpreter based rather than compiler based because this makes it platform neutral andideal for use on networks like the World Wide Web. Because of this the code executesrelatively slowly. However with the speed of modern machines this is not a problem andalmost certainly compiler implementations or extensions of Java will become the norm inthe near future. Java is easier to use and designed as a higher level language than C++although most of the syntax is borrowed directly from C++. Like Fortran 90 it is theresult of evolution in programming and is probably the best attempt yet at providing anall-purpose high level interpreter.

5 Problems and programming

The professional programmer should not force a language to fit a particular problem butchoose a particular language which is well suited to the problem in hand. Unfortunatelythings are not always so clear cut. However if you want to become a good programmeryou should consider the following:

Language syntax comes in three basic flavours; procedure-oriented, data-oriented andobject-oriented.

Computational problems come in a large spectrum of flavours; assembler/low-level,

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 12

system/compiler writing etc., windows systems, data systems, communications, datalogging, scientific computation, the list is very large and there is no obvious uniquesequence. Some problems may require a lot of development time to solve but will executevery quickly. Others will be easy to code but will take forever to execute.

If the problem you want to solve is important and big enough it is often worth the effortof learning a new language, or to learn some more of a language you already know a littleabout, rather than struggling with a familiar but inappropriate syntax.

OOP is not the answer to everything. Defining complicated data objects in an efficientand elegant way may not be the crux of a problem. You should choose your language andyour programming style to suit the problem. However to make this choice in an informedway you need to know what the various options are about. This course aims to give yousome idea of what OOP is about so that you can make the correct choice and use it whenappropriate.

6 A suitable problem for OOP

The most common way of learning object-oriented programming and indeed using OOPin anger is in the development of windows systems. If you browse over the shelves in thelocal bookshop you will find large tomes concerned with windows programming and theMicrosoft Foundation Class (MFC) library or similar topics. These are daunting. Theyoften claim that OOP makes such programming less complicated and much easier butglancing through the many sections and sub-sections will probably convince you otherwise.However, it is the case that object-orientation is a very good way of providing tools forthe solution to a particular type of problem. This is analagous to the way subroutinesand functions in the NAG library can provide the tools for a procedural solution to manynumerical scientific problems.

For this workshop we have chosen a more scientific programming example to try andintroduce the main aspects of OOP. The idea is to perform particle or ray tracing throughsome instrument. The instrument might be a telescope or spectrometer and the particlesmight be photons or electrons or whatever. We will try to write code which can be adaptedeasily to many possible configurations in the same way that the MFC library is designedto provide the basic tools for windows programming.

Suppose you have an instrument which consists of various elements, polished mirrorsurfaces, stops and apertures etc.. Each element has a defined geometry and definedlimits. We can set up a simple hierarchy:

surface geometry

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 13

|

--------------------------------------

| | |

plane sphere surface of revolution

|

---------------------

| | |

cylinder paraboloid hyperboloid

The elements will also be characterised by some surface quality:

surface quality

|

-------------------------------------------------------

| | | |

smooth rough grating emitter

| | |

---------- ---------- -----------

| | | | | |

Gaussian fractal periodic aperiodic parallel diffuse

Finally the rays or particles can be similarly arranged:

particle

|

-----------------

| |

photon electron

None of the above is unique, the arrangment could be different, and extra complexitycould be added. Finding the best hierarchical description for the objects is the mainproblem with OOP. It may be that you have to try various possibilities before you findthe best approach.

The underlying procedure which we want to follow is:

1) generate a ray or particle - position, direction, energy

|

\ /

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 14

|

2) search for intersection of ray with surface - new position

|

\ /

|

3) reflect, scatter or absorb particle - new position, direction, energy

|

\ /

|

4) if absorbed go to 1), if not absorbed go to 2)

These steps would be repeated for a maximum number of injected particles.

Steps 1) to 2) or 4) to 2) involve the propogation of the particle. This may be influencedby changing refractive index or electric and magnetic fields.

Step 2) depends on the geometry of the surfaces.

Step 3) depends on the surface quality and the type of particle.

7 Using Java on SPECTRE

The Java compiler is called javac and expects source files with the extension .java

spectre$ javac First.java

This creates a file First.class which contains the machine independent Java bytecodes.You must then use the Java interpreter to run your program.

spectre$ java First

No extension is required on the file name since it expects the default .class produced bythe compiler. Of course the name of the file, First in the above example, should reflectthe class or classes contained in the file.

In order that the files you create with Java don’t get mixed up with other files you mighthave we suggest that you create a new directory to work in during this course. So createa new directory called java under your home directory and change the default to thisdirectory.

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 15

spectre$ cd ensure that you are in your home directory

spectre$ mkdir java create a new directory for the workshop

spectre$ cd java select the new directory as default

8 Getting started with Java

We are going to use the particle tracing problem outlined above as a vehicle to introduceJava. The following code is a simple implementation of stage 1) in which particles aregenerated. You will see that it looks very different from a Fortran 90 program. In fact itlooks much more like a C or C++ program but EVERYTHING in Java is “encapsulated”in a class.

class ElementaryParticle

{

public long pnum;

public double[] position = {0.0,0.0,0.0};

public double[] direction = {0.0,0.0,0.0};

private static long nextpnum = 0;

ElementaryParticle()

{

pnum=++nextpnum;

}

public void println()

{

System.out.println("particle number "+pnum);

System.out.print(" position ");

System.out.print(position[0]+","+position[1]+","+position[2]);

System.out.println();

System.out.print(" direction ");

System.out.print(direction[0]+","+direction[1]+","+direction[2]);

System.out.println();

}

}

class Photon extends ElementaryParticle

{

public double wavelength;

Photon(double phwl)

{

wavelength=phwl;

}

public void println()

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 16

{

super.println();

System.out.println(" particle type: photon");

System.out.println(" wavelength "+wavelength);

}

}

class Electron extends ElementaryParticle

{

public double velocity;

static final double charge=-1.60e-19;

Electron(double elve)

{

velocity=elve;

}

public void println()

{

super.println();

System.out.println(" particle type: electron");

System.out.println(" velocity "+velocity);

}

}

class First

{

public static void main(String[] args)

{

System.out.println("Running first program");

Electron el1 = new Electron(55.4);

el1.direction[0]=0.3;

el1.direction[1]=0.2;

el1.direction[2]=Math.sqrt(1.0-Math.pow(el1.direction[0],2)-

Math.pow(el1.direction[1],2));

Photon ph1 = new Photon(10.9);

el1.println();

ph1.println();

}

}

8.1 Task - application First

Type the above program verbatim into a file called First.java using your favourite editor.Then you can use the Java compiler javac and interpreter java as described above to runthe program. Note that Java (and Unix) are case sensitive so, for example, photon would

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 17

not be the same as Photon in the above. The output using the machine spectre shouldbe:

spectre$ javac First.java

spectre$ java First

Running first program

particle number 1

position 0.0 0.0 0.0

direction 0.3 0.2 0.9327379053088815

particle type: electron

velocity 55.4

particle number 2

position 0.0 0.0 0.0

direction 0.0 0.0 0.0

particle type: photon

wavelength 10.9

spectre$

When carrying out this and subsequent tasks keep a record of what you are doing in yournotebook including date, task number, listings of your source code, notes on how it worksand a record of results and failures.

Task 1 completed on: demonstrator:

9 A walk through the First program

The declaration of each class starts with the words “public class” followed by a namefor the class. The rest of the declaration appears between curly braces {}. In Java suchbraces are used to group things together to form a scope. Each line or separate statementwithin the {} is terminated by a semicolon. The ends of lines are irrelevant, it is thesemicolon that matters. The layout of the code is optional but one similar to the abovemakes in easier to read and understand.

Each class declaration can contain:

• fields - these are the data of the class. They play the same role as variables andparameters in Fortran.

• constructors - these initialize fields and perform setting up operations when anobject of the class is created.

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 18

• methods - these are where processing gets done. They play the role of functions orsubroutines in Fortran.

Note that the declaration of the class is only that. It is not creating an actual so calledinstance of the class. It is equivalent to saying what a REAL variable consists of in Fortranrather than creating a particular REAL variable. However, since the declaration of a classmay contain methods, code for these methods may be compiled when you declare a class.

The access declared for classes, fields, methods and interfaces can be public, private,protected or package.

• Public means that the declared item is accessible anywhere the class is accessibleand will be inherited by subclasses.

• Private means that the declared item is only accessible within the class itself.

• Protected means that the declared item is accessible within the class and sub-classesonly and will be encountered later.

• Package means that access is restricted to within a defined software Package (groupof classes).

If the access in omitted (blank) then package is assumed. The package access and Packagesare not dealt with here but for the purposes of this workshop they are essentially public.The use of access is usually only important if you are writing code for use by otherprogrammers.

Look at the class ElementaryParticle declared above. The first four lines in the declarationdeclare fields. Each consists of

access type name;

for example:

public long pnum;

The primitive data types available are boolean (true or false), char (16-bit Unicode 1.1character), byte (8-bit signed), short (16-bit integer signed), int (32-bit integer signed),long (64-bit integer signed), float (32-bit floating point), double (64-bit floating point).

Arrays are declared by adding [] after the type:

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 19

public double[] position = {0.0,0.0,0.0};

In this case the following sequence enclosed in curly brackets initialises the array elementsand defines the number of elements. This declaration could have been:

public double[] position = new double[3];

position[0]=0.0;

position[1]=0.0;

position[2]=0.0;

The word new creates the field concerned. Note that the array index runs from 0 throughto n-1. In the above example the fields position and direction will be created separatelyfor every instance of the class. This will become clearer a little later on.

The declaration of nextpnum is rather different. Now the field is private and static. Thismeans that it is not created separately for every instance of the class. There will only beone unique version of this field (it is static and could be described as a class variable) andit can only be accessed by the ElementaryParticle class (it is private).

private static long nextpnum = 0;

Next comes the declaration of a constructor for the class

ElementaryParticle()

{

pnum=++nextpnum;

}

The constructor has exactly the same name as the class itself, in this caseElementaryParticle. The parentheses () can contain arguments for the constructor but inthis case there is none. Everytime a new instance of the class is created this constructorwill be evoked. In this case the ++ operator will increase the value of the static fieldnextpnum by 1 and then the assignment (=) will assign that value to the field pnum.If the ++ operator had been placed after the field name nextpnum then the assignmentwould be made before the incrementation. This constuctor gives each particle createda unique running identification number. You can now see why the field nextpnum wasdeclared static.

The last thing to be declared within the class ElementaryParticle is a method. The firstline has the form

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 20

access returntype name()

Here the returntype specifies the type or class of the data returned by the method whenit completes which in this case is void (i.e. nothing is returned). The parentheses () cancontain arguments but in this case there is none.

public void println()

{

System.out.println("particle number "+pnum);

System.out.print(" position ");

System.out.print(position[0]+","+position[1]+","+position[2]);

System.out.println();

System.out.print(" direction ");

System.out.print(direction[0]+","+direction[1]+","+direction[2]);

System.out.println();

}

The method println here produces a summary of the ElementaryParticle fields (datavalues). The method System.out.println() resides in class System and subclass out. Thedots between the words are the way Java references elements within the class structure.Because of “encapsulation” all methods are referenced in this way. The argument ofprintln and print (no new line) is just a string constructed from components using the+ operator to join the elements together. That completes the declaration of the classElementaryParticle.

The next two declarations are subclasses of the class ElementaryParticle called Photonand Electron. The declarations start:

public class Photon extends ElementaryParticle

The extends ElementaryParticle tells the compiler that we are declaring a subclass of somepreviously declared superclass, in this case ElementaryParticle. Otherwise the declarationtakes a similar form and contains field declarations, a constructor and methods.

The field charge is qualified with the word final

static final double charge=1.60e-19;

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 21

This is the way you declare named constants in Java equivalent to PARAMETERs inFortran. Again the word static ensures there is only one copy of this field. The word finaltells the compiler that the value is constant. Such a constant is created (compiled) duringthe declaration of a class rather than when a particular instance of the class is created.Constants like pi, the mass of the electron etc. should be declared like this.

The constructors in Photon and Electron have an argument declared as double

Photon(double phwl)

{

wavelength=phwl;

}

The method println extends the declaration already present in the superclassElementaryParticle. The word super.println() refers to this declaration. However printlnis now augmented by an extra statement to print out the wavelength or velocity. Thisis an example of inheritance plus polymorphism. As you will see the behaviour of themethod println depends on the context.

Finally we come to the declaration of the class First which contains the method that isthe program. This must always be called main and declared public static and void.

public static void main(String[] args)

{

...

}

Note that main() always has a single argument declared as String[] which is an arrayof words or strings separated by spaces. This can be used to pick up command linearguments from the system. For example the command line

$java Runit one two

would provide ”one” for args[0] and ”two” for args[1]. Such words can be used to controlthe main method at run time.

Instances of the classes Electron and Photon are declared and created by

Electron el1 = new Electron(55.4); // create electron

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 22

The word new creates the instance. Electron(55.4) evokes the constructor for the classElectron which initialises the wavelength to 55.4. The name of the instance of the classin this case is el1.

The method main() above uses two Math methods Math.sqrt() and Math.pow() to takethe square root and raise to a power (2 in this case). Again note all methods areencapsulated in a class which in this case is the Math class.

el1.direction[0]=0.3;

el1.direction[1]=0.2;

el1.direction[2]=Math.sqrt(1.0-Math.pow(el1.direction[0],2)-

Math.pow(el1.direction[1],2));

The fields within classes are referenced using the same syntax as for methods, the instancename followed by dot and field name. These are the Java equivalent of variables.

The method println is evoked for the two instances of Photon and Electron, el1 and ph1.Again “encapsulation”, “polymorphism” and “inheritance” are at work. The methodprintln is “encapsulated” in both el1 and ph1 the particles created. In both casesprintln has inherited code from the superclass ElementaryParticle. Yet println performsdifferently for electrons and photons. This is Object-Oriented Programming!

Three methods for putting comments into Java code are available

/** blar blar */ This can be picked up by the tool javadoc.

/* blar blar */ This can extend over many lines.

// blar blar This lasts until the end of the current line.

The /** form is designed to provide self documentation of classes and should be used justbefore the beginning of a class declaration to describe the class and its intended use. The/* form can be used for long comments explanations and the // form for short notes.Always include comments to explain what is going on in the code especially if you arehaving to think hard about what it is you are writing.

9.1 Task - class Proton

Edit your First.java file to include the declaration of a new subclass for the Proton andcreate an instance of a Proton in the program First. At the same time you should addsome comments to the code to describe what is going on. Make sure you know thefollowing before you proceed to the next stage:

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 23

• How classes are declared.

• How curly braces {} are used to define the scope of classes, methods etc..

• How classes are extended to declare sub-classes.

• How methods (like println()) are declared and how polymorphism can arise.

• The declaration and purpose of a constructor for a class.

Task 2 completed on: demonstrator:

10 Expressions, control and exceptions

Although everything in Java is wrapped up in classes methods are written using a syntaxvery similar to C which in turn includes all of the important statement forms of Fortran90. Our Second program includes examples of the commonly used statements. In order tocode our chosen problem we need to perform vector arithmetic and vector manipulationso our Second program declares a Vector class and Particle class to do this.

The Vector class is:

/** 3 component vector manipulation and arithmetic */

class Vector

{

public double[] cmpts =new double[3];

Vector(double x, double y, double z)

{

cmpts[0]=x;

cmpts[1]=y;

cmpts[2]=z;

}

Vector()

{

cmpts[0]=0.0;

cmpts[1]=0.0;

cmpts[2]=0.0;

}

public Vector add(Vector a)

{

/* add vectors */

Vector r = new Vector();

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 24

for(int i=0; i<3; i++)

{

r.cmpts[i]=cmpts[i]+a.cmpts[i];

}

return r;

}

public Vector subtract(Vector a)

{

/* subtract vectors */

Vector r = new Vector();

for(int i=0; i<3; i++)

{

r.cmpts[i]=cmpts[i]-a.cmpts[i];

}

return r;

}

public Vector scale(double a)

{

/* multiply by scalar */

Vector r = new Vector();

for(int i=0; i<3; i++)

{

r.cmpts[i]=cmpts[i]*a;

}

return r;

}

public double dot(Vector a)

{

/* dot product */

double r = 0.0;

for(int i=0; i<3; i++)

{

r=r+cmpts[i]*a.cmpts[i];

}

return r;

}

public Vector normalise()

{

/* normalise to direction cosines */

double sums = this.dot(this);

Vector r = new Vector();

if(sums!=0.0)

{

r=this.scale(1.0/Math.sqrt(sums));

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 25

return r;

}

else

{

throw new RuntimeException(

"Attempt to normalise null vector");

}

}

public Vector cross(Vector a)

{

/* cross product */

Vector r = new Vector();

r.cmpts[0]=cmpts[1]*a.cmpts[2]-cmpts[2]*a.cmpts[1];

r.cmpts[1]=cmpts[2]*a.cmpts[0]-cmpts[0]*a.cmpts[2];

r.cmpts[2]=cmpts[0]*a.cmpts[1]-cmpts[1]*a.cmpts[0];

return r;

}

public void print()

{

System.out.print(cmpts[0]+","+cmpts[1]+","+cmpts[2]);

}

public void println()

{

System.out.println(cmpts[0]+","+cmpts[1]+","+cmpts[2]);

}

}

The Particle class is:

/** Simple representation of a particle as a ray */

public class Particle

{

public Vector position;

public Vector direction;

public double energy;

Particle(Vector pos, Vector dir)

{

position=pos;

direction=dir.normalise();

energy=1.0;

}

public void println()

{

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 26

System.out.println("Particle");

System.out.print(" position ");

position.print();

System.out.print(" direction ");

direction.print();

System.out.println(" energy "+energy);

}

}

The program Second then uses the Vector and Particle classes.

/** Second Java Program */

class Second

{

public static void main(String[] args)

{

System.out.println("Running Second program");

// Create vectors and particles

Vector v1 = new Vector(1.0,2.0,3.0);

Vector u1 = new Vector(2.0,3.0,4.0);

Particle r1 = new Particle(v1,u1);

Vector v2 = new Vector(1.5,2.5,3.5);

Vector u2 = new Vector(-2.1,8.1,4.1);

Particle r2 = new Particle(v2,u2);

// Do some vector arithmetic

Vector sum = v1.add(v2);

Vector sub = v1.subtract(v2);

double dot = r1.direction.dot(r2.direction);

Vector cross = r1.position.cross(r2.position);

double mag1 = Math.sqrt(r1.direction.dot(r1.direction));

double mag2 = Math.sqrt(r2.position.dot(r2.position));

// List result of vector addition

v1.print();

System.out.print(" add ");

v2.print();

System.out.print(" = ");

sum.println();

// List result of vector subtraction

v1.print();

System.out.print(" subtract ");

v2.print();

System.out.print(" = ");

sub.println();

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 27

// List result of dot product

r1.direction.print();

System.out.print(" dot ");

r2.direction.print();

System.out.println(" = "+dot);

// List result of cross product

r1.position.print();

System.out.print(" cross ");

r2.position.print();

System.out.print(" = ");

cross.println();

// List calculated vector magnitudes

System.out.println("magnitude of direction particle 1 = "+mag1);

System.out.println("magnitude of position particle 2 = "+mag2);

}

}

10.1 Task - application Second

Type the Vector and Particle classes into separate files Vector.java and Particle.javaand compile them using javac. Then type the class Second program into a file calledSecond.java and compile and run it in the same way as before. Note that if you are goingto use classes (like Vector and Particle) in subsequent programs it is best to put the sourcefor each class in a separate file called <classname>.java The results should look like:

spectre$ javac Second.java

spectre$ java Second

Running Second program

1,2,3 add 1.5,2.5,3.5 = 2.5,4.5,6.5

1,2,3 subtract 1.5,2.5,3.5 = -0.5,-0.5,-0.5

0.371391,0.557086,0.742781 dot -0.225364,0.869261,0.439996 = 0.727376

1,2,3 cross 1.5,2.5,3.5 = -0.5,1,-0.5

magnitude of direction particle 1 = 1.0

magnitude of position particle 2 = 4.55522

spectre$

It should be noted that the Java API contains a class Vector. However this API class is adynamically growable array and does not perform the operations usually associated witha vector in mathematics.

Task 3 completed on: demonstrator:

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 28

11 A walk through the Second program

To start with take a look at the class Second which contains the main program thatdemonstrates the vector arithmetic.

The first section creates the Vector objects v1, u1, v2 and u2. The first constructor forthe Vector class has three double arguments which are the components of the vector. AParticle consists of two vectors which define the origin of the ray and its direction andtherefore the constructor takes two Vector arguments. So we have lines like

Particle r1 = new Particle(v1,u1);

As before the lefthand side of the assignment declares an object called r1 of type Particle.The righthand side including the word new actually creates the object. The componentswhich make up the ray are passed as arguments to the constructor of the class Particle.

The next section performs some vector arithmetic. Note that all the methods are evokedusing the variable name. The field or method we require is encapsulated within a classso the dot syntax is used to find the correct component. For example the dot product oftwo vectors is evoked in the line

double dot = r1.direction.dot(r2.direction);

The first vector in the dot product is the field r1.direction and the second vector isr2.direction. The method is evoked as r1.direction.dot(). This will seem strange at firstbut it is the essence of Object-Oriented programming style. Methods that do things arealways evoked using the name of some data object. There is an intimate relationshipbetween the actions and the data. In this particular case the result, which must be ascalar, is returned as a double by the method concerned.

The rest of the Second program lists the results. Notice that the calculated value of themagnitude of the direction of r1 is listed as 1 but the direction of the Particle variable r1was created as

Vector u1 = new Vector(2.0,3.0,4.0);

The direction of a Particle is always normalised so that the components represent thedirection cosines and the direction vector is always a unit vector. This normalisationtakes place automatically in the constructor of the Particle class. Take a look at thedefinition of class Particle. It contains the constructor definition

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 29

Particle(Vector pos, Vector dir)

{

position=pos;

direction=dir.normalise();

}

The normalise method is evoked for the direction everytime we create an instance of aParticle object.

The Vector class has two constuctors. The first with three double arguments and thesecond with no arguments. When Java decides which constructor or method to use itchecks the name AND the list of arguments to make sure that they match. In this casea Vector can be created either from three double components or no components. In thelatter case the components are automatically set to 0.0. This form of the constuctor is usedin the method definitions within the Vector class. Using different forms of constructor fora class to provide different levels of default behaviour is a very common device in Javacode.

We can now turn our attention to the code within the methods which perform the vectorarithmetic. These are all declared within the class Vector. The methods add, subtract,scale and dot all contain definite loops. For example the dot product contains

for(int i=0; i<3; i++)

{

r=r+cmpts[i]*a.cmpts[i];

}

This is the equivalent of a Fortran do loop. The loop counter is declared as integer andinitialized to zero by int i=0; and the test for the continuation of the loop is i<3;. Finallythe increment to be applied on each pass is given by i++. Because the ++ is after the ithe increment of 1 will be applied after the i has been used in the loop. So the loop willbe executed for 3 passes with i=0,1,2 which picks out all the components of the vector.The lines executed in the loop are enclosed in {}. Actually if there is only one statementexecuted as in this case these brackets are not required since they are only used to groupstatements together. Notice that cmpts[i] refers to the ith component of “this” vectorand a.cmpts[i] refers to the ith component of the argument vector a.

In each method the result is declared with the appropriate type, for example in dot wehave

double r = 0.0;

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 30

At the end of the method this is returned as the value of the method using

return r;

In the case of cross for example the result is a Vector so we have

Vector r = new Vector();

.

.

return r;

In all cases we have chosen to create a returned value rather than change the originalvector. For example scale and normalise could have performed the arithmetic andthen overwritten the original component values but for consistency and ease of use thistechnique was not adopted.

You will see that normalise includes an if-else structure and something rather strange

public Vector normalise()

{

/* normalise to direction cosines */

Vector r = new Vector();

double sums = this.dot(this);

if(sums!=0.0)

{

r=this.scale(1.0/Math.sqrt(sums));

}

else

{

throw new RuntimeException(

"Attempt to normalise null vector");

}

return r;

}

The if() {} else {} is very similar to IF-ELSE-ENDIF blocks in Fortran. The bracketsafter the if contain an expression which returns a boolean (logical) value. When this istrue the clause contained in {} immediately after the if() will be executed. If false the else{} clause will be executed. In the above case there is a problem if the sum of the squares

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 31

of the vector elements (calculated using the dot product) is zero. It is then impossibleto normalise the length of the vector to unity and we must “throw an exception”. Inthis case the exception avoids division by zero. After an exception is “thrown” it can be“caught” by some other code which may deal with the problem. The RuntimeExceptionclass thrown is ubiquitous and will automatically be caught by the system.

In more complicated circumstances you may want to catch the exception yourself andtake remedial action. This will be described in more detail later.

11.1 Task - class Vector

Read through all the methods in class Vector to make sure you understand how theywork. How would you use them to:

• Calculate the angle between two vectors.

• Calculate a unit vector perpendicular to the plane defined by two vectors.

• Calculate the distance between two position vectors.

• Calculate the direction (unit vector) between two position vectors.

Modify Second.java so that it attempts to normalize a null vector to see what effect theexception has.

Task 4 completed on: demonstrator:

11.2 Task - scope, this and super

Look at how the word “this” is used to refer to the name of the current class/object and“super” is used to refer to the parent class. The way in which data fields (variables) canbe declared and used within different scopes can be confusing. What is the output fromthe following code? In the clause

while (logical) { code };

the code within the scope of the while will be executed repeatedly until the logical returnsfalse. The code will not be executed at all if the logical is false at the start of the firstpass.

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 32

Type the program into the file Var.java and run it to see if you are right.

class MyClass

{

int var; // field in MyClass (1st var)

MyClass(int var) // 2nd var not the same as MyClass.var

{

this.var =var; // makes the two var’s equal

}

}

class MySecondClass extends MyClass

{

int var=1; // 3rd var different from super.var

MySecondClass(int var) // 4th var not this.var

{

super(var);

}

void mymethod()

{

while (var<10)

{

int var =5; // 5th var within scope of while only

this.var++;

System.out.println(var+" "+this.var+" "+super.var);

}

}

}

class Var

{

public static void main(String[] args)

{

MySecondClass a = new MySecondClass(9);

a.mymethod();

}

}

You can avoid such confusion by sensible choice of field names.

Task 5 completed on: demonstrator:

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 33

12 Abstract classes and interfaces

It is often the case that when you start programming in OOP the top level classes likeParticle above are difficult to define in detail. They may declare a general structurebut must lack details of the implementation. For example we will now try and set updeclarations for another part of our tracing problem, the surface elements. We know thatall surfaces will be defined by certain fields. However at the moment we have no ideaabout the details of how we are going to find the intersection point of a particle path(ray) with a particular surface, a sphere say. In fact we know that this calculation islikely to be very different depending on the type of surface concerned.

Each surface will be defined using some reference datum consisting of a position vector,the surface normal at that position and a reference axis tangential to the surface at thatposition. The third reference axis can always be generated from the other two using thecross product. If we take the reference position, presumed to be actually on the surface,then we can always define some local 2-dimensional coordinate system to describe positionson the surface with an origin at the reference position. The edge or boundaries of thesurface can then be described by some line or lines in this local coordinate system. Thisis illustrated in figure 1. Note that in general the surface may be curved and that the

refpos

3rd axis

boundary

local coordinate grid on surface

refnorm

refaxis

Figure 1: Definition of a surface

normal to the surface at some arbitary position is not necessarily parallel to the referencenormal.

We will start with the boundaries in local surface coordinates. These may be rectangular,

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 34

circular or some other fancy shape. In the ray-particle tracing we shall want to knowwhether or not an intersection point with some surface shape is inside or outside thesurface boundary. It will also be useful to generate random positions on the surfacewithin the boundary for creating particles. We can define an abstract entity in Javaknown as an interface.

/** General boundary on a 2-d surface */

interface Bounds

{

boolean within(double[] coord); // intersection within surface limits?

double[] ranpos(); // random position within limits

void setseed(long seed); // set seed of random number generator

void println(); // list details of boundary

}

An interface behaves like a class in many ways but you can’t have an instance of aninterface, it is a purely abstract thing. An interface can only contain implicitly abstractmethods. That is methods which have no specified implementation. They can also containstatic final fields, that is universal constants. An interface can be “implemented” in aclass. For example here follows two possible boundary definitions in the form of classes:

import java.util.Random

/** Rectangular boundary on a 2-d surface */

class Rectbound implements Bounds

{

public double xmin; // minimum value along reference axis

public double xmax; // maximum value along reference axis

public double ymin; // minimum value perpendicular to reference axis

public double ymax; // maximum value perpendicular to reference axis

public Random ran = new Random();

Rectbound(double x1, double x2, double y1, double y2)

{

xmin=x1;

xmax=x2;

ymin=y1;

ymax=y2;

}

public boolean within(double[] coord)

{

return (coord[0]>xmin && coord[0]<xmax && coord[1]>ymin &&

coord[1]<ymax);

}

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 35

public double[] ranpos()

{

double[] pos=new double[2];

pos[0]=ran.nextDouble()*(xmax-xmin)+xmin;

pos[1]=ran.nextDouble()*(ymax-ymin)+ymin;

return pos;

}

public void setseed(long seed)

{

ran.setSeed(seed);

}

public void println()

{

System.out.println("Rectangular boundary");

System.out.print(" x-range "+xmin+","+xmax);

System.out.println(" y-range "+ymin+","+ymax);

}

}

/** Circular boundary on a 2-d surface */

class Circbound implements Bounds

{

public double rads; // square of radius

public Random ran = new Random();

Circbound(double r)

{

rads=r*r;

}

public boolean within(double[] coord)

{

return (coord[0]*coord[0]+coord[1]*coord[1])<rads;

}

public double[] ranpos()

{

double[] pos=new double[2];

double r=Math.sqrt(rads);

do

{

pos[0]=ran.nextDouble()*r*2-r;

pos[1]=ran.nextDouble()*r*2-r;

}

while( (pos[0]*pos[0]+pos[1]*pos[1]) >= rads);

return pos;

}

public void setseed(long seed)

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 36

{

ran.setSeed(seed);

}

public void println()

{

System.out.println("Circular boundary");

System.out.println(" radius "+Math.sqrt(rads));

}

}

Notice the first line of each class declaration states that the class implements the Boundsinterface. Therefore each class contains definitions of the methods declared in the Boundsinterface. Study these class definitons carefully and make sure you understand how theywork. The && operator performs a logical AND and Random is a class in Java’s utilitieswhich provides sequences of random numbers. Having created an instance of the Randomclass (called ran in the above code) then each member of the random sequence can bereturned using ran.nextDouble() which is in the range 0.0 to 1.0 by default. The construct

do { code } while (logical);

is a loop which will repeat code until the logical is false. Note this form of indefinite loopalways executes the code at least once.

When a class implements an interface it generally provides a definition for ALL themethods declared in the interface. If it doesn’t then the implementing class must bedeclared abstract.

Interfaces can be extended in the same way as classes except they can extend more thanone interface. This is called multiple inheritance. Java does not allow multiple inheritanceof classes so a class can only extend one superclass. However a class can implement morethan one interface. So the use of interfaces is the way in which Java incorporates multipleinheritance.

An interface is purely abstract and as such it forms no more than a sort of contract. Anyclass which references an interface enters into that contract. We will now consider thedefinition of a Surface class:

/** General surface geometry*/

abstract class Surface

{

public Vector refpos; // reference position on surface (origin)

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 37

public Vector refnorm; // reference normal at origin

public Vector refaxis; // reference axis at origin

public Vector intpos =new Vector(0.0,0.0,0.0); // intersection position

public double intdist=0.0; // intersection distance (along ray)

public double[] intcoord={0.0,0.0}; // intersection coordinates

Bounds edge; // Boundary class

Surface(Vector pos, Vector norm, Vector axis, Bounds bds)

{

refpos=pos;

refnorm=norm.normalise();

refaxis=axis.normalise();

edge=bds;

}

public void println()

{

System.out.print(" pos ");

refpos.print();

System.out.print(" norm ");

refnorm.println();

System.out.print(" axis ");

refaxis.println();

edge.println();

}

abstract protected void ptoc(); // position to coordinates

abstract protected void ctop(); // coordinates to position

abstract protected boolean intersect(Particle p); // Find intersection

abstract protected Vector getran(); // get random position vector

}

Note that this is declared as abstract. This is because it the definition of four abstractmethods, ptoc(), ctop(), intersect(Particle p) and getran(). The word protected meansthese methods can only be accessed from within classes that extend the class. In otherwords they are meant to be implemented only from within such classes. The methodptoc() is expected to convert from a position on the surface expressed as a 3-componentvector to a 2-d coordinate pair in the local surface coordinate system (the dashed grid onfigure 1). ctop() should convert from a 2-d coordinate pair to a 3-component vector. Themethod intersect(Particle p) finds the intersection position vector of a particle (ray) withthe surface and getran() gets a random position vector within the boundary set. Noneof these methods has an implementation (executable statements) and so an instance ofa surface cannot be created. In the class Surface we have no idea how the methods inBounds or the methods declared abstract are going to work. We must extend Surface byfurther class definitions to specify “real” surfaces that can have an instance. However theneat thing is that all such surfaces will inherit the fields and methods declared in Surface.

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 38

Here is an example of the definition of a Plane surface class.

/** Plane surface */

class Plane extends Surface

{

Plane(Vector pos, Vector norm, Vector axis, Bounds bds)

{

super(pos,norm,axis,bds);

}

protected void ptoc()

{

// Find y reference axis in plane

Vector yaxis=refnorm.cross(refaxis);

// Vector from origin on plane to intersection

Vector vp=intpos.subtract(refpos);

// Calculate local x and y

intcoord[0]=vp.dot(refaxis);

intcoord[1]=vp.dot(yaxis);

}

protected void ctop()

{

// Find y reference axis in plane

Vector yaxis=refnorm.cross(refaxis);

// Vector from origin on plane to intersection

Vector vp=refaxis.scale(intcoord[0]);

vp=vp.add(yaxis.scale(intcoord[1]));

// Find position of intersection

intpos=refpos.add(vp);

}

protected boolean intersect(Particle p)

{

// Check energy of particle

if(p.energy==0.0)

return false;

// Cos of angle between plane normal and particle direction

double a = refnorm.dot(p.direction);

if(a==0.0)

{

// Particle parallel with surface, no intersection

return false;

}

else

{

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 39

// Distance and direction to point on plane

Vector dr=refpos.subtract(p.position);

double s=dr.dot(dr);

s=Math.sqrt(s);

dr=dr.normalise();

// Cos of angle between line to point on plane and norm

double g=refnorm.dot(dr);

// Find intersection on plane

intpos=p.position.add(p.direction.scale(s*g/a));

// Calculate distance along ray to plane

Vector rr=intpos.subtract(p.position);

intdist=rr.dot(rr);

intdist=Math.sqrt(intdist);

// Calculate local x and y

ptoc();

// Check within limits

return edge.within(intcoord);

}

}

public Vector getran()

{

intcoord=edge.ranpos();

ctop();

return intpos;

}

public void println()

{

System.out.println("Planar surface");

super.println();

}

}

Note that the constructor includes an argument of type Bounds. This is assigned tothe instance edge and subsequently the within() method from the Bounds interface isreferenced using edge.within(intcoord). Any instance of Plane will be constructed usinga class that implements Bounds. It is then that the contract set by the Bounds interfaceis honoured. At last all the abstract methods in Bounds and Surface will have animplementation.

Figure 2 illustrates the vector arithmetic implemented in the intersect() method to findwhere a particle hits a plane.

We can now write a class Third to exercise the class Surface.

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 40

refpos

refnorm

p.position

intpos

p.direction

drdistance s

distance s*g

a=cos

g=cos γ

α

intdist=s*g/a

α

γ

Figure 2: Intersection of a particle with a plane surface

/** Third Java Program */

class Third

{

public static void main(String[] args)

{

System.out.println("Running Third program");

Vector org = new Vector(2.0,2.0,3.0);

Vector dir = new Vector(1.0,0.0,0.0);

Particle p1 = new Particle(org,dir);

Rectbound rec = new Rectbound(-1,2,-3,6);

Circbound cir = new Circbound(3.0);

Vector pos = new Vector(1.5,2.5,3.5);

Vector norm = new Vector(1.0,0.0,0.0);

Vector axis = new Vector(0.0,1.0,0.0);

Plane s1 = new Plane(pos,norm,axis,rec);

Plane s2 = new Plane(pos,norm,axis,cir);

boolean hit1 = s1.intersect(p1);

boolean hit2 = s2.intersect(p1);

p1.println();

s1.println();

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 41

s2.println();

if(hit1)

{

System.out.println("intersection");

System.out.print(" position ");

s1.intpos.println();

System.out.println(" distance "+s1.intdist);

System.out.println(" coordinates "+s1.intcoord[0]+

","+s1.intcoord[1]);

}

if(hit2)

{

Vector rr=new Vector(0.0,0.0,0.0);

System.out.println("random positions in circle");

for(int i=0;i<10;i++)

{

rr=s2.getran();

System.out.print(" ");

rr.println();

}

}

}

}

12.1 Task - application Third

Type the Third program in and try it out. To save typing you can copy the Bounds,Rectbound, Circbound, Surface and Plane source code from

/disk/s/zrw/under/java/Bounds.java

/disk/s/zrw/under/java/Rectbound.java

/disk/s/zrw/under/java/Circbound.java

/disk/s/zrw/under/java/Surface.java

/disk/s/zrw/under/java/Plane.java

You will need to compile Bounds.java, Rectbound.java, Circbound.java, Surface.java andPlane.java after you have copied them. The results should look like:

spectre$ java Third

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 42

Running Third program

Particle

position 2.0,2.0,3.0 direction 1.0,0.0,0.0 energy 1.0

Planar surface

pos 1.5,2.5,3.5 norm 1.0,0.0,0.0

axis 0.0,1.0,0.0

Rectangular boundary

x-range -1.0,2.0 y-range -3.0,6.0

Planar surface

pos 1.5,2.5,3.5 norm 1.0,0.0,0.0

axis 0.0,1.0,0.0

Circular boundary

radius 3.0

intersection

position 1.5,2.0,3.0

distance 0.5

coordinates -0.5,-0.5

random positions in circle

1.5,2.31694,1.84626

1.5,3.28978,4.23799

1.5,1.3789,3.95061

1.5,2.11345,3.55555

1.5,1.6541,1.16536

1.5,3.89111,4.2566

1.5,0.391311,5.61832

1.5,4.88745,3.4916

1.5,0.624179,2.51002

1.5,2.30628,2.37661

You should now get an inkling of the power of Object-oriented syntax. All the effortput into designing the class and interface structure begins to pay off when you startto construct more complicated programs. You can create any number of objects thatimplement Bounds as in the lines

Rectbound rec = new Rectbound(-1,2,-3,6);

Circbound cir = new Circbound(3.0);

Each instance, rec and cir above, has its own copy of the fields and has access to animplementation of the methods in Bounds. Similarly the lines

Plane s1 = new Plane(pos,norm,axis,rec);

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 43

Plane s2 = new Plane(pos,norm,axis,cir);

create instances of the Surface class. These in turn can be passed as arguments wheneveran instance of the Surface class is required. We can implement many forms of Bounds andSurface and they will all behave in exactly the same way, sharing code and data wheneverpossible. Remember the instance names, like “s1” and “s2” above, encapsulate both thefields (data) and methods (procedures) so that providing we know what is encapsulatedand we understand the arguments required then it is almost guaranteed that the methodswill work correctly.

Problems can arise. Suppose you were presented with the class third without being toldwhat the classes Vector, Particle, Surface and so on, did. Then things would not be sotransparent. Object-Oriented code can be neat, reliable but incomprehensible. When youdesign a class structure to solve some problem you should spare a thought for programmerswho might want to use or extend it.

Task 6 completed on: demonstrator:

12.2 Task - class Annulabound

Create a file Annulabound.java defining a new class of boundary called Annulaboundwhich descibes an annulus on the surface. This will require an inner and outer radius. Atthe same time modify the Third.java class to test out your new boundary class.

Task 7 completed on: demonstrator:

13 Graphics

One of the main reasons Java has been so successful (so far) is that it was designed foruse with Graphics on the Internet. In fact the first releases were incorporated into theNetscape and HotJava World Wide Web browsers.

The classes, interfaces and associated methods which provide the functionality requiredfor graphics and many other higher level tasks constitute what is known as the JavaApplication Programming Interface or Java API. The particular part of the API we shallconcentrate on is the Abstract Window Toolkit or AWT. We shall also touch on the relatedapplet package. An applet is a program written in Java to run within a Java-compatibleweb browser such at Netscape or HotJava.

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 44

If we can plot out results from the ray tracing we shall be able to check and develop thecode more quickly. The following Fourth class and associated classes provides a simple testof the Surface class developed in the Third program. The Java API provides classes whichcan plot graphics, images, text and so on in windows. To start with we shall be using theAWT class Canvas. This is a simple way of providing a blank window component whichcan be used for plotting graphs etc.. Unfortunately all the graphics methods provided inthe API are based on pixelated graphics system in which the coordinates are integer pixelpositions. It is more natural for physicists to work with real variables so I’ve written asimple class Figure with extends Canvas and provides plotting utilites that look a bit likePGPLOT that you used in the Fortran 90 workshops. You don’t need to know the detailsof the inner workings of class Figure but you do need to know the public methods whichit provides.

public class Figure extends Canvas

{

// the constructor is the same as for Canvas

Figure()

// set the Canvas to uniform background colour

public void clear()

// set the current plotting colour

public void setColor(Color c)

// set the plotting window on the canvas.

// The default is 0.1 to 0.9 in both axes, leaving room for annotation

// around the edge. Position 0.0,0.0 is the bottom left.

public void setWindow(double xlo, double xhi, double, ylo, double yhi)

// define the real variable space of the plotting window.

// The origin is in the bottom left with x increasing to the right and y

// increasing up the screen. mtype is used to define the type of mapping

// "lin" for linear, "xlog" for x logarithmic y linear, "ylog" for

// x linear y logarithmic and "xylog" for both axes logarithmic.

// "scale" for linear with the same scaling for both axes.

public void mapping(String mtype, double xlo, double xhi, double ylo,

double yhi)

// draw an ellipse top left at x,y of given width and height.

public void drawOval(double x, double y, double width, double height)

// draw a filled rectangle top left at x,y of given width and height.

public void drawRect(double x, double y, double width, double height)

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 45

// draw a line from x1,y1 to x2,y2

public void drawLine(double x1, double y1, double x2, double y2)

// draw lines joining n x[] and y[] points to approximate a curve

public void drawCurve(int n, double[] x, double[] y)

// draw closed polygon joining n x[] and y[] points

public void drawPolygon(int n, double[] x, double[] y)

// draw a line histogram for n points x[] and y[]

public void drawHistogram(int n, double[] x, double[] y)

// draw a box around mapped surface within Canvas window

public void box()

// set the current pixel position

public void setPixelPos(double x, double y)

// get the current pixel position

public double[] getPixelPos()

// get next pixel position in raster. The raster starts at the top

// left hand corner. When the bottom right hand corner is reached the

// raster is complete, false is returned and the current pixel position is

// reset to the start of the next raster.

public boolean nextPixelPos()

// draw the pixel at the current pixel position using current

// drawing colour.

public void drawPixel()

}

In order to produce a graph or picture you must extend the Figure class and writea method called paint(). This is illustrated in the following Picture and Graph classdefinitions.

class Picture extends Figure

{

public void paint(Graphics g)

{

double xmin=-3.0;

double xmax=9.0;

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 46

double ymin=-3.0;

double ymax=9.0;

mapping("lin",xmin,xmax,ymin,ymax);

Rectbound rec = new Rectbound(-1,2,-3,6);

Circbound cir = new Circbound(3.0);

rec.ran.setSeed(1111);

cir.ran.setSeed(2222);

Vector pos = new Vector(1.5,2.5,3.5);

Vector norm = new Vector(0.0,0.0,1.0);

Vector axis = new Vector(1.0,0.0,0.0);

Plane s1 = new Plane(pos,norm,axis,rec);

Plane s2 = new Plane(pos,norm,axis,cir);

Vector rr=new Vector(0.0,0.0,0.0);

setColor(Color.red);

for(int i=0;i<1000;i++)

{

rr=s1.getran();

drawOval(rr.cmpts[0],rr.cmpts[1],0.0,0.0);

}

setColor(Color.green);

for(int i=0;i<1000;i++)

{

rr=s2.getran();

drawOval(rr.cmpts[0],rr.cmpts[1],0.0,0.0);

}

setColor(Color.blue);

drawLine(xmin,2.5,xmax,2.5);

drawLine(1.5,ymin,1.5,ymax);

setColor(Color.black);

box();

}

}

class Graph extends Figure

{

public void paint(Graphics g)

{

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 47

double xmin=-3.0;

double xmax=9.0;

double ymin=-3.0;

double ymax=9.0;

mapping("lin",xmin,xmax,ymin,ymax);

setColor(Color.green);

drawOval(1.5,2.5,6.0,6.0);

Rectbound rec = new Rectbound(-1,2,-3,6);

double[] x = new double[4];

double[] y = new double[4];

x[0]=0.5;

y[0]=-0.5;

x[1]=3.5;

y[1]=-0.5;

x[2]=3.5;

y[2]=8.5;

x[3]=0.5;

y[3]=8.5;

setColor(Color.red);

drawPolygon(5,x,y);

setColor(Color.blue);

drawLine(xmin,2.5,xmax,2.5);

drawLine(1.5,ymin,1.5,ymax);

setColor(Color.black);

box();

}

}

In order to display these plots you need to create an instance of the class Frame and thenadd the Figure components to the Frame. The following class Fourth does this.

import java.awt.*;

public class Fourth extends Frame

{

public Fourth(String title)

{

super(title);

}

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 48

public static void main(String args[])

/* main method to execute Fourth as an application */

{

System.out.println("Fourth start");

Fourth app=new Fourth("Fourth Java");

app.setSize(600,300);

Picture picture = new Picture();

Graph graph = new Graph();

GridLayout gridlay = new GridLayout(1,2);

app.setLayout(gridlay);

app.add(picture);

app.add(graph);

app.show();

System.out.println("Fourth stop");

}

}

The line

import java.awt.*;

makes available all the necessary classes in the AWT package.

The constructor for class Fourth simply puts a title at the top of the displayed window.The main() method is the program which java will execute. The program starts bycreating an instance of Fourth (extended from Frame) and then sets it’s size (in pixels)

Fourth app=new Fourth("Fourth Java");

app.setSize(600,300);

It may seem strange that the main() method has to create an instance of Fourth sincemain() is encapsulated in the class Fourth. However a method can be called without aninstance of the encapsulating class being present although it is usually the case that suchan instance exists. Next we must create instances of Picture and Graph.

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 49

Picture picture = new Picture();

Graph graph = new Graph();

The instance of the class gridLayout is used to specify how the Figures are to be packedinto the Frame. (1,2) means 1 row, 2 columns.

GridLayout gridlay = new GridLayout(1,2);

The following lines set up the grid layout and add the Figures to the Frame.

app.setLayout(gridlay);

app.add(picture);

app.add(graph);

app.show();

Note all these methods are encapsulated in app which is the name of the instance of theFourth (Frame).

13.1 Task - application Fourth

Study Graph and Picture to see how they use the methods defined in the class Figure.You don’t need to worry about the details of how the methods in Figure work. Figure,in turn, uses the plotting methods provided by the AWT in the class java.awt.Graphics.Copy classes Figure, Picture and Graph from

/disk/s/zrw/under/java/Figure.java

/disk/s/zrw/under/java/Picture.java

/disk/s/zrw/under/java/Graph.java

Type the class Fourth into the file Fourth.java and try it out. You will need to compileFigure.java, Picture.java and Graph.java as well. When you want to remove the graphicswindow produced use the winops kill option.

Task 8 completed on: demonstrator:

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 50

14 Applets

If you wish to display graphics using Java from a World Wide Web (WWW) browser or,indeed, use Java for programming WWW applications, you must use a different form ofJava program, the applet. The java.applet package contains the Applet class which is anextension of the java.awt.Panel class. A Panel is like the java.awt.Frame we used in theFourth class above. It is a container in which we can display graphical components. Hereis an applet version of the Fourth program above.

import java.awt.*;

import java.applet.Applet;

public class Fifth extends Applet

{

GridLayout gridlay = new GridLayout(1,2);

Picture picture;

Graph graph;

public void init()

{

System.out.println("Fifth.init");

picture=new Picture();

graph=new Graph();

setLayout(gridlay);

add(picture);

add(graph);

}

public void destroy()

{

System.out.println("Fifth.destroy");

}

}

The line at the top

import java.applet.Applet;

is required to make the Applet class available. The Fifth class defined extends the Appletclass and includes just two methods, init() and destroy(). There is now no main() method.

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 51

The code which creates the instance of the Fifth (Applet extension of panel) class is insidethe WWW browser or viewing program. The init() method is evoked by the drivingprogram just after the applet Panel is created and the destroy() method is evoked toclean up just before the applet is completed. In the init() method the Panel methodssetLayout() and add() don’t require a prefix since they refer to this instance of the class(which has already been created). This is different from the main() method in the Fourthapplication in which the instance of the Fourth class was created as app within the main()method itself. If you are using threads (a thread is a sequence of steps a bit like a miniprogram) then there are three other methods that can be included in the Applet class tocontrol what is going on, start(), run() and stop(). This will be discussed later.

You cannot use the java interpreter to run the applet since there is no main() method.Instead you must write an HTML (Hyper Text Markup Language) file to run the applet.The minimum required is something like

<title>Fifth Java</title>

<hr>

<applet code="Fifth.class" width=600 height=300>

</applet>

<hr>

The <title> tag defines the text which will appear at the top of the browser window. <hr>draws a horizontal line across the browser page so that you can see the area occupiedby the applet Panel. The width and height parameters specifiy the size of the Panel inpixels.

14.1 Task - applet Fifth

Type the applet code into a file called Fifth.java and compile it with javac in the usual way.Then type the HTML code into a file called Fifth.html. You can run the program eitherby opening the HTML file from within the netscape browser or by using the appletviewerutility

spectre$ appletviewer Fifth.html

The viewer is useful because it logs on your screen the files it is opening so you can seehow the java program is executed. When the applet is up and running you can control itusing the pull-down menu available in the top left of the screen. Use the quit commandto return to the normal shell prompt.

Task 9 completed on: demonstrator:

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 52

15 Writing your own Java Program

It is now time for you to try and write a Java program (with a little help). We are goingto look at a programming task which is nothing to do with ray tracing so that you startto get a feel for how you can approach different problems using OOP. The idea is to plota picture of a complex set, for example a Julia set or the Mandelbrot set.

First of all we need to define what such a set is! A complex set is a set of points (usually aninfinite number of points) on the complex plane (i.e. in an Argand diagram). Associatedwith a complex set is some formula which is used to decide whether or not a point onthe complex plane (i.e. a complex number) is in the set. The most interesting complexsets are produced by some iterative formula and are fractal in nature. You don’t need toknow this but the Mandelbrot set is a set of Julia Sets.

A picture or rendering of such a set can be produced by using the appropriate formulaover a raster or grid of points that cover some portion of the complex plane. If a point isfound to be in the set then we colour the pixel at that point black and if it is not in theset we colour the pixel at that point white. The character and accuracy of the renderingdepends on the formula used to define membership of the set.

So where do we start with OOP?What we probably need is a class that defines a particulartype of complex set, a class to render (plot) a complex set and finally an applicatonclass, with a main() method, which creates an instance of the set and an instance of therendering. The essence of any rendering of a complex set is a procedure (or method sincewe are using Java) which determines whether a complex number z is in the set or not. Sowe can start by defining an interface that declares a method of the form

boolean inset(double[] z)

This is expected to return true if the complex number z is in the set and false if not inthe set.

15.1 Task - interface ComplexSet

Create an interface called ComplexSet (in a file called ComplexSet.java) which declaressuch a method. Also declare a void println() method which is intended to list details ofthe complex set. You can use the interface Bounds above as the model for this interface.

The ComplexSet interface is intended to be implemented by any class which defines acomplex set. The purpose of the interface is to force the programmer to provide exactly

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 53

the same form of methods for every set coded. It also means that the programmercan write and compile code which uses the methods declared in the interface before theinterface has been implemented.

Task 10 completed on: demonstrator:

15.2 Task - class Mandelbrot

Next we need a formula which defines the Mandelbrot set. The simplest is as follows.Take a complex number z=(xst,yst) where xst is the real part and yst is the imaginarypart. Then repeatedly calculate a new complex number using the formulae

xnew=xold*xold-yold*yold-xst

ynew=2*xold*yold-yst

Start with xold=xst and yold=yst and after each iteration calculate the modulus squaredof the result

r=xnew*xnew+ynew*ynew

Repeat this until

r>rescape or iteration number > maxiter

where rescape is of order 1.e8 (the square of 1.e4) and maxiter is about 100. If r is greaterthan the escape radius during iteration then the point z is not in the set, otherwise it isin the set.

Write a class Mandelbrot (in a file called Mandelbrot.java) that implements the interfaceComplexSet using the above iterative scheme. Include a constructor that allows you toset the rescape and maxiter values when you create an instance of the class. Use theprintln() method to list out the name of the set and these values. You might use the classRectbound above as a model for this class. You can use a loop of the form

for(int i=0;i<maxiter;i++)

{

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 54

...

if(r > rescape)

return false;

...

}

return true;

to perform the iteration where the if() will terminate the definite loop prematurely incases where the point has escaped.

Task 11 completed on: demonstrator:

15.3 Task - class RenderSet

Now we come to the problem of plotting out the raster of points. This can be done bya class similar to Picture or Graph above, using the methods provided by the Figureclass. The heart of the class required is the paint() method which needs to look like thefollowing.

public void paint(Graphics g)

{

setWindow(0.0,1.0,0.0,1.0);

mapping("scale",x0,x1,y0,y1);

setColor(Color.black);

box();

while(nextPixelPos())

{

if(set.inset(getPixelPos()))

{

drawPixel();

}

}

}

The setWindow() method redefines the plotting window (to the maximum in this case).The mapping() method sets up a mathematical coordinate system over the window. Inthis case this defines the area of the complex plane covered by the plot. The ”scale”option ensures that the scaling of the x-axis (real-axis) and y-axis (imaginary axis) isthe same. The setColour() and box() methods select a drawing colour and put a framearound the defined window. The method nextPixelPos() selects the next pixel in the raster

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 55

returning false if the raster is complete. The set.inset() method determines whether ornot the current pixel position (in mathematical coordinates) returned by getPixelPos(),is a member of the set or not. Finally the drawPixel() method colours the current pixel.

Write a class called RenderSet in file RenderSet.java which extends Figure and plots apicture of a complex set. The data fields in the class must include

private ComplexSet set;

and x0, x1, y0, y1 for the mapping. You should write a constructor for the class thatinitializes the set and the mapping ranges. This will look something like the constructorin the Surface class above.

Task 12 completed on: demonstrator:

15.4 Task - application Sixth

Finally we require a Sixth class with a main() method to actually plot the result. Writea Sixth class to plot a picture of the Mandelbrot set. You can use the Fourth or Fifthprograms above as a model. You should use a frame size of at least a few hundred pixelsin each axis and a mathematical coordinate range -1.0 to 2.0 and -1.5 to 1.5 for the realand imaginary axes to include the complete set. So your main() method should containlines like:

app.setSize(500,500);

Mandelbrot Cset = new Mandelbrot();

RenderSet picture = new RenderSet(Cset,-1.0,2.0,-1.5,1.5);

Task 13 completed on: demonstrator:

15.5 Task - class Julia

A Julia set is defined by a very similar iterative scheme. The only difference is that thestart position in the iteration is replaced by a complex constant cs=(cr,ci):

xnew=xold*xold-yold*yold+cr

ynew=2*xold*yold+ci

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 56

The iteration still starts with xold=xst and yold=yst.

Write a Julia class in file Julia.java which implements the ComplexSet interface. This willrequire a few trivial changes to the Mandelbrot class already written. Your constructorshould include the constant cs. Modify your Sixth.java file to plot a Julia set rather thanthe Mandelbrot set. My favourite Julia set has cs=(-0.74543,0.11301) and requires a range(-2.0,2.0,-1.5,1.5).

You will notice that the pictures you get of the complex sets are rather indistinct. Ifyou try plotting a smaller area of the complex plane at the boundary of the set greatercomplexity is revealed. In fact, however far you try to zoom in on the boundary, morecomplexity becomes apparent.

There are other properties of such sets which can be exploited to provide more revealingrenderings. In particular there is an algorithm for approximating the distance to the setfrom points which are not in the set and there is another algorithm for calculating theradius of a circle centred on points not in the set which is guaranteed not to intersect theset. Both these could be included as methods in the ComplexSet interface.

Using these other properties the renderings can be more than just black and white pictures.Sets can be rendered as pictures of 3-D surfaces of one form or another. Thus theRenderSet class could be modified/extended to produce different types of plot.

The structure imposed by OOP in Java makes enhancements and modifications like theserather easy.

Note that we could have chosen to declare ComplexSet above as an abstract class ratherthan an interface. In this particular application in makes no difference. The advantageof interfaces is that a class can implement more than one interface and an interface canextend more than one interface. i.e interfaces provide Java with multiple inheritance.

Task 14 completed on: demonstrator:

16 Surface quality in the ray tracing problem

So far we have looked at the geometry and boundaries of surfaces and the intersection ofrays or particles with the surfaces. We now need to consider the scattering, absorptionand emission from the surfaces. This depends on the surface quality.

The best way to incorporate this aspect is to modify our abstract definition of a surfaceto include surface properties. We can do this by extending the Surface class to a

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 57

new SurfaceQ class. The extended definition below includes a surface normal at theintersection point, a Squality interface which is passed to the object as a constructorargument and new methods natp(), scatter(Particle p) and emit().

/** Surface geometry and quality*/

abstract class SurfaceQ extends Surface

{

public Vector intnorm; // normal at intersection set by method natp()

// natp() will depend on surface type

Squality qual; // surface properties

SurfaceQ(Vector pos, Vector norm, Vector axis, Bounds bds, Squality sqa)

{

super(pos,norm,axis,bds);

qual=sqa;

}

public void println()

{

super.println();

qual.println();

}

abstract protected void natp(); // find normal at position

public boolean scatter(Particle p)

{

return qual.scatter(this,p);

}

public Particle emit()

{

return qual.emit(this);

}

}

The surface quality interface is given below. The scatter method has argumentsSurfaceQ and Particle since the scattering or absorption depends on both the interactingcomponents. The emit method only has a SurfaceQ argument to determine the directionof emission. The properties of particles emitted will depend on the implementation of theinterface.

/**

* surface quality responsible for scattering, absorption and emission of

* particles

*/

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 58

interface Squality

{

/** scatter or absorb particle */

boolean scatter(SurfaceQ s,Particle p);

Particle emit(SurfaceQ s); // emit particle

void println(); // list details of surface quality

}

Now we can implement the Squality interface to create a Mirror, Laser (parallel sourcebeam) and Detector class.

/** Perfect mirror surface quality */

class Mirror implements Squality

{

public boolean scatter(SurfaceQ s, Particle p)

{

// Find reflection angle at intersection position

double cosa=p.direction.dot(s.intnorm);

// In this case reflection angle equals incidence angle

double cosb=cosa;

double cosab=cosa+cosb;

// find change in direction

Vector change = s.intnorm.scale(cosab);

// apply change, normalise and overwrite original direction

Vector rdir=p.direction.subtract(change);

p.direction=rdir.normalise();

// update origin of particle

p.position=s.intpos;

return true;

}

public Particle emit(SurfaceQ s)

{

throw new RuntimeException(

"Mirror.emit: attempt to emit from a mirror surface");

}

public void println()

{

System.out.println("perfect mirror surface");

}

}

The geometry of the reflection used in the scatter() method is illustrated in figure 3.

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 59

s.intnorm

rdir

s.intnorm.scale(cosab)ab

intpos

cosab=cosa+cosbp.direction

Figure 3: Refection from a plane surface

/** Parallel beam source */

class Laser implements Squality

{

public boolean scatter(SurfaceQ s, Particle p)

{

throw new RuntimeException(

"Laser.scatter: attempt to scatter from Laser");

}

public Particle emit(SurfaceQ s)

{

// emission along surface normal

Vector pos = s.getran();

Vector dir = s.intnorm;

return new Particle(pos,dir);

}

public void println()

{

System.out.println("parallel beam source");

}

}

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 60

16.1 Task - class Detector

Write the Detector class in file Detector.java which implements Squality in a similarway to Laser and Mirror above. The scatter() method should set the particle energyto zero and return false indicating that the particle has been absorbed (i.e. detected).The emit() method should throw a RuntimeException since we don’t want our detectorto emit particles, and the println() method should just list ”perfect detector” or somesimilar text. You will need the SurfaceQ and Squality class files to compile your Detectorclass. Copy them from

/disk/s/zrw/under/java/SurfaceQ.java

/disk/s/zrw/under/java/Squality.java

Finally we must create a new PlaneQ surface class to reflect the changes in the Surfaceclass. Note we cannot extend the Plane class since this extended the Surface rather thanthe SurfaceQ class. We need to modify the constructor and the println() method andinclude a natp() method as shown below. We also need to change the intersect() methodso that it scatters the particle if the intersection is in range. The rest remains as it wasin the Plane class.

/** Plane surface with quality */

class PlaneQ extends SurfaceQ

{

PlaneQ(Vector pos, Vector norm, Vector axis, Bounds bds, Squality sqa)

{

super(pos,norm,axis,bds,sqa);

}

...

public void natp()

{

intnorm=refnorm;

}

...

protected boolean intersect(Particle p)

{

// Check energy of particle

if(p.energy==0.0)

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 61

...

// Check within limits

if(edge.within(intcoord))

{

scatter(p);

return true;

}

else

return false;

...

}

public void println()

{

System.out.println("Planar surface with quality");

super.println();

}

}

Task 15 completed on: demonstrator:

16.2 Task - defining a source, a mirror and a detector

Study these definitions carefully. Write sections of code in your notebook to:

• Set up a laser beam with a circular cross section, starting at the origin and pointingalong the x-axis.

• Set up a rectangular, plane, mirror which will intersect the laser beam.

• Set up a rectangular, plane, detector which will intersect the reflected laser beam.

Task 16 completed on: demonstrator:

17 Completing the ray tracing problem

The classes which define the components of the ray tracing problem are now completebut we still need some way of tracing particles or rays through a sequence of components.

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 62

For example a simple optical bench set up might consist of a source, mirror and detectoras shown in figure 4.

(0,0,0) (10,0,0)

(10.-10,0)

Laser

(1,0,0)

Mirror

(0,1,0)

Detector

(-0.707,-0.707,0)

Figure 4: Test bench arrangement for ray tracing

What we need is an abstract class which can ray trace this sort of generic optical bench.The RayTrace class below does this.

/** Ray tracing of a set of surface components */

abstract class RayTrace

{

public int ncomponent; // number of surface components

public int nray; // number of rays to be traced

public SurfaceQ[] component; // surface components to be ray traced

public double xpos[][]; // xpos, ypos and zpos are the intersection

public double ypos[][]; // points along the ray

public double zpos[][];

public double xloc[][]; // xloc and yloc are the local coordinates

public double yloc[][]; // of the intersection points on components

public int npos[]; // number for positions for a particular ray

Particle p; // the particle or ray traced

RayTrace(int nc, int nr) // constructor to set up the arrays etc.

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 63

{

ncomponent=nc;

nray=nr;

component = new SurfaceQ[ncomponent];

xpos = new double[nray][ncomponent];

ypos = new double[nray][ncomponent];

zpos = new double[nray][ncomponent];

xloc = new double[nray][ncomponent];

yloc = new double[nray][ncomponent];

npos = new int[nray];

}

public void trace() // perform ray tracing through components

{

for(int i=0; i<nray; i++)

{

int j=0;

p = component[j].emit();

do

{

xpos[i][j]=component[j].intpos.cmpts[0];

ypos[i][j]=component[j].intpos.cmpts[1];

zpos[i][j]=component[j].intpos.cmpts[2];

xloc[i][j]=component[j].intcoord[0];

yloc[i][j]=component[j].intcoord[1];

j++;

npos[i]=j;

}

while((j<ncomponent) && (component[j].intersect(p)));

}

}

}

There is no undefined (abstract) method in RayTrace but it is declared abstract becausethe components to be traced are declared but not defined. This is the opposite situationto an interface in which only abstract methods and final static fields may appear. Themethod RayTrace.trace() is rather naive in that the sequence or order of componentstraced is fixed. However this is good enough to solve a large number of ray tracingproblems. A more sophisticated tracing method could always be added later by extendingthe RayTrace class.

The RayTrace class uses arrays of arrays, for example

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 64

public double zpos[][];

...

zpos = new double[nray][ncomponent];

In this case the individual arrays are type double but you can have arrays of arrays ofany type of data object. The number of arrays is given by the leftmost index, [nrays] inthis case. The size of the individual arrays can be variable but in this case it is fixed,[ncomponent].

We can define a particular set of components by creating a new class which extendsRayTrace. The following TestBench class sets up the bench shown in figure 4.

/** Simple test of ray tracing */

public class TestBench extends RayTrace

{

TestBench(int nr)

{

super(3,nr);

Laser las = new Laser();

Vector lpos = new Vector(0.0,0.0,0.0);

Vector ldir = new Vector(1.0,0.0,0.0);

Vector lref = new Vector(0.0,1.0,0.0);

Circbound lbeam = new Circbound(1.0);

component[0] = new PlaneQ(lpos,ldir,lref,lbeam,las);

Mirror mir = new Mirror();

Vector mpos = new Vector(10.0,0.0,0.0);

Vector mdir = new Vector(-1.0,-1.0,0.0);

Vector mref = new Vector(0.0,0.0,1.0);

Rectbound mlim = new Rectbound(-2.0,2.0,-2.0,2.0);

component[1] = new PlaneQ(mpos,mdir,mref,mlim,mir);

Detector det = new Detector();

Vector dpos = new Vector(10.0,-10.0,0.0);

Vector ddir = new Vector(0.0,1.0,0.0);

Vector dref = new Vector(1.0,0.0,0.0);

Rectbound dlim = new Rectbound(-3.0,3.0,-3.0,3.0);

component[2] = new PlaneQ(dpos,ddir,dref,dlim,det);

}

}

The following class PlotRaysXY can be used to plot the rays out. The details of the rays

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 65

are contained in the RayTrace instr object which is an argument of the constructor.

import java.awt.*;

/** Plot rays from ray tracing in XY plane */

public class PlotRaysXY extends Figure

{

double xmin;

double xmax;

double ymin;

double ymax;

RayTrace instrument;

PlotRaysXY(RayTrace instr, double xlo, double xhi, double ylo, double yhi)

{

instrument=instr;

xmin=xlo;

xmax=xhi;

ymin=ylo;

ymax=yhi;

}

public void paint(Graphics g)

{

mapping("scale",xmin,xmax,ymin,ymax);

box();

setColor(Color.red);

for(int i=0; i<instrument.nray; i++)

{

drawCurve(instrument.npos[i],instrument.xpos[i],instrument.ypos[i]);

}

}

}

17.1 Task - class PlotLocal

Write a PlotLocal class which plots the intersection points of all the rays for a specifiedsurface component. This class will be very similar to PlotRaysXY above. Pass the indexof the surface component to the class as an argument of the constructor. Check that thisargument is not out of range, i.e. not less than zero or greater than the highest componentindex. Remember Java array indices run from 0 to N-1.

The start of the constructor should look something like

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 66

PlotLocal(RayTrace instr, int ic,

double xlo, double xhi, double ylo, double yhi)

{

instrument=instr;

icom=ic;

...

The heart of the paint() method should contain a loop like:

for(int i=0; i<instrument.nray; i++)

{

if((instrument.npos[i]-1)>=icom)

drawOval(instrument.xloc[i][icom],instrument.

yloc[i][icom],0.0,0.0);

}

You will need the RayTrace.java class file to compile your PlotLocal class. You can copythis from

/disk/s/zrw/under/java/RayTrace.java

Task 17 completed on: demonstrator:

17.2 Task - application Seventh

Now, at long last, we can try out the complete ray tracing of a simple sequence of surfaces.The following Seventh class does just that.

import java.awt.*;

public class Seventh extends Frame

{

public Seventh(String title)

{

super(title);

}

public static void main(String args[])

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 67

/* main method to execute Seventh as an application */

{

System.out.println("Seventh start");

Seventh app=new Seventh("Seventh Java");

app.setSize(800,400);

TestBench bench = new TestBench(100);

bench.trace();

PlotRaysXY rays = new PlotRaysXY(bench,-5.,15.,-15.,5.);

PlotLocal dets = new PlotLocal(bench,2,-3.,3.,-3,3.);

GridLayout gridlay = new GridLayout(1,2);

app.setLayout(gridlay);

app.add(rays);

app.add(dets);

app.show();

System.out.println("Seventh stop");

}

}

Copy your Fourth.java file to create Seventh.java, edit it to look like the above, compile itand try it out. You will need the following files in addition to the others you have alreadycopied.

/disk/s/zrw/under/java/Mirror.java

/disk/s/zrw/under/java/Laser.java

/disk/s/zrw/under/java/PlaneQ.java

/disk/s/zrw/under/java/TestBench.java

/disk/s/zrw/under/java/PlotRaysXY.java

You should have written the Detector.java and PlotLocal.java files yourself. There is quitea lot going on in the Seventh program although the encapsulation of OOP makes it lookdeceptively simple. When you run the program you should get two pictures, one of therays traced and one of the detected distribution. Refer back to section 6 and check howthe Seventh program implements our original description of the ray tracing problem.

Task 18 completed on: demonstrator:

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 68

18 Introducing interactive graphics

Java was developed to provide interactive graphics and a Graphical User Interface (GUI)for use on the WWW and in similar environments. The AWT includes all the usualcomponents you would expect, buttons, menus, scroll bars etc.. Here we will use buttonsto introduce some of the principles involved in programming a GUI.

We are going to include code which provides a way of shifting and rotating surfacecomponents in the ray tracing. This will require some form of joy stick that is constuctedusing buttons arranged in a square within a Panel. A Panel is a convenient AWTcomponent that can be added to an Applet window or a application Frame. The followingcode sets up a class JoyStick.

import java.awt.*;

import java.awt.event.ActionListener;

import java.awt.event.ActionEvent;

public class JoyStick extends Panel

{

JoyStick(ActionListener al, String label)

{

Button b1 = new Button("LU");

Button b2 = new Button("U");

Button b3 = new Button("RU");

Button b4 = new Button("L");

Button b5 = new Button(label);

Button b6 = new Button("R");

Button b7 = new Button("LD");

Button b8 = new Button("D");

Button b9 = new Button("RD");

b1.setActionCommand("LU");

b2.setActionCommand("U");

b3.setActionCommand("RU");

b4.setActionCommand("L");

b5.setActionCommand("Stop");

b6.setActionCommand("R");

b7.setActionCommand("LD");

b8.setActionCommand("D");

b9.setActionCommand("RD");

b1.addActionListener(al);

b2.addActionListener(al);

b2.addActionListener(al);

b3.addActionListener(al);

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 69

b4.addActionListener(al);

b5.addActionListener(al);

b6.addActionListener(al);

b7.addActionListener(al);

b8.addActionListener(al);

b9.addActionListener(al);

GridLayout gridbut = new GridLayout(3,3);

setLayout(gridbut);

add(b1);

add(b2);

add(b3);

add(b4);

add(b5);

add(b6);

add(b7);

add(b8);

add(b9);

}

public double[] getJoyStick(ActionEvent ev)

{

String ob = ev.getActionCommand();

double dd=1.0;

double shift[] = new double[2];

if(ob.equals("LU"))

{

shift[0]=-dd;

shift[1]=dd;

}

if(ob.equals("U"))

{

shift[0]=0.0;

shift[1]=dd;

}

if(ob.equals("RU"))

{

shift[0]=dd;

shift[1]=dd;

}

if(ob.equals("L"))

{

shift[0]=-dd;

shift[1]=0.0;

}

if(ob.equals("Stop"))

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 70

{

shift[0]=0.0;

shift[1]=0.0;

}

if(ob.equals("R"))

{

shift[0]=dd;

shift[1]=0.0;

}

if(ob.equals("LD"))

{

shift[0]=-dd;

shift[1]=-dd;

}

if(ob.equals("D"))

{

shift[0]=0.0;

shift[1]=-dd;

}

if(ob.equals("RD"))

{

shift[0]=dd;

shift[1]=-dd;

}

return shift;

}

}

Each button for the joy stick is created in the constructor JoyStick(). For example

Button b1 = new Button("LU");

...

b1.setActionCommand("LU");

...

b1.addActionListener(al);

The text string ”LU” will be the label on the button. The setActionCommand(”LU”)method sets the text string which will be returned as the command when the buttonis pressed and the addActionListener(al) method sets the object which will handle thebutton event. In JoyStick this object is passed as an argument of the constructor. Thecentral button is labelled with a string passed as an argument of the constructor sothat the whole joystick can be given a suitable name. This central button produces a

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 71

”Stop” action command and a zero shift which could be used to toggle something. TheGridLayout class is then used to arrange the buttons in a 3 by 3 square.

The method getJoyStick(ActionEvent ev) gets a shift up-down and left-right from the joystick. This method will be evoked from within the code that handles the event generatedwhen a button is hit. In this case this method is expected to be in object al as set by theaddActionListener() method. The assignment

String ob = ev.getActionCommand();

gets the command string for the event. This will be the string set by thesetActionCommand() method as described above.

Next we need a way of moving the surface elements. We can do this for all surfaces if weintroduce a new class SurfaceQM which extends SurfaceQ.

/** Surface geometry, quality and movement*/

abstract class SurfaceQM extends SurfaceQ

{

SurfaceQM(Vector pos, Vector norm, Vector axis, Bounds bds,

Squality sqa)

{

super(pos,norm,axis,bds,sqa);

}

// tilt the surface normal

// delta[0] is rotation in radians about reference axis (assumed small)

// delta[1] is rotation in radians about other axis (assumed small)

public void tilt(double delta[])

{

// calculate other reference axis vector

Vector other = refnorm.cross(refaxis);

// apply tweek along reference axis and other

Vector dref = refaxis.scale(delta[1]);

Vector doth = other.scale(delta[0]);

// add tweek to the original normal and create unit vector

refnorm=refnorm.add(dref.add(doth));

refnorm=refnorm.normalise();

// now find new reference axis

other = refnorm.cross(refaxis);

refaxis=other.cross(refnorm);

refaxis=refaxis.normalise();

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 72

}

// shift the surface reference position

public void shift(double delta[])

{

...

}

// rotate about the surface normal

// delta in radians (assumed small)

public void rotate(double delta)

{

...

}

}

The method tilt() uses two small rotation angles in radians (provided by the JoyStick asyou will see) and changes the direction of the mirror normal as shown in figure 5. The

mirror surface

doth

dref

refaxis

other axis

refnormnewrefnorm

Figure 5: Geometry employed by the tilt() method.

methods shift() and rotate() are intended to translate the reference position and rotatethe surface about the normal as shown in figure 6.

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 73

refnorm

refaxis

delta[0]delta[1]

delta[2] refaxis

refnorm

delta

refpos

x

z

y

Figure 6: Geometry employed by the shift() and rotate() methods.

18.1 Task - class SurfaceQM

Create a new class SurfaceQM as described above and implement the shift() and rotate()methods as indicated in figure 6.

In order to use the SurfaceQM class we need new versions of the PlaneQ, RayTrace,TestBench, PlotLocal and PlotRaysXY classes.

Task 19 completed on: demonstrator:

18.2 Task - using class SurfaceQM

Create new classes PlaneQM, RayTraceM, TweekBench, PlotLocalM and PlotRaysXYMthat use the SurfaceQM class in place of the SurfaceQ class.

Task 20 completed on: demonstrator:

18.3 Task - applet Eighth

We will now bring the JoyStick and TweekBench together in an Applet which will tilt themirror in our test bench set up.

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 74

import java.awt.*;

import java.awt.event.ActionListener;

import java.awt.event.ActionEvent;

import java.applet.Applet;

public class Eighth extends Applet implements ActionListener

{

JoyStick tweek;

TweekBench bench;

PlotLocalM plotlocal;

PlotRaysXYM plotrays;

public void init()

{

System.out.println("Eighth start");

GridLayout gridlay = new GridLayout(2,2);

setLayout(gridlay);

bench = new TweekBench(100);

plotlocal = new PlotLocalM(bench,2,-3.,3.,-3,3.);

plotrays = new PlotRaysXYM(bench,-5.,15.,-15.,5.);

tweek = new JoyStick(this,"mirror tilt");

add(plotrays);

add(plotlocal);

add(tweek);

}

public void actionPerformed(ActionEvent ev)

{

double delta[] = tweek.getJoyStick(ev);

delta[0]=-delta[0]*0.01;

delta[1]=-delta[1]*0.01;

bench.component[1].tilt(delta);

bench.trace();

plotrays.repaint();

plotlocal.repaint();

}

}

Note that the Eighth class implements the ActionListener interface. The Applet windowcontains three components, two plotting panels plotrays and plotlocal, and a JoyStickpanel called tweek. The JoyStick(this,”mirror tilt”) constructor passes this, i.e. theobject Eighth, as the ActionListener object. The line

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 75

bench.trace();

performs a ray tracing of 100 rays.

If a button is hit with the mouse then an event is generated and the Applet code passes thisevent to the actionPerformed() method. This method is required by the ActionListenerinterface. The actionPerformed() method gets the delta associated with the event usingtweek.getJoyStick(ev), scales the delta to give suitable angles in radians, tilts the mirrorusing the tilt method of the mirror (component[1] in our test bench) and traces another100 rays. Finally it repaints the pictures.

Copy the Eighth program and JoyStick code from

/disk/s/zrw/under/java/Eighth.java

/disk/s/zrw/under/java/JoyStick.java

Compile the code in the usual way and create an Eighth.html file to run the applet andtry it out with the appletviewer. Make sure you understand how the event handler for abutton is set up and how the event generated, when a button is hit with the mouse, ishandled. Write down the sequence of methods that is evoked.

By adding a relatively simple extension to our SurfaceQ class, to create the newSurfaceQM class, we have introduced the possibility of tilting, shifting and rotating ALLsurfaces which we create within the ray tracing. Unfortunately adding extra functionalitylike this can mean that other code has to be modified. This is why it is important thatyou try and plan all the functionality you require at the start. The power of OOP is onlyrealised if the appropriate effort is expended in the planning/design phase.

Task 21 completed on: demonstrator:

19 Ray tracing spherical surfaces

Ray tracing is much more interesting if the reflecting surfaces are curved so we shall nowimplement the simplest curved surface, a sphere. All that is required is a new class,SphereQM, which extends SurfaceQM in the same way that PlaneQM does. One extraparameter, the radius, is required. All the others are the same as for the plane surface.

The constructor of our SphereQM class must save the radius. This radius will subsequentlybe used by methods to find the centre of the sphere, subtracting the reference normalscaled by the radius from the reference position.

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 76

centre=refpos.subtract(refnorm.scale(radius));

The intersect(Particle p) method must be changed to find the intersection of a ray(particle) with a sphere. The geometry required is shown in figure 7. The distance s

p.direction

refnorm

p.position

refppos

centre

radius

dαs

v

Figure 7: Intersection of a ray with a sphere.

and direction from the origin of the ray, p.position, to the centre can be found. Thecosine of the angle alpha can then be calculated from the dot product of this vector andp.direction. As the distance d changes so the distance v varies as a quadratic in d givenby the cosine rule

v**2 = d**2 - 2.d.s.cos(alpha) + s**2

For intersection we require this to be equal to the square of the radius. Therefore if wesolve the quadratic when v=radius we can find the two intersection points. We must becareful to cater for cases when there are no intersection points (complex roots) and onlyone intersection point (perfect square). Having found these points we must determine

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 77

which point is nearest the p.position in a positive direction along the ray and which isalso within the boundary defined on the surface.

The conversion from a position vector on the surface to local coordinates must beperformed by the ptoc() method and the inverse conversion from local coordinates toa position vector by the method ctop(). The easiest approach is to project the positionvector into the tangent plane as shown in figure 8. The distance dp is given by

radius

refnorm

β

intpos

tangent plane

refnorm

refaxis

other axis

x

ya

a

refppos

dp

dp

refpos

Figure 8: Projection of position vector into tangent plane.

dp=radius(1-cos(beta))

The cosine of beta can be found by taking the dot product of the reference normal andthe unit vector from the centre to the intersection position. If this cosine is negative thenthe intersection point is at a great circle distance >90 degrees from the reference positionand dp will be greater than the radius. Such positions should be given a local coordinatewhich is suitably large and therefore beyond any defined boundary. The position on thetangent plane can be found by adding a refnorm vector scaled by dp to the intersectionposition. Then the vector a can be found by taking the difference between this vector andthe reference position. Finally the local x and y positions can be calculated by projectingthe a vector onto the refaxis and other axis using the dot product. The inverse is achievedin similar fashion.

So ptoc() requires the following steps:

• find the centre of the sphere using the refpos, radius and refnorm

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 78

• find yaxis in tangent plane using refaxis and refnorm

• find unit vector from centre to intersection point

• calculate distance from intersection to tangent plane along refnorm

• find position in tangent plance wrt refpos

• calculate local x and y using the dot product to project onto the refaxis and yaxis

Similarly ctop() requires:

• find the centre of the sphere using the refpos, radius and refnorm

• find yaxis in tangent plane using refaxis and refnorm

• calculate distance from refpos to projection of intersection on tangent plane

• calculate cosine of angle subtended by intersection

• calculate distance to tangent plane along refnorm

• find position in tangent plane wrt refpos

• find position of intersection on tangent plane

• move down refnorm to find intersection point

• set intersection normal using natp()

The natp() method which calculates the normal at the intersection point is easy.

centre=refpos.subtract(refnorm.scale(radius));

intnorm=intpos.subtract(centre);

intnorm=intnorm.normalise();

When you are debugging your code you may find it useful to include System.out.println()calls within the above methods so that you can see the intermediate results of yourcalculations.

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 79

19.1 Task - class SphereQM, application Ninth

Write a SphereQM class as outlined above above using PlaneQM as a template. Don’tforget to modify the println() method to list the radius and centre. Create a newSphereBench class (by editing the TestBench class) which uses a spherical mirror insteadof a plane mirror. Finally create a Ninth.java program by editing the Seventh.java fileto test your new SphereQM class. Try and choose a radius of curvature so that rays arebrought to a focus on the detector of our test bench.

Because the mirror is set at 45 degrees to the beam the focus suffers from sphericaldistortion and the focussing is astigmatic. The best focus for meridional rays is verydifferent to the best focus for sagittal rays.

Although the geometry is a little tricky you can now see that adding a new surface typeis relatively easy. Very little new code has to be produced and the new surface typeintegrates into all the other software without any need for modifications. This is theadvantage of OOP.

Task 22 completed on: demonstrator:

20 Further interaction

In addition to Buttons there are a number of other AWT GUI components which provideinteraction; Checkboxes, Choices, Dialogs, Lists, Menus, Scrollbars, Scroll Panes andTextFields.

Suppose we require some form of sliding control which can be used to position the detectoron our test bench. This can be provided using a combination of a Scrollbar and TextField.The interactive control required is shown in the class Slider defined below.

import java.awt.*;

import java.awt.event.*;

public class Slider extends Panel

{

Scrollbar slide;

Label label;

TextField text;

int max=1000;

int block=10;

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 80

double smin;

double scale;

Slider(AdjustmentListener al, String title, double sm, double sx)

{

smin=sm;

scale=(sx-sm)/((double)(max));

slide = new Scrollbar(Scrollbar.HORIZONTAL);

slide.setMaximum(max+block);

slide.setBlockIncrement(block);

slide.addAdjustmentListener(al);

label = new Label(title, Label.CENTER);

text = new TextField(String.valueOf((float)smin)+" ",10);

GridLayout gridsl = new GridLayout(3,1);

setLayout(gridsl);

add(label);

add(text);

add(slide);

}

public double value(AdjustmentEvent e)

{

double val = ((double)e.getValue())*scale+smin;

text.setText(String.valueOf((float)val+" "));

return val;

}

}

The Slider consists of 3 horizontal areas, a text Label (just to give the thing a title), aTextField used to indicate the numerical position of the Slider and a ScrollBar used toadjust the Slider.

The first 2 arguments of the constructor are similar to those of the JoyStick and definethe object which is going to act as a listener for events from the ScrollBar and the titleused in the Label. The other arguments, double sm, double sx are used to define therange of floating point numbers associated with the Slider control.

A ScrollBar actually works with an integer range, set to max+block in the constructorabove and an integer step size, block, which defines how much the device shifts whenusing the mouse. The block is added to the max value in the setMaximum(max+block)method so that the floating point range ends up as exactly sm to sx.

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 81

The line

text = new TextField(String.valueOf((float)smin)+" ",10);

creates and initializes the TextField to the minimum value of the Slider. The methodString.valueOf() generates a String which represents the floating point value. The (float)cast has been used to limit the number of significant figures used. The 10 defines theminimum width of the TextField.

The line

slide.addAdjustmentListener(al);

sets the object al as the listener for the ScrollBar control. The object al must implementthe interface AdjustmentListener and must therefore include a method called

public void adjustmentValueChanged(AdjustmentEvent e)

The remaining lines in the constructor simply add the Label, TextField and ScrollBar tothe Panel using a 3 line grid.

The method value(AdjustmentEvent e) is used to calculate the position of the Slider,converting from the integer value returned by e.getValue() method into a floating pointnumber. This double value is converted to a String and inserted in the TextField andreturned as the value of the method. It is to be expected that the method value() will beevoked by the adjustmentValueChanged() method.

We can put the Slider class to work by modifying the Eighth program above. The followingindicates the additional code required.

import java.awt.*;

import java.awt.event.*;

import java.applet.Applet;

public class Tenth extends Applet implements ActionListener,

AdjustmentListener

{

...

SphereBench bench;

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 82

Slider slip;

...

public void init()

{

...

Panel sub = new Panel();

GridLayout subgrid = new GridLayout(4,1);

sub.setLayout(subgrid);

...

bench = new SphereBench(100);

...

slip = new Slider(this,"detector y position",-15.,-5.0);

...

sub.add(slip);

add(sub);

}

...

public void adjustmentValueChanged(AdjustmentEvent e)

{

double newpos = slip.value(e);

double oldpos = bench.component[2].refpos.cmpts[1];

double delta[] = new double[3];

delta[0] = 0.0;

delta[1] = newpos-oldpos;

delta[2] = 0.0;

bench.component[2].shift(delta);

}

}

You can now see how the adjustmentValueChanged() method is set up. When theScrollBar in the Slider is moved with the mouse this method is evoked and the slip.value(e)call gets the new position of the slide (and also updates the TextField). The shift requiredis then calculated and the detector component of the bench shifted by the appropriateamount.

20.1 Task - applet Tenth

Create a Tenth.java program by editing the Eighth.java file using the code indicated aboveand try out the Slider control.

You should now have a good idea of how the event handling model of the Java AWTworks. All the interactive components that create events are handled in a similar fashion.

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 83

A Choice component provides an easy way of choosing between options using a pull-downmenu. Suppose we want to be able to switch between a plane mirror and spherical mirroron our optical bench. This can be done using a Choice.

Task 23 completed on: demonstrator:

20.2 Task - class Choice

Lookup how to use the Choice component in the java.awt at

http://java.sun.com/products/jdk/1.1/docs/api/packages.html

Modify the Tenth.java program to allow you to switch between a plane mirror and aspherical mirror. It is probably easiest if you create a new bench class called ChoiceBenchsay, which defines both a plane and spherical mirror.

Task 24 completed on: demonstrator:

21 Threads and multi-tasking

A thread is a series of steps executed in sequence, so the procedural programs you arefamiliar with are single threads. Actually more than one thread is active even whenyou are running the simple Java programs described above but all the threads bar yourprogram are hidden in the background. When running an Applet the init() method iscalled by the driving thread and thus init() constitutes the visibly active thread (at leastat the start). When running an Application the main() method assumes this role.

Java provides facilities so that the programmer can create, start and stop a numberof asynchronous threads to implement multi-tasking. These threads can then runsimultaneously or at least in a fashion that appears to be simultaneous because, of course,the different threads are time sharing the same processor in most machines.

Threads are represented by instances of the class Thread. This class can be used in twoways. You can extend the Thread class and override the default run() method. Thenew class is then used by creating an instance of the class and calling the Thread start()method.

class MyThread extends Thread

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 84

{

...

public void run()

{

... \\ code here to do whatever is required of the thread

}

...

}

...

MyThread t = new MyThread();

t.start();

Alternatively you can use the Runnable interface that declares one abstract method run().In this case you must create a class that implements the Runnable interface and whichtherefore includes a run() method. Your class is then wrapped up (or Threaded if youwant) in a Thread by creating an instance of a Thread, passing an instance of your classas a constructor argument. This avoids problems of multiple inheritance when you requireyour class to be both threaded and an extension of another class.

class MyThreadedClass implements Runnable

{

...

public void run()

{

... \\ code here to do whatever is required of the thread

}

...

}

...

Thread t = new Thread(new MyThreadedClass());

t.start();

Suppose we want to trace rays through our simple optical bench while at the same timewe want to tilt the mirror around continuously in a cyclic fashion. We can define a newclass which continuously wobbles a surface and lists the position of the tilt.

import java.awt.*;

public class WobbleSurfaceQM extends Panel implements Runnable

{

SurfaceQM surface;

TextField text;

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 85

static final double rtod = 57.2957795131;

double amplitude;

int maxstep = 10;

public WobbleSurfaceQM(String title, SurfaceQM s, double ampdeg)

{

surface = s;

amplitude = ampdeg/rtod;

Label label = new Label(title+" (degrees)", Label.CENTER);

text = new TextField("0.0 ",10);

GridLayout gridlay = new GridLayout(2,1);

setLayout(gridlay);

add(label);

add(text);

}

public void run()

{

double delta[] = new double[2];

delta[0]=0.0;

delta[1]=0.0;

double step=amplitude/(double)(maxstep);

int i=0;

int ic=1;

double theta;

while(true)

{

try

{

Thread.sleep(100);

}

catch (InterruptedException ignore)

{

}

i=i+ic;

if(i==maxstep)

{

ic=-1;

}

if(i==-maxstep)

{

ic=1;

}

delta[0]=step*(double)ic;

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 86

surface.tilt(delta);

theta=rtod*step*(double)i;

text.setText(String.valueOf(theta)+" ");

}

}

}

The constructor sets up a Label and TextField within a Panel and the run() methodwobbles the surface back and forth by a few degrees continuously updating the TextFieldto give the value of the tilt in degrees. It is intended that an instance of WobbleSurfaceQMis run as a thread. The Thread.sleep(100) method causes the thread to be marked as notre-schedulable for a number of milliseconds (100 in this case). This permits other threadsto start running. It must be called within a try-catch block because a sleeping thread maybe interrupted by an active thread. Usually no exception is thrown and the try{} clausewill be completed, the thread will rest for at least 100 milliseconds and will resume afterthe catch(){} clause. The use of Thread.sleep() slows down the execution of the tiltingloop and will allow the ray tracing loop (in the main thread) to execute faster.

We can use the class WobbleSurfaceQM in a program as follows:

import java.awt.*;

public class Eleventh extends Frame

{

public Eleventh(String title)

{

super(title);

}

public static void main(String[] args)

{

Eleventh app=new Eleventh("Eleventh Main");

app.setSize(600,600);

GridLayout gridlay = new GridLayout(2,2);

app.setLayout(gridlay);

TweekBench bench = new TweekBench(2);

WobbleSurfaceQM wobble = new WobbleSurfaceQM("mirror wobble",

bench.component[1],5.0);

PlotLocalM plotlocal = new PlotLocalM(bench,2,-3.,3.,-3,3.);

PlotRaysXYM plotrays = new PlotRaysXYM(bench,-5.,15.,-15.,5.);

app.add(plotrays);

app.add(plotlocal);

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 87

app.add(wobble);

app.show();

Thread t = new Thread(wobble);

t.start();

System.out.println("Starting Eleventh Main loop");

while(true)

{

try

{

Thread.sleep(100);

}

catch (InterruptedException ignore)

{

}

bench.trace();

plotrays.repaint();

plotlocal.repaint();

}

}

}

21.1 Task - application Eleventh

Edit the Fourth.java program to create Eleventh.java and copy class WobbleSurfaceQMfrom

/disk/s/zrw/under/java/WobbleSurfaceQM.java

There is one further important consideration. In the Eleventh program above it is possiblethat the thread that is tracing and plotting the rays could be accessing surface data fieldswhile the thread that is wobbling the surface is modifying the same data fields. In sucha case we need to lock the data fields while they are being modified so that other threadscan’t use them during that time. This can be done using the synchronized statementwhich has the form:

synchronized(object reference - data field)

{

code to be executed

}

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 88

While the code embodied by the scope of the statement is being executed the Javascheduler will ensure that no other thread can access the object reference. For examplewe can lock the refnorm data field in our tilt() method:

// add tweek to the original normal and create unit vector

synchronized(refnorm)

{

refnorm=refnorm.add(dref.add(doth));

refnorm=refnorm.normalise();

}

You should modify the tilt(), rotate() and shift() methods in class SurfaceQM so that thesurface data fields are locked while they are being modified. Actually if you don’t includethis modification the code will probably run correctly because the probability of a clashcausing a problem is very small.

Compile the program and try all this out.

Task 25 completed on: demonstrator:

21.2 Task - class SlideSurfaceQM

Create a new class SlideSurfaceQM which performs a similar function toWobbleSurfaceQM but shifts a surface back and forth along the direction of the normal.Modify the Eleventh program to use class SlideSurfaceQM with a spherical mirror.

Task 26 completed on: demonstrator:

21.3 Task - wobbling the source and mirror simultaneously

Modify the Eleventh program so that both the source and the mirror wobblesimultaneously!

Once again you can see that adding extra functions to OOP code is very easy providingthe original design of the classes was carefully thought out.

In the above we have not worried about any synchronisation problems between threadsand we have only locked data fields using the synchronized statement. If you have aproblem in which the method in one thread relies on the completion of the method from

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 89

another thread then you can synchronize the threads rather than just locking data fields.All you have to do is include the word synchronized in the declaration lines of the methodswhich must be mutually locked when running. Only threads which are in the same classcan be declared synchronized.

Task 27 completed on: demonstrator:

22 Using the classes available

If you have spent some time designing and testing a new set of interacting classes thenyou can produce quite sophisticated programs combining the power of your code withthe classes in the API. For example we can produce a point like source of rays using aSphereQM surface and Laser Squality. This is equivalent to passing a parallel (laser)beam through a diverging (concave) lens.

22.1 Task - application Twelfth

Create a class PointBench in which the parallel beam source is replaced by a point source.You can use the class TweekBench as a starting point.

You will have noticed that the layout of components provided by class GridLayout israther inflexible. A prettier result can be achieved using class GridBagLayout. Details ofhow to use this class can be found at:

http://java.sun.com/products/jdk/1.1/docs/api/java.awt.GridBagLayout.html

http://java.sun.com/docs/books/tutorial/uiswing/layout/gridbag.html

Create a program Twelfth.java by editing Eleventh.java using PointBench in place ofTweekBench and GridBagLayout instead of GridLayout.

In all the applications above we have not provided a proper way of stopping the applicationand returning to the shell prompt. You can do this using a button which returns the “quit”command string (or something similar of your choice). In the actionPerformed() methodwhich services the buttons you should execute the System.exit() method, for example:

...

String ob = ev.getActionCommand();

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 90

...

if(ob.equals("quit"))

{

System.out.println("quitting application");

System.exit(0);

}

...

The argument of the System.exit() call is the returned status which is set to zero (OK)above.

Task 28 completed on: demonstrator:

23 Into the unknown

If you have worked your way through all the tasks above you will have a good idea ofwhat Object-Oriented Programming involves. Here are a few tips to help you design yourown OO programs in Java.

• Design the class structure before you start writing code. Think about the data fieldsand methods which are likely to be encapsulated in each class.

• Keep the class structure simple. It is better to have a larger number of unrelatedclass trees rather than trying to cram too much functionality into one or twomammoth classes.

• If you find you need multiple inheritance in your class structure use interfaces.

• Always put as much common functionality in the base classes since this will save onrepeating code unnecessarily. This concerns both fields and methods.

• Keep the methods simple with the minimum number of arguments and minimumfunctionality.

• Remember the arguments (parameters) to methods are strictly input parametersand arguments are objects and as such pass fields and methods alike. Argumentsshould come from outside of the class, i.e. from another class. All the results frommethods are returned as the method value or appear as modifications of the datafields within the class.

• Keep the constructors for classes simple and provide constructors with differentargument lists for different levels of default behaviour.

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 91

• Avoid public members within a class. i.e. keep the interface to the outside worldas simple as possible. It is often better to provide internal defaults for fields andsetthingy(value) forms of method to change these defaults.

• If you are wondering how to do something check the API to see if a particular wheelyou want has already been invented.

In this workshop we have placed the emphasis on the Object-Oriented aspects of Javaprogramming and neglected many of the procedural programming facilities providedwithin the language. Furthermore we have only touched on the vast API which providesa wealth of classes for all manner of applications. However you should now know enoughto be able to make use of the on-line documentation provided on the WWW. Here aresome useful links:

The Java Language specification

http://java.sun.com/docs/books/jls/html/index.html

Java API Packages like java.applet and java.AWT

http://java.sun.com/products/jdk/1.1/docs/api/packages.html

The javadoc utility

http://java.sun.com/products/jdk/1.1/docs/tooldocs/solaris/javadoc.html

23.1 Task - Cellular Automata

A chess-doard cellula automaton is a process which generates a pattern of black and whitesquares on a rectangular grid. An initial row is seeded with a particular pattern and thensome rule is used to convert this pattern into a new pattern on the next row. The samerule is then used again to generate the next row and so on.

The simplest first row is all zero (false) except for a single isolated 1 (true). A particularlysimple but powerful form of rule is where the jth element of a row is determined by the(j-1)th, jth and (j+1)th values in the previous row:

M(k,j)=rule(M(k-1,j-1),M(k-1,j),M(k-1,j+1))

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 92

i.e. the M(k, j) is 1 or 0 (true or false, black or white, etc.) depending on the 3 elementsabove in the matrix. The so-called rule number 30 summarised below gives particularlyinteresting results.

k-1 --> k

1 1 1 0

1 1 0 0

1 0 1 0

1 0 0 1

0 1 1 1

0 1 0 1

0 0 1 1

0 0 0 0

Write a Java application program to render the pattern produced by rule 30.

Task 29 completed on: demonstrator:

23.2 Task - Recusive Triangles

A right-angled triangle with sides (1, 2,√5) can be subdivided into 5 similar triangles as

shown in figure 9. Each of the component triangles can be so divided in turn. Following

Figure 9: The subdivision of a (1, 2,√5) triangle

this recursion a complicated aperiodic pattern can be produced. Write a Java applicationprogram to draw the pattern resulting from a specified level (about 4 or 5) of recursion.

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 93

Task 30 completed on: demonstrator:

24 Quick Java reference

24.1 Primitive types

boolean logical true or false

char 16-bit Unicode 1.1.5 character

byte 8-bit signed two’s complement integer

short 16-bit signed two’s complement integer

int 32-bit signed two’s complement integer

long 64-bit signed two’s complement integer

float 32-bit IEEE 754-1985 floating-point number

double 64-bit IEEE 754-1985 floating-point number

Casting is performed (if possible) by (type)expression where type is one of above.

24.2 Character escape sequences

Special characters in strings are defined by the following escape sequences.

\n newline

\t tab

\b backspace

\r return

\f form feed

\\ backslash itself

\’ single quote

\" double quote

\ddd a char by octal value, where each d is one of 0-7

24.3 Arithmetic operators

+ addition (also used to concatenate strings)

- subtraction

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 94

* multiplication

/ division

% remainder

++ increment (can be before or after operand)

-- decrement (can be before or after operand)

24.4 Relational and conditional operators

> greater than

>= greater than or equal to

< less than

<= less than or equal to

== equal to

!= not equal to

24.5 Logical operators

&& logical AND

|| logical OR

! logical NOT

24.6 Bitwise operators

& bitwise AND

| bitwise inclusive OR

^ bitwise exclusive or (XOR)

~ take unary bitwise complement

<< unary shift bits left filling with zeros to right

>>> unary shift bits right filling with zeros to left

>> unary shift bits right filling with highest (sign) bit on left

24.7 class Math methods

sin(a) sine(a) a in radians

cos(a) cosine(a) a in radians

tan(a) tangent(a) a in radians

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 95

asin(v) arcsine(v) v in range -1.0 to 1.0

acos(v) arccosine(v) v in range -1.0 to 1.0

atan(v) arctangent(v) returned in range -pi/2 to +pi/2

atan2(x,y) arctangent(x/y) returned in range -pi to pi

exp(x) e^x

pow(y,x) y^x

log(x) ln x (natural logarithm of x)

sqrt(x) square root of x

ceil(x) Smallest whole number >= x

floor(x) Largest whole number <= x

rint(x) return truncated integer value of x as double

round(x) return (int)floor(x+0.5) for either float or double

abs(x) return absolute value of any numeric type

max(x,y) return larger of x and y for any numeric type

min(x,y) return smaller of x and y for any numeric type

24.8 Repetition and control

for(init-expr; log-expr; incr-expr)

for(int i=start; i<end ; i++) definite loop

do {code} while(log-expr); indefinite loop test after pass

while(log-expr) {code} indefinite loop test before pass

if(log-expr) {code} else {code} if-else block

value = (this ? if-true:if-false) conditonal operator

throw new someException throw an exception

try {code} catch(exception) {code}

finally {code} try-catch block

switch (thiscase) switch-block

{case v1: code; without break fall through to v2

case v2: code; break;

default: code;} switch-block

synchronized (object reference) synchronized block (reference lock)

{code}

24.9 class String

indexOf(char ch) index of first ch

indexOf(char ch, int start) index of first ch>=start

indexOf(String str) index of first str

indexOf(String int start) index of first str>=start

University of LeicesterDepartment of Physics and AstronomyThird/Fourth Year Computing WorkshopObject-Oriented Programming

Document: joopIssue: 4.0Date: October 3, 2012Page: 96

lastIndexOf(char ch) index of last ch

lastIndexOf(char ch, int start) index of last ch<=start

lastIndexOf(String str) index of last str

lastIndexOf(String str, int start) index of last str<=start

compareTo(String str) true if same

regionMatches(int start,

String other, int ostart, int len) true if same

regionMatches(boolean ignorecase,

int start, String other,

int ostart, int len) true if same

startsWith(String prefix, int off) true if prefix at off

startsWith(String prefix) true if prefix at 0

endsWith(String suffix) true if ends with suffix

startsWith(String prefix) true if prefix at 0

valueOf(type) convert to String

new Boolean(String).booleanValue() convert from String

Integer.ParseInt(String, int base) convert from String

Long.ParseLong(String, int base) convert from String

new Float(String).floatvalue() convert from String

new Double(String).doubleValue() convert from String


Recommended