CONST Tick1 = ((0.95, 1), 1), Tick5 = ((0.91, 1), 1.5), Tick10 = ((0.87, 1), 1.9), LabelFrac = 0.75, RedStart = 8, SpeedBnds = [10, 150, 2, 20], TachBnds = [0.5, 9.5, 0.1, 1], BaseWidth = 10, TipWidth = 2, SpeedOffset = 10 * Angle.Degree, TachOffset = 5 * Angle.Degree, ZeroOffset = 8 * Angle.Degree; FUNC p = AnglePoint(a, b, theta) IS p = (COS(theta), SIN(theta)) REL (a, b) END; PROC txt := LabelText(start, tick, lbl, i) IS VAR val IN val := start + (i * tick); IF val MOD lbl = 0 -> txt := Unparse.Value(val) | txt := NIL FI END END; PROC DrawLabel(a, b, lblTxt) IS SAVE PS IN PS.SetColor(Color.White); PS.SetFont("Helvetica-Bold", PS.Large); TypeLinesC.Center((LabelFrac, 0) REL (a, b), lblTxt) END END; PROC DrawTick(a, b, tickSz, color) IS IF VAR in, out, width IN tickSz = ((in, out), width) -> SAVE PS IN PS.MoveTo((in, 0) REL (a, b)); PS.LineTo((out, 0) REL (a, b)); PS.SetColor(color); PS.SetWidth(width); PS.SetEndStyle(PS.ButtEnds); PS.Stroke() END END FI END; PROC ZeroTick(a, b) IS DrawTick(a, b, Tick10, Color.White); DrawLabel(a, AnglePoint(a, b, ZeroOffset), "0") END; PROC tickSz, color := NormalTickCl(i, val) IS i := i + 5; IF i MOD 10 = 0 -> tickSz := Tick10; color := Color.White | i MOD 5 = 0 -> tickSz := Tick5; color := Color.White | tickSz := Tick1; color := Color.Grey75 FI END; PROC tickSz, color := TachTickCl(i, val) IS tickSz, color := NormalTickCl(i, val); IF val > RedStart -> color := Color.Red | SKIP FI END; PROC res := AngleCC(b, a, c) IS res := Angle.CC(b, a, c); IF res < 0 -> res := res + 2 * Math.Pi | SKIP FI END; PROC res := TickVal(start, tickVal, i) IS res := start + (i * tickVal) END; PROC Ticks(b, a, c, bnds, tickCl) IS IF VAR phi = AngleCC(c, a, b), start, end, tickVal, val, lbl, numTicks, tickSz, color, i = 0, theta, p, lblTxt IN bnds = [start, end, tickVal, lbl] -> numTicks := (end - start) / tickVal; DO i <= numTicks -> theta := -(i / numTicks) * phi; p := AnglePoint(a, b, theta); val := TickVal(start, tickVal, i); lblTxt := LabelText(start, tickVal, lbl, i); IF lblTxt # NIL -> DrawLabel(a, p, lblTxt) | SKIP FI; tickSz, color := APPLY(tickCl, i, val); DrawTick(a, p, tickSz, color); i := i + 1 OD END FI END; PROC DrawGauge(a, b, startOffset, bnds, tickCl) IS IF VAR c ~ (-0.12649187, 0.9919676) REL (a, b), d = AnglePoint(a, b, -startOffset) IN b HOR c AND Circle.On(c, a, b) -> Circle.Draw(a, b); PS.Fill(); Ticks(d, a, c, bnds, tickCl); ZeroTick(a, b) END FI END; PROC Cmd0() IS IF VAR a ~ (0, 122.11675), b ~ (-84.06939, 45.509354), c ~ (0, -122.11675), d = R2.Plus(c, (-84.06939, -76.6074)), e = (156.02068, -122.11675), f = R2.Origin IN f = Geometry.Mid(a, c) AND a VER c AND b VER d AND (a, b) CONG (c, d) AND c HOR e AND a VER f -> DrawGauge(a, b, SpeedOffset, SpeedBnds, NormalTickCl); DrawGauge(c, d, TachOffset, TachBnds, TachTickCl) END FI END;