Command List

Point Commands
Line Commands
Circle Commands
Bézier Commands
Flt Commands
Angle Commands
Arc Commands
Polygon Commands
Conic Commands
Transformation Commands
Miscellaneous Commands

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.pp", which makes a line from two points, will barf if its parameters are not variables representing points.

In what follows, [P] stands for any point identifier, [C], for any circle identifier, and so on. The list of possibilities includes: [P] = point, [L] = line, [C] = circle, [CON] = conic, [BEZ] = Bézier curve, [F] = flt, [X] = transformation, [A] = angle, [ARC] = arc, [P] = polygon. [RPN] = a valid sequence of rpn commands.

Items like [INT], [FLOAT], and [HEX] indicate a fixed, floating point or hex number. [INT2] represents an integer that is 1 or 2; [INT4] can take only the values 1, 2, 3, 4. Hex numbers must have the form 0xhh...h, where h is a hex digit: 0, 1, ..., 9, a, b, ..., f.

Finally, [LAYER] and [COLOR] stand for a valid layer or color specification.

Point Commands

[P] = .free([FLOAT], [FLOAT]);
Make a completely unconstrained point whose initial coordinates are given by the two floating-point numbers. The coordinate system goes roughly from -1.0 to 1.0 in each direction, but obviously if the window is non-square, this isn't right. With a non-square window, the smaller dimension goes from -1.0 to 1.0; the larger dimension is scaled appropriately. The point (0,0) is always exactly in the center of the drawing area.

[P] = .pinned([FLOAT], [FLOAT]);
Exactly the same as .free, except that the new point cannot be dragged with the mouse.

[P] = .vonl([L], [FLOAT], [FLOAT]);
Make a point constrained to be on the line, so it has one degree of freedom. The floating point values are the point's initial coordinates (which need not be exactly on the line -- the point will instantly be projected to the line for the first display).

[P] = .vonc([C], [FLOAT], [FLOAT]);
Make a point which is constrained to be on the circle, so it has one degree of freedom. The floating point values are the point's initial coordinates (which need not be on the circle -- the point will instantly be projected to the circle for the first display).

[P] = .v.ff([F], [F]);
The values of the [F]s are evaluated, and used as the point's x and y coordinates.

[P] = .v.vvmid([P], [P]);
Make a point constrained to be the midpoint of the other two points.

[P] = .v.ll([L], [L]);
Make a point constrained to be at the intersection of the two given lines, or at infinity in the appropriate direction if the lines are parallel.

[P] = .v.lc([L], [C], [INT2]);
The point 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 either 1 or 2.

[P] = .v.cc([C], [C], [INT2]);
The point 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.

[P] = .v.vvf([P], [P], [F]);
A new point is constructed between the first and second point parameters in the ratio given by [F]. If [F] is zero, the new point will be on top of the first point. If the ratio is 1, it will be on top of the second. If the ratio is 2/3, it will be 2/3 of the distance between the first and second given points. Ratio values outside the range [0,1] also make sense and are interpreted in the obvious way—a ratio of -1 would put the point on the opposite side from the second point of the first, and with a distance equal to the distance between the given points.

[P] = .v.avv([A], [P], [P]);
A new point is made that makes an angle with the other two points equal to the given angle. The angle is measured in a counter-clockwise direction.

[P] = .v.ccenter([C]);
The new point is at the center of the given circle.

[P] = .v.lvmirror([L], [P]);
The mirror image of the point through the line is generated.

[P] = .vonconic([CON], [FLOAT], [FLOAT]);
The point is forced to remain on the given conic section. The two floats are the current coordinates.

[P] = .v.vcinv([P], [C]);
Inverts the given point through the circle.

[P] = .v.lconic([L], [CON], [INT2]);
The point is at the intersection of the line and the conic section. There are up to 2 possibilities, so [INT2] can be 1 or 2.

[P] = .v.vvvbisect([P], [P], [P]);
The new point is on the angle bisector of the angle formed by the other three points. It is on the inside of that angle.

[P] = .v.vx([P], [X]);
The new point is the old one with the given transformation applied.

[P] = .v.vtranslate([P], [F], [F]);
Construct the new point by translating the old one by the first flt in the x-direction and by the second in the y-direction.

[P] = .v.vscale([P], [F], [F]);
The new point is the old point scaled by the first flt in the x-direction and by the second in the y-direction.

[P] = .v.vrotate([P], [F]);
Construct the new point by rotating the old one by flt counter-clockwise about the origin. The angle represented by flt is dependent on the degreemode.

[P] = .v.lcvother([L], [C], [P]);
The new point is at the intersection of the line and the circle and is guaranteed to be different from the given point.

[P] = .v.ccvother([C], [C], [P]);
The new point is at the intersection of the two circles and is guaranteed to be different from the given point.

[P] = .v.vvvharmonic([P], [P], [P]);
A new point is the harmonic conjugate of the first three. If the first three points are called A, B, and C, the result, X, satisfies H(AC, BX).

Line Commands

[L] = .l.vv([P], [P]);
The new line passes through the two given points.

[L] = .l.vlperp([P], [L]);
A new line is constructed, passing through the given point and perpendicular to the given line.

[L] = .l.vlpar([P], [L]);
A new line that passes through the given point and is parallel to the given line is constructed.

[L] = .l.vc([P], [C], [INT2]);
A new line which passes through the point and is tangent to the given circle is constructed. In general, there are two possibilities, so [INT2] is 1 or 2.

[L] = .l.ccext([C], [C], [INT]);
The new line is an exterior tangent to the two given circles. [INT2] is 1 or 2, since there are two possibilities.

[L] = .l.ccint([C], [C], [INT2]);
The new line is an interior tangent to the two given circles. [INT2] is 1 or 2, since there are two possibilities.

[L] = .l.conicv([CON], [P], [INT2]);
Constructs a line tangent to the conic that passes through the point. There are 2 possibilities, so [INT2] must be 1 or 2.

[L] = .l.vvperp([P], [P]);
This line is the perpendicular bisector of the segment connecting the two points.

Circle Commands

[C] = .c.vv([P], [P]);
The new circle is constrained to have its center at the first point, and to pass through the second.

[C] = .c.vvv([P], [P], [P]);
A new circle that passes through all three points is constructed.

[C] = .c.lll([L], [L], [L], [INT4]);
A circle that is tangent to all three lines is constructed. There are, in general, 4 possibilities, so [INT4] is 1, 2, 3, or 4. The usual circle—the one that sits inside the triangle determined by the three lines—has [INT4] equal to 1.

[C] = .c.vf([P], [F]);
The circle has a center at the point, and a radius equal to the value of flt.

[C] = .c.ccinv([C], [C]);
The new circle is the inverse of the first circle through the second circle.

[C] = .c.lcinv([L], [C]);
The new circle is the inverse of the line through the circle.

[C] = .c.vcrad([P], [C]);
Constructs a circle centered at the point, and having the same radius as the given circle. This emulates a compass for straight-edge and compass constructions.

Bézier Commands

[BEZ] = .bez.vvvv([P], [P], [P], [P]);
A new cubic B&eacure;zier curve is constructed having the four points as control points.

Flt Commands

[F] = .f.rpn([RPN]);
An [RPN] list is a set of comma-separated tokens that are chosen from among flt, angle, float, and stack commands. The stack commands are listed above. The sequence is evaluated as if it were a PostScript program, and the top number on the stack is the final value of flt. If there's an error, flt is set to something huge and no error is reported.

[F] = .f.vv([P], [P]);
flt is set to the distance between the points.

[F] = .f.area([POLY]);
flt is set to the area of the polygon.

[F] = .f.vvvratio([P], [P], [P]);
Calculates the ratios of the distances between the first and second and second and third points.

[F] = .script([FLOAT], [FLOAT], [FLOAT]);
Only one of these commands can appear in a file. The three floats are interpreted as the minimum value, maximum value, and step size. If this command appears, when the run script button is pressed, the value of flt is set to the minimum value, and is incremented by the step size until it is larger than the maximum value. Then the script stops.

[F] = .f.vxcoord([P]);
The x coordinate of point is assigned to flt.

[F] = .f.vycoord([P]);
The y coordinate of point is assigned to flt.

Angle Commands

[A] = .a.vvv([P], [P], [P]);
The new angle is centered at the second of the three points, and has as edges rays from the center to the other two points.

[A] = .a.f([F]);
This makes an angle of size flt. The [F] can be interpreted as either degrees or radians, depending on Geometer's mode.

Arc Commands

[ARC] = .arc.vvv([P], [P], [P]);
Similar to the angle command, but the arc drawn is centered on the second point and has a radius such that it begins at the first point. It ends on the line from the second to the third point, and goes in a counter-clockwise direction.

Polygon Commands

[POLY] = .polygon([INT], [P], ..., [P]);
The value of [INT] is the number of points to follow -- it must be between 3 and 10, inclusive.

Conic Commands

[CON] = .conic.vvvvv([P], [P], [P], [P], [P]);
Five points determine a conic section passing through all of them.

[CON] = .conic.lllll([L], [L], [L], [L], [L]);
Construct a conic section tangent to all five lines.

Transformation Commands

[X] = .x.identity();
Makes the identity transformation.

[X] = .x.rotate([X], [F]);
Add a rotation with xform to make a new one flt is the rotation in degrees or radians, depending on the mode of geometer.

[X] = .x.scale([X], [F], [F]);
Add a scale to the given xform. The two flts represent x- and y- scaling.

[X] = .x.translate([X], [F], [F]);
Add a translation to the given xform. The two flts represent x- and y- translation.

[X] = .x.xxf([X], [X], [F]);
If the value of flt = 0, the first xform is used; otherwise the other. This is a way to get a conditional transformation.

[X] = .x.f9([X], [F], ..., [F]);
There are nine flt values that are used as entries into a transformation matrix which is then multiplied by the given xform to make a new one. The new transformation matrix is filled as follows, assuming the flt values are numbered 0 to 8 as they appear above:

  | flt0  flt1  flt2  |
  | flt3  flt4  flt5  |
  | flt6  flt7  flt8  |

Miscellaneous Commands

.layercondition([F], [F], [F], [HEX]);
If the value of the second flt lies between the values of the first and third, set the layers to the value of the hex number. This is generally used in scripts. Here's an example that turns on layer 1 for the first third of the script, layer 2 for the second third, and layer 3 for the final third:

            f = .script(0, 1, .02);     // steps of .02
            .layercondition(0.0, f, .3333333, 0x1);
            .layercondition(.3333333, f, .6666666, 0x2);
            .layercondition(.6666666, f, 1.0, 0x4);

Generally the first and third flt values are constants, but that's not required.

.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.

There are some special characters you can insert in the text. See the section on text for more information on how to add characters like some of these: ∠, Δ, ≅.

// comment text ...
Any line beginning with "//" is ignored, but is saved and printed in any output files generated.

[COLOR] = ([FLOAT], [FLOAT], [FLOAT]);
[COLOR] can be replaced by any of the valid color identifiers, usually .c8, .c9, ..., .c31, but it can be the default colors as well. The command above sets the red, green, and blue components for the given color identifier. For example to make .c18 have red, green, and blue components of .1, .2, and .3, respectively, include the following command:

            .c18 = (.1, .2, .3);

These definitions can be placed anywhere in the file, but they are only evaluated once as the file is parsed. When the file is saved, they will be written out at the top of the file. .c8 through .c15 have some interesting initial colors; .c16 through .c31 are initially white.

It's a good idea to make the three values between 0.0 and 1.0.

[LAYER];
[LAYER] stands for any valid layer identifier, for example .l0, .l1, ..., .l31, or .l0on, .l1on, ... , .l31on; These are default layers for the file and are treated exactly as are the default colors.

.degreemode; or .radianmode;
Sets the mode for printing and reading angles. Geometer is in degreemode by default;

.macro
These are covered in under macro definitions.