@Section
   @Title { Putting it all together }
   @Tag { together }
@Begin
@PP
In this section we consider the problem of linking individual shapes
together to form complex diagrams like this one:
@ID @Fig {
@Frame { 10c @Wide 6c @High }
// X**0.1 ++ Y**0.4 @BaseOf A:: @Square { @I A }
// X**0.4 ++ Y**0.7 @BaseOf B:: @Square { @I B }
// X**0.6 ++ Y**0.1 @BaseOf C:: @Square { @I C }
// X**0.8 ++ Y**0.6 @BaseOf D:: @Square { @I D }
// A @JoinFigures arrow { forward } B
// A @JoinFigures arrow { forward } C
// B @JoinFigures arrow { forward } C
// B @JoinFigures arrow { forward } D
// C @JoinFigures arrow { forward } D
}
We already have several aids to hand:  the basic graphics symbols
for rotation and scaling, the ability to nest text, equations, and other
figures (in fact arbitrary Lout objects) within our shapes; and the
ability to define our own symbols.
@PP
Two other useful aids are the horizontal and vertical concatenation
symbols from raw Lout:
@ID @Code "A  |1.0c  B"
causes @Code A and @Code B to appear side by side, one centimetre
horizontal.con @Index { horizontal concatenation }
concatenation @Index { concatenation }
apart (this is horizontal concatenation).  In general, @Code A and
@Code B may be arbitrary objects, and any length is acceptable
immediately after the @Code "|" symbol.  Similarly,
@ID @Code "A  /1.0c  B"
makes @Code A and @Code B appear with @Code B directly beneath {@Code A}
vertical.con @Index { vertical concatenation }
(this is vertical concatenation), again with a one centimetre
separation.  You could use tables to get the same effects.  Vertical
concatenation often appears below in the special form {@Code "//"},
which roughly means vertical concatenation with zero separation.
@PP
The default values of the various options -- @Code "solid" for
{@Code linestyle}, @Code noarrow for {@Code arrow}, and so on -- may be
changed by giving options to the @Code "@Fig" symbol:
@ID {
@Code {
"@Fig"
"   linestyle { noline }"
"   paint { black }"
"{"
"   @Circle |1c @Square"
"   /1c @Diamond | @Polygon"
"}"
}
||7ct
@Fig
   linestyle { noline }
   paint { black }
{
    @Circle |1c @Square
   /1c
   @Diamond | @Polygon
}
}
A complete list of options is given in the next section.
@PP
@Code "@Fig" provides another aid:  the symbols {@Code "@BaseOf"} and
base.of @Index @Code "@BaseOf"
mark.of @Index @Code "@MarkOf"
{@Code "@MarkOf"}.  The right parameter of {@Code "@BaseOf"} is an
arbitrary object, and its left parameter is a point.  As far as Lout
is concerned, the result of @Code "@BaseOf" is always an empty object;
but the right parameter will appear on the page with the bottom left-hand
corner of its base at the point denoted by the left parameter.  We stress
that Lout has no idea that this is happening, and so cannot prevent the
shifted object from writing over other objects or even going off the edge
of the page.  Of course, this lack of discipline is just what is needed
very often in diagrams.
@PP
The @Code "@MarkOf" symbol works in a similar way, except that the point
where the object's alignment marks cross (rather than its bottom left-hand
corner) will appear on the page at the point denoted by the left parameter.
@PP
We can set up a coordinate system for a figure:
@ID @OneRow @Code {
"@Figure shape { xsize 0 @Label X  0 ysize @Label Y }"
"{ 10c @Wide 6c @High }"
}
In fact, Fig contains this shape under the name {@Code "@Frame"}, so we
frame. @Index @Code "@Frame"
need only write
@ID @Code "@Frame { 10c @Wide 6c @High }"
Of course, the right parameter may contain an arbitrary Lout object.
@PP
Once the frame is set up, we can specify points by their @Code X and
@Code Y coordinates, as fractions of the total width and height:
@ID @Code "X ** 0.5  ++  Y ** 0.8"
To place the squares in the diagram above, we can use
@ID @OneRow @Code {
"//  X**0.1 ++ Y**0.4  @BaseOf  A:: @Square { @I A }"
"//  X**0.4 ++ Y**0.7  @BaseOf  B:: @Square { @I B }"
"//  X**0.6 ++ Y**0.1  @BaseOf  C:: @Square { @I C }"
"//  X**0.8 ++ Y**0.6  @BaseOf  D:: @Square { @I D }"
}
The symbols' precedences are chosen so that this very common situation
requires no braces.  The result of this is
@ID @Fig {
@Box margin { 0c } @Frame { 10c @Wide 6c @High }
// X**0.1 ++ Y**0.4 @BaseOf A:: @Square { @I A }
// X**0.4 ++ Y**0.7 @BaseOf B:: @Square { @I B }
// X**0.6 ++ Y**0.1 @BaseOf C:: @Square { @I C }
// X**0.8 ++ Y**0.6 @BaseOf D:: @Square { @I D }
}
{@PageMark sumpoints} where we have drawn a box with margin 0 around the
frame to make its extent clear.
@PP
Now the arrow from @I A to @I B starts on the boundary of @I A at the
angle of a line drawn between the centres of @I A and {@I B}:
@ID @Code "A@CTR ++ { {A@CTR @Angle B@CTR} A@CIRCUM }"
and a similar expression will yield the endpoint of the arrow.  Such
expressions should be placed into definitions if they are to be used often:
joinfigures. @Index @Code "@JoinFigures"
@ID @OneRow @Code {
"import @Fig"
"def @JoinFigures"
"   left A"
"   named linestyle { solid }"
"   named dashlength { 0.15 cm }"
"   named arrow { noarrow }"
"   named linewidth { 0.5 pt }"
"   right B"
"{  @Arrow"
"      from { A\"@CTR\" ++ {{A\"@CTR\" @Angle B\"@CTR\"} A\"@CIRCUM\"} }"
"      to   { B\"@CTR\" ++ {{B\"@CTR\" @Angle A\"@CTR\"} B\"@CIRCUM\"} }"
"      linestyle { linestyle }"
"      dashlength { dashlength }"
"      arrow { arrow }"
"      linewidth { linewidth }"
"   {}"
"}"
}
Definitions are the subject of Section {@NumberOf definitions},
although for @Code named parameters, which define
options, you have to consult the Lout expert's guide
@Cite { $kingston1995lout.expert }.  Now, to the figure above we can add
@ID @OneRow @Code {
"// A @JoinFigures arrow { forward } B"
"// A @JoinFigures arrow { forward } C"
"// B @JoinFigures arrow { forward } C"
"// B @JoinFigures arrow { forward } D"
"// C @JoinFigures arrow { forward } D"
}
to obtain the diagram as it appears at the beginning of this
section.  Definitions are the best means of managing complexity in
diagrams, and serious users of advanced graphics will need to keep
a stock of them in a @Code "mydefs" file.
@End @Section
