@Section
    @Tag { dia_geom }
    @Title { Expert usage:  numbers, lengths, angles, and points }
@Begin
@PP
@@Diag has many options whose values contain lengths, angles, and
points.  Options such as @Code margin and {@Code vsize}, which affect the
size or appearance of the base of a node, may contain only the kinds of
lengths described in Section {@NumberOf objects}; but in all other cases
arbitrarily complex algebraic expressions may be used to specify the
values.
@PP
The usual mathematical operations may be applied to numbers, angles, and
lengths:
@ID @Code "2.0f + 3.0f * sin { 30d }"
is a valid length.  Since this is just ordinary algebra on real numbers,
the unsurprising details are deferred to the summary
(Section {@NumberOf dia_summ}).  Grouping is always done with braces,
never parentheses.
@PP
More interesting are the geometrical symbols that @@Diag provides.  The
most fundamental is not a symbol at all:  two lengths side by side define
a point.  For example,
@ID @Code "xsize  ysize * 0.5"
within an outline is the point at the far right of the base, halfway
up.
@PP
There are @Code "++" and @Code "--" symbols for vector addition and
subtraction of two points, and @Code "**" for multiplication by a
scalar.  For example,
@ID @Code "A@CTR ++ { 1.0f 0 }"
is the point @Code 1f to the right of {@Code "A@CTR"}.  It is a good idea
to distinguish between @I { absolute points }, like {@Code "A@CTR"}
and @Code "0.5,1", which denote fixed positions on the page, and
@I { relative points }, like {@Code "1.0f 0"}, which serve as offsets
from absolute points.  The difference of two absolute points is a relative
point; adding two absolute points gives an unpredictable result because
it depends on the origin of the coordinate system.  However, the expression
@ID @Code "P1 ** x ++ P2 ** {1 - x}"
is safe for any two absolute points {@Code P1} and {@Code P2} and any
number {@Code x}; it produces a point on the line through the two
points.
@PP
These remarks on safety do not apply within the @Code outline option of
{@Code "@Node"}, because there the coordinate system is clearly
specified.  Vector operations, with the aid of a few well-chosen tags,
can greatly simplify the production of outlines:
@ID {
@Code {
"@Node"
"   outline {"
"      SB:: {0 ysize} ** 0.4"
"      ST:: {0 ysize} ** 0.6"
"      HB:: {xsize 0} ** 0.7"
"      SB"
"      SB ++ HB"
"      HB"
"      xsize  ysize * 0.5"
"      HB ++ {0 ysize}"
"      HB ++ ST"
"      ST"
"      SB"
"   }"
"   paint { grey }"
"{ 6c @Wide 2c @High }"
}
||7ct
@Diag {
@ShowTags @Node
   outline {
      SB:: {0 ysize} ** 0.4
      ST:: {0 ysize} ** 0.6
      HB:: {xsize 0} ** 0.7
      SB
      SB ++ HB
      HB
      xsize  ysize * 0.5
      HB ++ {0 ysize}
      HB ++ ST
      ST
      SB
   }
   paint { grey }
{ 6c @Wide 2c @High }
}
}
But absolute sums like @Code "SB ++ HB" are not safe
in link paths and stray options like {@Code "alabelpos"}.
@PP
Sometimes it is useful to define tags
which are not wanted afterwards and are better forgotten.  For
this there is the @Code ":=" symbol, which works in much the same
way as @Code "::" except that the tag is forgotten after the outline
or path option ends.  The value assigned does not have to be a point, it
can be a length or angle, or even a sequence of values.  It is
permissible to change the value assigned to a tag by reassigning.
@PP
Two very useful symbols, {@Code angleto} and {@Code atangle}, bring
angleto. @Index { @Code angleto symbol in @Code "@Diag" }
atangle. @Index { @Code atangle symbol in @Code "@Diag" }
angles into the algebra.  The {@Code angleto} symbol finds the angle
from one point to another.  For example,
@ID @Code "SB angleto ST"
in the outline above would produce {@Code 90d}.  The @Code atangle symbol
finds the point at a given length and angle from the origin.  For example,
@ID @Code "1.4142f atangle 45d"
is the point {@Code "1f 1f"}, and
@ID @Code "B@NE  ++ 2f atangle 115d"
is the point @Code 2f from {@Code "B@NE"} to its northwest.
@PP
There is a @Code prev symbol, used only within {@Code outline} and
prev. @Index { @Code prev symbol in @Code "@Diag" }
{@Code path}, which returns the previous point on the outline or
path, ignoring points within {@Code "[]"}.  It makes relative movements
very easy:
@ID {
@Code {
"   outline {"
"      0 0"
"      { 2c atangle 30d }"
"      prev ++ { 2c atangle 90d }"
"      prev ++ { 2c atangle 150d }"
"      prev ++ { 2c atangle 210d }"
"      prev ++ { 2c atangle 270d }"
"      0 0"
"   }"
}
||7ct
@Diag { ||2.5c
@Node
   outline {
      0 0
      { 2c atangle 30d }
      prev ++ { 2c atangle 90d }
      prev ++ { 2c atangle 150d }
      prev ++ { 2c atangle 210d }
      prev ++ { 2c atangle 270d }
      0 0
   }
{ 4c @Wide 4c @High }
}
}
This example is rather naughty because the outline does not grow and
shrink with the base as it should.  Such outlines, while tempting, are
always regretted later.
@PP
There are {@Code xcoord} and {@Code ycoord} symbols for finding the
xcoord. @Index { @Code xcoord symbol in @Code "@Diag" }
ycoord. @Index { @Code ycoord symbol in @Code "@Diag" }
@I x and @I y coordinates of a point:
@ID @Code {
"{xcoord P1} min {xcoord P2}"   "{ycoord P1} max {ycoord P2}"
}
is the point at the top left-hand corner of the smallest rectangle
containing points {@Code P1} and {@Code P2}.  And there is a
@Code distance symbol which produces the (non-negative) distance between
two points:
@ID @Code "CTR  ++  { CTR distance NW } atangle { CTR angleto NW }"
equals {@Code NW}.
@PP
The rest of this section is concerned with how the `special virtue'
of the @Code from and @Code to options, their ability to accept a node
tag as well as a point, is implemented behind the scenes.  A good
user-defined link should also have this virtue, because it is extremely
useful.
@PP
The solution is based on a symbol called {@Code boundaryatangle},
whose preceding object should be either a point or else the tag
of a node with one of the standard shapes, and whose following object
is an angle:
@ID @Code {
"{ xsize ysize*0.5 } boundaryatangle 45d"
"A boundaryatangle 45d"
}
In the first case the result is the point, regardless of the
angle.  In the second case, the result is the point on the boundary of
the node whose tag is given, at the given angle from the centre.
@PP
There is a second symbol with a similar adaptive ability, called
{@Code "??"}, which is defined to be @Code "@" whenever that would
make sense, and otherwise to produce the preceding object for its
result.  For example, @Code "A??CTR" will equal @Code "A@CTR" if there
is such a thing; but
@ID @Code "{ xsize ysize*0.5 }??CTR"
will have result {@Code "{ xsize ysize*0.5 }"} since replacing
@Code "??" by @Code "@" does not produce anything sensible.
@PP
Now suppose we want a link path that connects @Code "from" and
@Code "to" by a straight line, where @Code "from" and @Code "to" may be
either node tags or points.  In either case a suitable direction for the
line to take is
@ID @Code "from??CTR angleto to??CTR"
and so the desired path is
@ID @Code {
"path {"
"    FROM:: from boundaryatangle { from??CTR angleto to??CTR }"
"    TO:: to boundaryatangle { to??CTR angleto from??CTR }"
"    FROM"
"    TO"
"}"
}
The first line defines point @Code FROM to be on the boundary of
@Code from at the appropriate angle, if @Code "from" is a node tag;
otherwise @Code "FROM" is just the point {@Code from}.  The second
line defines point @Code TO similarly, and then the last two lines
join these two points.  The @Code line standard link type is exactly
this plus a few additional tags and directions.
@End @Section
