Here's how to do the triangle example using a triangle macro:
.geometry "version 0.2";
.macro triangle(.vertex v1, .vertex v2, .vertex v3)
{
l1 = .l.vv(v1, v2);
l2 = .l.vv(v2, v3);
l3 = .l.vv(v3, v1);
}
v1 = .free(-0.764826, 0.554192, "1");
v2 = .free(-0.515337, 0.766871, "2");
v3 = .free(-0.384458, 0.300613, "3");
v4 = .free(0.265849, 0.476483, "4");
v5 = .free(0.703476, 0.595092, "5");
v6 = .free(0.658487, -0.0429448, "6");
triangle(v1, v2, v3);
triangle(v4, v5, v6);
The macro triangle takes three parameters, all of which are points, and from them it constructs three lines. Each time it is called, it generates a new set of three lines from the given points.
At present, the macro facility is rather simple-minded -- parameters can be any of the usual types: .vertex, .line, .circle, .flt, .conic, et cetera.
If a name within the macro is either a parameter name or is a name of an item produced within the macro, that local version is used. If it is not a parameter name or locally generated item, Geometer assumes that it is a global value.
For example, the following macro will draw a line from the point that's a parameter "v" to the fixed point v0:
v0 = .pinned(0, 0);
.macro linetozero(.vertex v)
{
l1 = .l.vv(v0, v);
}
Macros can return a single value. For example, here is the syntax for a macro that takes two points and returns a circle having the two points as a diameter:
.macro .circle diamcircle(.vertex v1, .vertex v2)
{
vmid = .v.vvmid(v1, v2, .in);
.return c = .c.vv(vmid, v1);
}
v1 = .free(-0.2975, -0.12);
v2 = .free(0.1975, -0.1825);
v3 = .free(0.045, 0.3225);
c1 = diamcircle(v1, v2, .red);
c2 = diamcircle(v1, v3, .green);
Note that the point "vmid" is colored invisible so that it doesn't show up every time you make a new circle. Note also that the macro calls that produce c1 and c2 can have properties. In this case, the two different expansions of the macro will draw a red and a green circle. If you want, you can then use c1 or c2 in future constructions.
There is a known bug in the Geometer macro package that does not allow you to pass .flt parameters that are constant. For example, the following code will not work to generate a point with coordinates (.3, .3):
.macro .vertex v(.flt f)
{
.return vv = .v.ff(f, f);
}
v1 = v(.3);
You can get around the bug with this minor modification to the code, since as long as the .flt parameter is not constant, the macro code works fine:
.macro .vertex v(.flt f)
{
.return vv = .v.ff(f, f);
}
f3 = .f.rpn(.3);
v1 = v(f3);