PROCEDURE SegSegDir(READONLY p, q: LR3.T): LR3.T = (* The direction of segment "p--q", or zero if they are the same. *) BEGIN WITH r = LR3.Sub(q, p), d = r[0]*r[0] + r[1]*r[1] DO IF d < 1.0d-20 THEN RETURN LR3.T{0.0d0, ..} ELSE RETURN LR3.Dir(r) END END END SegSegDir; GenericChains = ARRAY OF GenericChain; GenericChain = RECORD t: ChainType; pt: PZLR3Chain.ReadData; cv: PZLRChain.ReadData; sy: PZSymbolChain.ReadData; END; TYPE ChainType = { Pt, (* Samples are points, as "LR3.T". *) Cv, (* Samples are unsqueezed numeric curvatures, "LONG". *) Sy (* Samples are squeezed and quantized numeric curvatures. *) }; pp.getKeyword("-chainType"); WITH s = pp.getNext() DO IF Text.Equal(s, "Pt") THEN o.chainType := ChainType.Pt; ELSIF Text.Equal(s, "Cv") THEN o.chainType := ChainType.Cv; ELSIF Text.Equal(s, "Sy") THEN o.chainType := ChainType.Sy; ELSE pp.error("bad chain type") END END; chainType: ChainType; (* Type of chain to read. *) PROCEDURE ReadAllGenericChains( dir: TEXT; prefix: TEXT; band: NAT; chainType: ChainType; READONLY sel: BOOLS; ): REF GenericChains = BEGIN WITH nc = NUMBER(sel), rch = NEW(REF GenericChains, nc), ch = rch^ DO FOR i := 0 TO LAST(ch) DO ch[i].t := chainType END; CASE chainType OF | ChainType.Pt => WITH , chPt = chPtData.chain^ DO FOR i := 0 TO LAST(ch) DO ch[i].pt := chPt[i] END END | ChainType.Cv => WITH , chCv = chCvData.chain^ DO FOR i := 0 TO LAST(ch) DO ch[i].cv := chCv[i] END END | ChainType.Sy => WITH , chSy = chSyData.chain DO FOR i := 0 TO LAST(ch) DO ch[i].sy := chSy[i] END END END; RETURN rch END END ReadAllGenericChains; PROCEDURE SegSegAngle(READONLY ai, af, bi, bf: LR3.T; alphaRef: LONG): LONG = (* The angle between segments "ai--af" and "bi--bf", reduced to the interval "alphaRef ± Pi". *) VAR alpha: LONG; BEGIN WITH ra = LR3.Sub(af, ai), rb = LR3.Sub(bf, bi), ct = ra[0]*rb[0] + ra[1]*rb[1], st = ra[1]*rb[0] - ra[0]*rb[1] DO alpha := Math.atan2(ct, st); WHILE alpha - alphaRef > +Pi DO alpha := alpha - 2.0d0*Pi END; WHILE alpha - alphaRef < -Pi DO alpha := alpha + 2.0d0*Pi END; RETURN alpha END END SegSegAngle;