This file contains internal information about the way C.a.R. works. It is intended for those, who want to understand the source code. But it may be interesting for the users who seek information beyond the documentation.
C.a.R. is written in Java. Here is an overview over the different packages that make up the source.
rene.zirkel | Contains the main classes. |
rene.gui | Several help classes for the GUI, like text fields, menu items, 3D panels etc. |
rene.dialogs | Some dialogs and window classes, especially the file dialog. |
rene.viewer | A replacement of the AWT List class. Used by the file dialog, the construction description and other. |
rene.util | BMP class and file utilities, used by the file dialog. |
rene.util.xml | XML input and output. |
rene.util.list | Chained list and tree for the XML routines. |
The main package contains all the geometry classes for the various object types, the code for the main window, and the code for the applet. There are no subdirectories.
The XML routines are very tiny, but mighty. However, they do not produce the standard objects. Instead, a tree representation is used for the XML file. The routines are powerful enough to read and write most XML stuff, including different encodings. The standard encoding is UTF-8.
The file dialog is used to replace the system dialog as used by the AWT. It does take care off file filters, and it effectively remembers old files and directories.
The BMP saver is very restricted. I found the code in the public domain.
All classes are packed into an archive zirkel.jar, together with the localization files for all languages and the necessary icons.
The first way to start the program is to install it locally. There are several installation methods, one of them is the Windows setup, which was generated with the fine freeware installer InnoSetup. Others are via Java Web Start or use the free version of InstallAnywhere.
In any case, the main method is contained in the Zirkel class in the default package. This is only calling the main method in rene.zirkel.Zirkel. Since Java 1.3, the main class will be found automatically, since the archive has a manifest. Thus, the application will start by double clicking zirkel.jar in Windows. The archive is also signed.
Of course, a Java virtual machine is needed. Java 1.1 like the Microsoft Java will suffice, but Java 1.2 yields a nicer graphics.
This is done by embedding applet code into a HTML page. The zirkel.jar archive must be on the Web server. Have a look into the demos to see, how the applet code looks like. It is possible to use a code base other than the location of the web page.
Note that constructions are found relative to the location of the zirkel.jar archive; i.e., relative to the code base.
The program contains an HTML export facility to generated web pages with the applet code and a minimal page body. Be advised to use this export for the first tries. Later, it may become easier to just copy the HTML pages and set the necessary applet parameters manually.
The applet parameters contain information about the applet style, the file to loaded, the colors, the available tools and others. You may study the sources of the demo pages to get a start. Or just use the HTML export.
Of course, links may be set anywhere on the page. But a special mechanism lets the applet switch the page, if the user solved a problem. The HTML export may be told to generate a solution page for problems, and to switch to that page automatically.
Localization is done by a mechanism provided by Java. The program reads the so called property files at its start. These files contain lines of translations of internal strings into the various languages. There is one property file per language, named ZirkelProperties_xx.properties, where xx is the language code. The property files are assumed to be in rene/zirkel. If a string is not contained in a local language, the English version will be used.
The reference to the documentation, locally or in the Web, is also localized in the property file. Have a look into the existing files to see how this works.
It is possible to change the current language with the command line parameter "-h xx", where xx is one of the following: en, de, it, br, pt, sl, da, fr.
The documentation is partly in HTML, and additionally in a few text files.
In the installations for Windows the zirkel.jar archive is copied to the documentation directory. This is needed by the demos. The demos start the program in an applet using the ZirkelApplet class. The same archive is used for the application itself starting the main method in the Zirkel class.
There are numerous demos and examples, most of them linked from the HTML pages. All demos use the same zirkel.jar archive, even in subdirectories. Consequently, the construction files must be specified with relative path names.
The text files that are contained in the archive zirkel.jar are in the subdirectory rene/zirkel and can be translated into local languages. In this case, the files must be preceded by xx_, where xx is the local language code, and the language must be set as a parameter in the properties file. By default, the English texts are used.
The most important text file is info.txt, which contains all context sensitive help. It has a very simple structure. Have a look at the English version in info.txt to see how it works.
C.a.R. can call the HTML documentation from within the program. This is achieved by starting an external process. Of course, the user may have to set up the correct path to the HTML browser he uses. The program looks for the local file index.html in the current directory. If this is not found, it starts the viewer with a reference to the documentation in the Web, as indicated in the localized property file.
The geometric objects are organized in a list, internally a Vector. This data structure is easily scanned from start to end. The object list does not change much, besides appending new objects.
The list of objects is a field in the Construction class.
The objects do also form a tree, since objects do depend on other objects, e.g. segments on their endpoints. Only the basic free points and constant expressions depend on no other objects. In general, an object may only depend on objects that are earlier in the object list. This allows to re-compute the list in one pass. However, bounds of points are an exception to this rule.
The main object types are the following. The internal class names are not mentioned here. Of course, the classes are organized in a hierarchic object oriented way. The main class it the ConstructionObject.
Points | Those are the normal points and the intersections. |
Lines | The lines, the segments, the rays and the fixed angle objects. |
Circles | The circles through one or two points and the circles of fixed radius. |
Angle | Decorative objects only, which may have a value however. |
Polygon | Decorative, but has the area as value. |
Quadric | Decorative without any value. |
Expression | Decorative with the obvious value. |
Text | Decorative only. |
The decorative objects cannot be used in constructions. Objects with values can be used in arithmetic expressions.
Objects have properties, such as thickness, color, and flags for showing the name or the value. Most objects have other special properties, like the fill status of circles and angles. Some objects have properties, which refer to other objects, like the line or circle for a bounded point, or the drawing limits for a circle segment. In this case it is possible that the objects refer to objects, which are defined later, which complicates the code.
Objects have specialized property dialogs. However, there is a root dialog class, which provided switches for the common properties of all objects. The dialog is called by the function "edit", which overrides in each particular object. Obviously, this function must do some administrative work in many cases to keep the references intact.
Objects may become invalid.
Objects may be hidden or super-hidden. There is a special tool to hide objects, and another tool to show all hidden objects. To super-hide an object manually, the user may press the shift key while hiding the object. Normally, super-hiding is only used by macros. A super-hidden object appears in the construction description, and it is possible to call its setup dialog there to unhide it.
We now describe some of the objects in more detail.
Points are subclasses of the PointObject class.
Points can be moveable or not. A freely generated point is of course moveable. A point bound to an object is moveable, but will be projected to the object immediately. Non-moveable points are intersection and fixed points. Points may be fixed by the user by entering an expression into the object dialog and starting the fixed state.
Points bounded on objects move with the object in two different modes. If the shift key is pressed during the generation of these points, the relative position on the object is fixed, otherwise the points float on the object.
Intersections can be between a pair of circles or lines. Clearly, lines and circles may intersect in two points, one point or none. If they do not intersect, an intersection becomes invalid. Touching circles or tangent lines still have two intersections internally. The intersection points are uniquely determined by the direction of the line and the position of the circle. As an exception, an intersection point may be commanded to stay away from a specified point, or to attract to a point. This feature is used automatically, if the user generates an intersection and the other intersection point is already constructed, assuming that the user wanted to get the other intersection point in every constellation.
If the user creates an intersection with the intersection tool by clicking on the objects, both intersections will be generated. If he creates it on the fly, by clicking on the intersection to create a point, only this intersection will be created.
The problem of intersections is generally the most difficult one to handle by a geometry program.
Lines are subclasses of the PrimitiveLine class.
Most lines depend on two points. These objects are lines, segments and rays. They defer by the pointing routine and by the way, intersections are handled. Intersections with segments become invalid, if the intersection is not on the segment.
The fixed angle object is a specified line object. It is a line that is forms a specified angle with the line trough given points A and B, and passes through A. It can draw an angle just like an angle object. But in constructions, it is treated like a ray. and it paints like a ray. Its property dialog has settings for the angle aspect too. See below for problems with angles.
There is a special switch in the settings dialog for the sign of the angle. The sign determines the side of the line AB the angle is on.
Note that fixed angles can be sized with the mouse, if the fixed state is switched off in the settings dialog.
Segments can be fixed in size, if one of the endpoints is free. This is an old feature, which should not be used anymore, since it requires a permanent check for the feasibility of the fix, since the endpoint may be bound to an object later. Instead, fixed circles should be used to fix a length. However, the feature may be comfortable at times.
Lines may be reduced to the relevant part between the two generating points and a little beyond. Segments may be draw in vector style.
Lines become invalid, if both defining points coincide. This is determined numerically with an internal accuracy.
Circles are subclasses of the PrimitiveCircle class.
There are three types of circles, depending on one, two or three points.
The one point type is the fixed circle with a radius given by an expression. The user will still be able to change the size of the circle by dragging its circumference, if the fixed state is switched off in the settings dialog. By default, it is on.
The two point type is given by the center and a point on the circle. The three point type draws a circle of a radius determined by the distance of two points around a center.
Circles can be reduced to the relevant points. This will draw only those parts, which pass through points connected with the circle, like bounded points or intersections. Circles can also be reduced to arcs. In this case, they draw only the part between two given points. There are two modes for this feature. Either the part is determined by the order of these points, or it is always the shortest path. The user determines this in the settings dialog by allowing obtuse angles or not.
Circles may be filled. Refer to the section about painting for more information about filled objects.
Note that circles become invalid, if the radius is smaller or equal to 0.
Angles are decorative objects, which cannot be used in other constructions. However, the size of an angle can be fixed, if either segment point is free. Then this point will move to keep the angle at its size. Angles depend on three points with the usual convention that the second point is the corner point.
One problem with angles is the orientation. By default, angles will be between 0 and 180 degrees, which simplifies matters. The user can change this mode by allowing the angle to become obtuse. In this case, the angle is drawn in a mathematical positive way.
Angles may be filled. Refer to the section about painting for more information about filled objects.
Those are decorative object, depending on several points. These objects paint as filled object. See the section about painting for more details. The value of a polygon is its area. It is painted into the center of gravity.
Quadrics are decorative objects depending on five points.
The quadric is computed by solving a linear system of five unknown parameters. It is a curve satisfying
ax^2+by^2+cxy+dx+ey=1
The numerical solution may be unstable. The quadric becomes invalid, if this is the case.
The quadric is painted by solving the above equation for y in the given x-range and connecting the two branches of (x,y)-points.
Expressions are decorative objects with a value. The displayed object is stored in the ExpressionObject class. The Expression itself is stored in the Expression class. This class is also used for fixing objects.
The program uses a scanner class to produce the expression from a given string. Note that the expression may contain references to objects. In this case the value of the object is used, or the object is the parameter of a function like the distance of two points d(A,B) or the angle a(A,B,C). The scanner class is capable of evaluating the expression at a later time, taking into account the changed object values.
Expression do keep track of the objects they depend on. This makes it possible to use expressions in macros. See the section about macros for more information.
Expressions paint as text. Expression will only paint the result value, not the expression itself. This value may be explained with any text in the form a=...
Expressions are moved by dragging them just like any other object.
Text is decorative only. The user gets a dialog with a TextArea object to edit the text. Text may consist of several lines.
The user can move the text by dragging the text at the upper left corner.
Painting is done by the ZirkelCanvas class, which contains the list of objects. This class contains variables, which determine the viewpoint, and has routines, which translates the (x,y)-coordinates to screen coordinates.
All objects are painted in the order they are in the list. However, there are two passes creating to levels of objects. The lower level contains the background objects, and the upper level the objects that are not in the background. Since Java 1.3 uses transparency, the background is no longer a necessity. However, it still makes a difference. For Java 1.1 and therefore for all browsers without a modern Java plug-in, putting objects into the background is important.
The area of filled objects is in the background by default. The user can change this in the setup dialogs of these objects. Weather or not filled objects have a boundary depends on the object type and the thickness of the object.
After all the objects the tracks are drawn. Clearly, this requires the most computing time. Note, that in general the speed of the program is determined by the graphics, not by the mathematical routines.
The background color is the normal system color. However, one should specify a background color for applets, since it should be equal to the background color of the containing page.
It is possible to load a background picture. There are several modes for this, which the user can determine. The picture can be centered, stretched or repeated.
This is done in part by the ZirkelCanvas class, which listens to mouse actions and to the keyboard.
Most mouse actions are passed to the current tool. The tool will then handles this mouse action properly. There are special tools for all the objects.
However, there are exceptions. A right mouse click to an empty place may open a popup menu. This is handled by ZirkelCanvas itself. Moreover, clicking with the right mouse on an object or an object name is handled by ZirkelCanvas by selecting this object and trying to drag it, if possible. The dragging itself is done by a special tool. But the default tool is restored at the end of the drag. If the drag is not possible, or the user did not drag the object, the setup editor for the object is opened by ZirkelCanvas.
A tool may handle a mouse click by selecting an object, or by selecting or creating a point. It will call routines in ZirkelCanvas to do this selection or creation. Note that when selecting a point the user can create a new point in most cases. It is even possible to create intersections and bounded point on the fly.
Of course, a tool may also use the mouse click for different purposes, like to stop or start an animation.
Keyboard action is caught by ZirkelCanvas, but not handled. It is passed to the containing frame, which is either ZirkelFrame or, for applets, ZirkelApplet. The user may change tools with keyboard strokes. He can also magnify or move the view this way.
Tracks consists of sequences of points saved in a Vector. There are two types of tracks.
First there are tracks of points. Those are generated by a moving point. The movement is user generated for normal tracks, either directly by moving this point or indirectly by moving other points. Or the movement is computer generated for automatic tracks. In this case another point moves on an object and causes the track point to move indirectly.
Automatic tracks have a special feature. In general, such tracks are generated by moving a certain point once around a circle, back and forth on a segment or a line. However, this may cause the track point to become invalid. At that time, the moving point will change its direction. Moreover, if the object point became invalid due to an intersection, which did no longer exist, the intersection will switch to the other intersection point. The purpose of this feature is to have the track run through all possible values of the construction. Otherwise, simulations of real machines would not be possible in a realistic way.
Automatic tracks have three view modes. They can be animated and showing the track, not animated, or not showing the track. The user can switch between these modes with a mouse click.
Painting tracks causes a lot of computation time, especially on Java 1.3.
Then there are tracks of lines. Those tracks contain successive intersections of line positions, when the line moves. This yields a path, such that all lines are tangent to that path. One should use this type only in automatic tracks. The user simply chooses a track of lines by selecting a line object as the object to tracked.
Tracks are painted after all other construction objects.
The user can track more than one point or line. All tracks are kept and handled in the corresponding tool class, which is either the Tracker or ObjectTracker class. Selecting another tool removes the tracks. To keep an image of a track, the user has to fix the current construction to the background.
To animate a construction, the user chooses a point and some objects the point is to move along. The size of these objects determines the resolution of the animation. The program tries to keep the speed of the animation at a constant rate, even on very fast computers. However, on slow computers the animation will slow down below the set speed, if the construction paints very slowly.
Macros are the most complicated part of this program. In theory, a macro runs a sequence of construction steps automatically. The macro depends on a set of points, called its parameters. When running the macro the user may select points from his constructions, and the macro will map those points to its parameters. However, there are special features that complicate the implementation of the macros.
To define a macro, the user starts with a construction. He then chooses the parameters. Usually, the parameters are a set of points in the construction. Then he defines the targets. Targets are not really necessary. But the macro runner is capable of hiding intermediate steps, i.e. all steps besides the targets. It will also assign the current settings for color, style and thickness to the target objects. Moreover, targets are important, if the macro is used in descriptive constructions, since the user may assign a name to the target object in the command line.
When the user presses the macro definition tool to select the targets, only those objects are visible that are constructible from the parameter points. This may be a bit confusing, but the macro cannot do its work otherwise. The user quickly sees what the macro will really construct once it is executed. Note, that even fixed points have to be chosen as parameters and will not be automatically generated by the macro runner.
The final step is to name the macro in the definition dialog. Here, it is possible to set a comment for the macro that explains its purpose. Moreover, it is possible to enter parameter prompts as guidelines for the user, when he runs the macro. Macros normally hide all intermediate steps, or may even super-hide them. We will explain the last item in this dialog later.
When running a macro, the user selects the points, which should be used for the parameter points. The prompt for each parameter will appear in the status line.
Circles and lines can be uses as macro parameters. This will automatically generate secondary parameters. E.g., when a circle is used as a parameter, its center will be usable in the construction, and all objects that depend on it are constructible. The same applies to the two points, which generate a line object.
Fixed circles or angles are constructible from their defining points, and get the values they had in the defining construction each time the macro runs. However, it is possible to prompt the user for that value. To do this, enter the name of the object in the corresponding line of the macro definition dialog. It is possible to enter more than one name here.
In general, expressions in fixed objects are translated properly by the macro runner. References to object values work as expected.
One of the major points is that complicated macros tend to have far too many parameters. Thus it is possible to fix parameters to certain construction objects. The user does this by pressing the shift key while selecting the parameter at run time. After the macro completes, a new macro is generated, which has these parameters fixed and does no longer call for them. Obviously, this macro is useful only for that specific construction. By the way, the fixes are stored by name. It is possible to rename these new macros to something meaningful, and get an easy to use version of the macro tailored for the specific construction problem.
If that mechanism is too complicated, it is possible to select the same parameter as the previous time the macro was run by pressing the space bar.
Finally, there is a useful feature. It is possible to use parameters as hints for the construction. If a parameter point is hidden in the original construction at define time, and if at run time the assigned parameter is a new point, which was generated on the fly during the parameter selection, then this new point will be hidden. Thus the user will be able to click somewhere and this click will generate a hidden point only. Using expressions, the location of this hint can be used to determine an orientation for a specific construction. E.g., the side of a 60 degree angle with respect to a given line may be determined by using the expression "sign(180-1)*60", where a is an angle formed by the hint and two points of the line. Note, that in this case the angle a must be enabled to become obtuse!
It is possible to do constructions by a description. The purpose is to teach students to think about the solution before trying it, and to learn how to describe a construction. The program contains a simple programming language for constructions, which was a major effort to implement.
The user can enter a construction line by line or from an external file.
The line by line input is called descriptive mode. It is entered by switching off the visual mode. The status line takes the input.
The file to read constructions from can be chosen in a file dialog from the file menu. It is also possible to edit this file with an internal editor, but the author prefers to use an external editor.
The programming language is basically quite simple. All lines have the form
names=function(parameters)
It is possible to enter several comma separated names for functions that return several values, and also to give several parameters. The function names are localized, but the English commands can be used everywhere.
External files may also contain macro definitions. To select macro parameter and targets, there are modifier tags. More details are in the documentation. Note that these macros are executed completely, when the file is loaded, so that macro calls in the macros are expanded. This is for ease of implementation.
The program uses XML to store constructions. The file format is quite easy to read, since XML is a text format. Note however, that the files are written in UTF8 encoding by default. The user may switch that off. In that case, the local encoding is used.
Macros may be saved along with constructions, or on their own. Macros with fixed parameters should be saved with the construction, since they may not make much sense otherwise. A macro file is just like a normal constructions, but contains only macros.
Note, that constructions contain information about running animations and tracks. These will be restored, when the construction is loaded. Moreover, grid settings, as well as the view window are saved with the construction too.
The current color settings are not saved with the construction. Rather, these settings are in the configuration file. However, the HTML export will save these settings on demand.
It is possible to pack long constructions to get a shorter file. This helps reducing load time in the Net. C.a.R. uses the gzip format to pack files. This format is very easily read and written in Java. It is possible to unzip these archives with the gzip program, available for Unix and Windows too.
The file extension "zir" should be used for constructions, resp. "zirz" for packed constructions. For macros the file extension "mcr" is reserved.
C.a.R. saves a configuration file named "zirkel.cfg" in the home directory. This file contains all user settings, including colors, most recent tool state, window size and position, command histories and much more.
It is possible to change the home directory with the command line switch "-h path".
It may make sense to make the configuration file "read only". Then user settings will not be saved.
The school mode is a way to restrict the menus and the tools to a necessary minimum. The mode is saved in the configuration file, which should be "read only" in this case.
The icon bar editor is disabled, and thus one can restrict the icon bar to the minimal tools.
Another way to restrict the functionality of the program are applets.
Assignments are construction problems, presented to the user. The main use may be on web pages.
Assignments are generated from constructions by choosing a last object, that the user sees, and choosing target objects. The user may use all objects before this last object including the last object for constructions. But the target objects cannot be used of course. Once all target objects have been constructed, the problem is solved and the user gets a verification. At this point, applets may switch to the solution page automatically.
It is possible to have target objects, which are merely guidelines, and are not checked for the solution. Moreover, it is possible to have hidden target objects. To do this, hide the target, switch the hidden objects on, create the assignment, and switch the hidden objects off to test and save the job.
Jobs are saved in a construction file that looks like any other construction. However, there is a special tag containing the necessary information. The file extension "job" is reserved for assignments, resp. "jobz" for packed jobs.