home *** CD-ROM | disk | FTP | other *** search
- Geometer illustrates geometric theorems and proofs. It also contains code
- that solves 2-D constraint problems, and illustrates an interesting
- form of user interface that allows both a graphical and a textual
- interaction. This version will work with a standard system 5.2
- installation. Geometer uses the program "jot" to do its text
- manipulation, and uses jot's file browser (/usr/lib/jot/browsegizmo) for
- its file browser.
-
- As an example, try running geom on the theorem "Medians.T" by typing:
-
- geometer Theorems/proofs/Medians.T
-
- As the text at the bottom of the window explains, this example
- illustrates the fact that the three medians of a triangle always meet
- at a point. Try mousing down on one of the vertices labelled A, B, or
- C with the left mouse and move it around. The triangle changes shape,
- but watch the intersection of the three medians.
-
- After you have convinced yourself that the theorem is true (or at least
- approximately so, to the precision of the machine), you can see a proof
- by clicking on the button labelled "next" in the upper right portion of
- the controls area. Each click of the "next" button takes you one step
- further through the proof. In this example, the proof takes only two
- steps. You can go back to the beginning with the "start" button, and
- you can go back one step in the proof with the "prev" button.
-
- At any stage in the proof, the free vertices can still be moved around
- to show how constructed lines, etc. change with different
- configurations of the problem.
-
- In any of the example files, the left mouse button can drag the free
- vertices. Only vertices can be moved, however. Everything else is
- ultimately defined in terms of free vertices or partially constrained
- vertices (vertex on a line, on a circle, etc.).
-
- For a far more interesting theorem and proof, try loading the example
- called Theorems/proofs/Ninepoint.T.
-
- Try any of the other examples. Most do not yet have a proof built in,
- but the theorems are explained in the accompanying text. There is some
- junk mixed in as well, but an attempt has been made to sort the example
- files into subdirectories. All the example files for geometer have the
- suffix ".T", although it's not required.
-
- The constraint evaluation code is pretty robust, and "reasonable" things
- happen if you ask to find the intersection of parallel lines, etc.
-
- Geometer Documentation:
-
- The program is invoked as:
-
- geometer
-
- or
-
- geometer <filename>
-
- where <filename> is a geometry file in the correct format.
-
- The geometric primitives currently include:
-
- vertices, lines, circles, bezier curves, lengths, ratios,
- conics, and angles
-
- Not all are accessible from the button interface, and lengths, ratios,
- and angles are all stored internally in the same way -- as a floating
- point number. In other words, you can multiply an angle by an angle,
- and geometer won't care, although it doesn't make much sense
- geometrically.
-
- To create a vertex, click on "New Vert", and then click in the black
- area. If you middle-click most buttons like "New Vert", you can
- make as many as you want. Click a new button, or in some blank space
- in the controls area to get out of multiple creation mode.
-
- There is a small feedback window that displays the status -- namely,
- what geometer expects you to do next. In basic mode, it's just waiting for
- you to select a vertex and move it, or to pick a new command from the
- menu.
-
- Under "Make Vert" are a number of ways to make a new vertex. They are:
-
- New Vert: click in a free vertex
- L,L=>V: make a vertex thats at the intersection of 2 lines
- VVmid: make a vertex at the midpoint between 2 vertices
- V on L: make a vertex constrained to lie on a given line
- V on C: make a vertex constrained to lie on a given circle
- L,C=>V vertex at intersection of a line and circle (there
- are up to 2 solutions; click near the one you want.)
- C,C=>V same as above, but at the intersection of 2 circles
-
- For making lines:
-
- V,V=>L make a line connecting 2 vertices
- V,L=>Lprp construct the line perpendicular to a line and passing
- through the vertex
- V,L=>Lpar construct the line parallel to a line and passing
- through the vertex
- V,C=>L make a line through a vertex and tangent to a circle
- C,C=>Lext make a line externally tangent to two circles
- C,C=>Lint make a line internally tangent to two circles
-
- For circles:
-
- Ctr,Edg=>C use the first vertex as the center, the second as a
- point on the radius.
- V,V,V=>C make a circle through 3 vertices.
-
- For conics:
-
- 5*V=>Conic Make a conic through 5 points.
-
- Lines can be infinite (Line), semi-infinite (Ray), or finite (Segment).
- Select a line and click on the correct button to change the line type.
- It also changes the mode, so all lines afterwards will have the new
- type.
-
- Click on a color to change the color of the selected thing, and to set
- the current color. The special color "Inv" is invisible. The object's
- constraints will be satisfied, but the object will be invisible. This
- is great for hiding construction lines. The color "Sm" stands for
- "Smear". Items painted the smear color will smear as a vertex is
- dragged around.
-
- "Show Invis" toggles whether invisible lines are shown. If they are not
- shown, they can't be selected.
-
- "Show Info" toggles whether the text descriptions are shown. If the screen
- is too cluttered, you may want to turn descriptions off.
-
- "Set color" allows you to click on an object to change its color. You
- usually want to middle click it so you can change lots of colors.
-
- There is a pull-down menu bar along the top of the window. Under the
- "File" heading are commands to save files, visit new files, and so on.
- All file name specification is done using the Showcase file browser, so
- Showcase has to be installed to use these commands. If you don't have
- Showcase installed, you can still run geometer on individual files from
- the shell command line.
-
- The "Print" command makes a PostScript file and calls lp on it, if a
- printer is magically hooked up in the right way, you can get a picture
- of what's on the screen. Invisible lines will be displayed as dotted
- lines in your print, if you are showing invisible lines when you issue
- the print command. (There's no feedback that the printing was
- successful, so don't go banging away on the button, or you'll get lots
- of copies.)
-
- The "Print EPS" makes an encapsulated PostScript file called geom.eps,
- but does not send it to the printer.
-
- There's also a hack for getting postscript-like output during a smear
- operation. Alt-x toggles it on and off, and while it is on, PostScript
- for the smeared primitives is dumped to standard output. To use it,
- you'll have to capture the output and hand-edit it into a file, but it's
- better than nothing.
-
- Alt-l (that's lowercase L) draws all the lines double width which
- improves the appearance for demos sometimes.
-
- Under the "Edit" menu are the commands "Delete", "Edit Source", and
- "Describe Item".
-
- "Delete" deletes the current selection if possible. It can't do so if
- some other geometric object depends on it.
-
- "Edit Source" fires up the jot text editor on the text form of the file and
- rereads the modified file when jot exits. Jot does it's work on the
- file /tmp/geom.x. If jot is not installed, you can't use the edit
- command; however, you can edit the file from another editor, and
- repeatedly view it from geometer. It's much easier just to install jot,
- however.
-
- Finally, "Describe Item" gives a short textual description of the
- selected item. When possible, it gives the names displayed on the
- screen, but if the item has no displayed name, it gives the internal
- name. Displayed names are presented in double quotes; internal names
- are enclosed within parentheses.
-
- The arrow buttons between the main keyboard and the numeric key pad move
- the entire figure up, down, left, and right a little bit. They are used
- primarily for small adjustments of the entire figure prior to printing.
- Similarly the "Page Up" and "Page Down" keys in the cluster above the
- arrow keys increase and decrease the size of the figure by factors of
- 1.01 and 1/1.01, respectively. This zooming is relative to the center
- of the display area.
-
- Layers
-
- There are 16 layers (0 through 15). Geometry can appear on any or all
- the layers. The layers currently being viewed are highlighted in the
- layer display in the controls area. Layers can be enabled or disabled
- by clicking in the appropriate boxes. "on" turns on all the layers;
- "start" turns off all but layer 0, "next" increases the number of all
- the visible layers by one, and "prev" decreases by one all the visible
- layers.
-
- When you create geometry, it appears on all the layers indicated. When
- you display the drawing, any items that have any layers in common with
- the currently active layers are drawn.
-
- File Format
-
- If you muck with the files with an editor (like jot in interactive
- mode), the format is C-like. I've designed it to be easy to extend,
- but I have only a primitive parser now, and a lot of obvious things
- can't yet be done. Look at the sample theorem files for examples.
- Here's a quick explanation of some of the commands:
-
- Any word beginning with a period (".") is reserved.
-
- Variables are defined by their first appearance. After it has been
- defined, a variable can be used in future definitions. Variables stand
- for any of the geometric primitives. For example, here's a complete
- file that defines two points and a line connecting them:
-
- .geometry "version 0.1";
- v1 = .free(-0.293478, 0.222826, "1");
- v2 = .free(0.358696, -0.0163043, "2");
- l1 = .l.vv(v1, v2);
-
- The first line is currently optional, but it's a good idea to include it
- for future upward compatibility.
-
- The second and third lines define two free vertices called v1 and v2
- ("free" means that they can be moved with the left mouse button). The
- coordinates are initial positions on the screen (normally, geometer's
- coordinate system displays data in the range -1.0 <= x, y <= 1.0).
- Finally, the "1" and "2" represent the names to be displayed.
-
- Finally, the line l1 is defined to be the line passing through the two
- vertices v1 and v2. l1 has no name.
-
- Properties
-
- Every geometric primitive has a few properties associated with it.
- These currently include such things as color, layer, name, line-type
- (if it's a line), and vertex type (if it's a vertex).
-
- There are default values for each property, and if none is specified in
- a primitive's description, the default is used. The defaults are:
-
- color: white (color index 7, really)
- name: none
- layer: all (0-15)
- line-type: segment
- vertex-type: diamond
-
- Any property information in a primitive's description overrides the
- default. For example, the line:
-
- vert23 = .free(0.0, 0.0, .red, .cross, "foo");
-
- defines a vertex with internal name vert23, displayed name "foo", drawn
- in red, and shaped like a cross. Since nothing about layers was stated,
- it will be in all layers (the default).
-
- Each primitive description has a few required fields, and after all
- those have been filled in, any combination of properties may be
- specified.
-
- The overriding properties can appear in any order, and there is no error
- if inconsistent data is given. The later data overrides the earlier
- data. For example:
-
- vertex561 = .free(0.0, 0.0, .red, .green);
-
- will be drawn in green.
-
- If no layer information is given, the primitive will appear on all
- layers; if any layer information is given, the primitive will be drawn
- on all and only the layers given. For example:
-
- vv = .free(0.0, 0.0, .L2, .L3, .L4);
-
- will be drawn only on layers 2, 3, and 4.
-
- If line-type information is given for a non-line or vertex-type
- information for a non-vertex, it is ignored.
-
- Here is a list of all the allowed properties:
-
- line-types
-
- .segment -- joins the two endpoints
- .ray -- starts at the first point and goes
- forever through the second
- .longline -- infinite line through the two vertices
-
- vertex-types
-
- .diamond, .plus, .cross, .nomark, .soliddiamond
-
- colors
-
- .black = .c0 -- black
- .red = .c1 -- red
- .green = .c2 -- green
- .yellow = .c3 -- yellow
- .blue = .c4 -- blue
- .magenta = .c5 -- magenta
- .cyan = .c6 -- cyan
- .white = .c7 -- white
- .c8, .c9, ..., .c31 -- color map colors 8 through 31
- .invisible -- not drawn
- .smear -- color smears while vertex is dragged
- .blink -- blinking yellow and black
-
- layers
-
- .L0, .L1, ..., .L15
-
- names
-
- anything enclosed in "double quotes".
-
- If a length, ratio, or angle is assigned a name, it's numerical value is
- displayed to the left of the figure. If there's no name, the value is
- hidden.
-
- Constraints
-
- Every primitive is defined in terms of constraints. In one of the
- examples above, ".l.vv" defines a line constrained to pass through two
- given vertices.
-
- Most of the constraints are of the form: .x.yyyy, where the first part,
- "x" is what's being made (v=vertex, l=line, c=circle, ...). The next
- entries are the things from which it's made. (.v.ll, for example, makes
- a vertex that's the intersection of 2 lines.) Sometimes there's more,
- like .l.vlperp (which makes a line passing through a vertex, and
- perpendicular to a given line.
-
- If there are multiple possibilities, there may be an integer to tell
- which one, for example:
-
- vv = .v.cc(circ1, circ2, 1);
-
- makes a vertex at the intersection of two circles. Replace the "1" with
- a "2" to get the other intersection.
-
- Here are forms of the rest of the recognized commands. Note that the
- set may increase in the future as new primitives are added. There is no
- possibility of conflict with user-defined names, since all the new
- primitives will be defined with names beginning with a period.
-
- In the listing below, only the required fields are specified; any number
- of additional properties can be specified in any order. The types of
- the parameters are important and are checked. For example, ".l.vv",
- which makes a line from two vertices, will barf if its parameters are
- not variables representing vertices.
-
- In what follows, "vertex" stands for any vertex identifier, "circle", for
- any circle identifier, and so on. Remember that "length", "angle", and
- "ratio" are all synonyms and can be used interchangeably. However, a
- ratio constructed in one insturction will usually be used in another
- line where "ratio" is specified as the input type.
-
- vertex = .free(<float>, <float>);
-
- Make a completely unconstrained vertex whose initial coordinates
- are given by the two floating-point numbers.
-
- vertex = .vonl(<float>, <float>, line);
-
- Make a vertex constrained to be on the line, so it has one
- degree of freedom. The floating point values are the vertex's
- initial coordinates (which need not be on the line -- the
- vertex will instantly be projected to the line for the first
- display).
-
- vertex = .vonc(<float>, <float>, circle);
-
- Make a vertex constrained to be on the circle, so it has one
- degree of freedom. The floating point values are the vertex's
- initial coordinates (which need not be on the circle -- the
- vertex will instantly be projected to the circle for the first
- display).
-
- vertex = .v.vvmid(vertex, vertex);
-
- Make a vertex constrained to be the midpoint of the other two
- vertices.
-
- vertex = .v.ll(line, line);
-
- Make a vertex constrained to be at the intersection of the
- two given lines.
-
- vertex = .v.lc(line, circle, <integer>);
-
- The vertex is at the intersection of the line and the circle.
- Since there are two possible intersections, they are
- distinguished by the value of the integer, which must be 1 or
- 2.
-
- vertex = .v.cc(circle, circle, <integer>);
-
- The vertex is at the intersection of the two circles. Since
- there are two possible intersections, they are distinguished by
- the value of the integer, which must be 1 or 2.
-
- vertex = .v.vvratio(vertex, vertex, ratio);
-
- A ratio is basically a floating point value that represents
- the distance between a pair of points. It is 0.0 at the
- first point, and 1.0 at the other. Numbers outside this
- range represent points on the line outside the endpoints.
- Ratios are constructed like any other primitive (see below).
- This constructs a new vertex having the given ratio between
- the given vertices.
-
- vertex = .v.avv(angle, vertex, vertex);
-
- A new vertex is constructed such that the angle formed
- using it and the other two vertices is equal to the given
- angle.
-
- vertex = .v.ccenter(circle);
-
- The vertex is at the center of the given circle.
-
- vertex = .v.lvmirror(line, vertex);
-
- The mirror image of the vertex through the line is generated.
-
- vertex = .vonconic(conic, <float>, <float>);
-
- Constrains the vertex to be on the given conic section.
-
- vertex = .v.vcinv(vertex, circle);
-
- Inverts the given vertex through the circle.
-
- vertex = .v.lconic(line, conic, <integer>);
-
- The vertex is at the intersection of the line and the
- conic section. There are up to 2 possibilities, so
- <integer> can be 1 or 2.
-
- line = .l.vv(vertex, vertex);
-
- The new line passes through the two given vertices.
-
- line = .l.vlperp(vertex, line);
-
- A new line is constructed, passing through the given
- vertex and perpendicular to the given line.
-
- line = .l.vlpar(vertex, line);
-
- A new line is constructed, passing through the given
- vertex and parallel to the given line.
-
- line = .l.vc(vertex, circle, <integer>);
-
- The new line passes through the vertex and is tangent to
- the given circle. In general, there are two possibilities,
- so <integer> is 1 or 2.
-
- line = .l.ccext(circle, circle, <integer>);
-
- The new line is an exterior tangent to the two given
- circles. <integer> is 1 or 2, since there are two
- possibilities.
-
- line = .l.ccint(circle, circle, <integer>);
-
- The new line is an interior tangent to the two given
- circles. <integer> is 1 or 2, since there are two
- possibilities.
-
- line = .l.conicv(conic, vertex, <integer>);
-
- Constructs a line tangent to the conic, and passing through
- the vertex. There are 2 possibilities, so <integer> is 1
- or 2.
-
- circle = .c.vv(vertex, vertex);
-
- The new circle is constrained to have its center at the
- first vertex, and to pass through the second.
-
- circle = .c.vvv(vertex, vertex, vertex);
-
- The new circle passes through all three vertices.
-
- circle = .c.lll(line, line, line, <integer>);
-
- The new circle is tangent to all three lines. There are,
- in general, 4 possibilities, so <integer> is 1, 2, 3, or 4.
-
- circle = .c.vlen(vertex, length);
-
- The circle has a center at the vertex, and a radius equal
- to the length. Length is a primitive that must already be
- defined. See below.
-
- circle = .c.ccinv(circle, circle);
-
- The new circle is the inverse of the first circle
- through the second circle.
-
- circle = .c.lcinv(line, circle);
-
- The new circle is the inverse of the line through the circle.
-
- bezier = .bez.vvvv(vertex, vertex, vertex, vertex);
-
- A new cubic Bezier curve is constructed having the four
- vertices as control points.
-
- ratio = .ratio.vvv(vertex, vertex, vertex);
-
- A ratio is constructed using the distances between the
- three vertices. This will make much better sense if the
- three vertices happen to fall on a line.
-
- length = .len.vv(vertex, vertex);
-
- The length is the length between the two vertices.
-
- length = .len.plus(length, length);
-
- The new length is the sum of the two given lengths.
-
- length = .len.minus(length, length);
-
- The new length is the sum of the two given lengths.
-
- length = .len.times(length, length);
-
- The new length is the sum of the two given lengths.
-
- length = .len.divide(length, length);
-
- The new length is the sum of the two given lengths.
-
- length = .len.f(<float>);
-
- The value of length is given by a floating point number.
-
- angle = .a.vvv(vertex, vertex, vertex);
-
- The angle is the angle made by the three vertices.
-
- conic = .c.vvvvv(vertex, vertex, vertex, vertex, vertex);
-
- Make a conic section passing through the five vertices.
-
- conic = .c.lllll(line, line, line, line, line);
-
- Make a conic section tangent to the five lines.
-
- .text("Any text you want.");
-
- Makes a line of text to be displayed at the bottom of the
- screen. The order in which text lines appear dictates the
- order in which they are displayed. In the current
- implementation, at most 8 lines are visible. Use the
- text in combinations with layers for more information.
-
- // any comment text in the world.
-
- Any line beginning with "//" is ignored, but is saved and
- printed in any output files generated.
-
-
- Programming hints:
-
- If you want a demonstration where more and more information appears each
- time you press the "next" button, draw your initial figure with all
- layers enabled. Then disable layer 0, and draw the next set of stuff,
- then disable layer 1 and draw the next set, and so on.
-
- Lots of constructions can be accomplished using the tools provided, and
- then "erased" using the invisible color.
-
-
-