DIRECTORY Controls, Draw2d, FileNames, G2dGraph, Imager, ImagerFont, IO, RealFns, Rope, ViewerClasses; G2dGraphImpl: CEDAR PROGRAM IMPORTS Controls, Draw2d, FileNames, Imager, ImagerFont, IO, RealFns, Rope EXPORTS G2dGraph ~ BEGIN ROPE: TYPE ~ Rope.ROPE; GraphData: TYPE ~ G2dGraph.GraphData; GraphProc: TYPE ~ G2dGraph.GraphProc; Function: TYPE ~ G2dGraph.Function; Bump: PUBLIC GraphProc ~ { xx: REAL ~ 1.0-ABS[1.0-x-x]; RETURN[xx*xx]; }; Gauss: PUBLIC GraphProc ~ { mean: REAL ~ 0.5; pi: REAL ~ 3.1415926535; standardDeviation: REAL ~ 0.16; factor1: REAL ~ 1.0/(2.0*standardDeviation*standardDeviation); factor2: REAL ~ 1.0/(standardDeviation*RealFns.SqRt[2.0*pi]); xx: REAL ~ x-mean; RETURN[factor2*RealFns.Exp[-xx*xx*factor1]]; }; Poisson: PUBLIC GraphProc ~ {RETURN[g.a*x*RealFns.Exp[-g.a*x]]}; Power: PUBLIC GraphProc ~ {RETURN[RealFns.Power[x, g.a]]}; Sin: PUBLIC GraphProc ~ {RETURN[RealFns.Power[0.5+0.5*RealFns.Sin[x], g.a]]}; Ln: PUBLIC GraphProc ~ {RETURN[RealFns.Ln[x]]}; Log: PUBLIC GraphProc ~ {RETURN[RealFns.Log[g.a, x]]}; Exp: PUBLIC GraphProc ~ { a: REAL ¬ IF g.a = 1.0 THEN 1.01 ELSE g.a; RETURN[(RealFns.Power[a, x]-1.0)/(a-1.0)]; }; Perlin: PUBLIC GraphProc ~ { IF x <= 0.0 OR g.a <= 0.0 THEN RETURN[0.0]; RETURN[RealFns.Power[0.5, RealFns.Log[0.5, x]*RealFns.Log[0.5, g.a]]]; }; WyvillData: TYPE ~ RECORD [R2, R4, R6: REAL]; Wyvill: PUBLIC GraphProc ~ { w: REF WyvillData ¬ NARROW[g.clientData]; r2: REAL ~ x*x; r4: REAL ~ r2*r2; r6: REAL ~ r2*r4; RETURN[w.R6*r6+w.R4*r4+w.R2*r2+1.0]; }; SlowInOut: PUBLIC GraphProc ~ { RETURN[(3.0-2.0*x)*x*x]; }; Compress: PUBLIC GraphProc ~ { RETURN[2.0*RealFns.Exp[-x*x*0.5]]; }; Pavicic: PUBLIC GraphProc ~ { pi: REAL ~ 3.1415926535; a: REAL ~ 0.5823997; -- a=(1-v2)/(v1-v2), v1=pi/3, v2=(pi/2)-(2/pi) t1: REAL ¬ a*(1.0-x); t2: REAL ¬ (1.0-a)*(1.0+RealFns.Cos[pi*x])/2.0; RETURN[t1+t2]; }; PerspZ: PUBLIC GraphProc ~ { d: REAL ¬ 10.0; den: REAL ¬ x/d+1.0; y ¬ IF ABS[den] < 0.0001 THEN 100.0 ELSE x/den; }; SquashStretch: PUBLIC GraphProc ~ { angle: REAL ¬ 2.0*3.14159256535*x; dot: REAL ¬ RealFns.Cos[angle]; y ¬ ((1-g.a)*0.5)*RealFns.Cos[3.1415926535*dot]+((g.a+1)/2.0); }; Ease: PUBLIC GraphProc ~ { F: PROC [x, v: REAL] RETURNS [REAL] ~ { RETURN[1.0/(1.0+RealFns.Exp[-v*x])]; }; fMinus1: REAL ¬ F[-1.0, g.a]; RETURN[(F[(2.0*x)-1.0, g.a] - fMinus1)/(F[1.0, g.a] - fMinus1)]; }; functions: LIST OF Function ¬ NIL; RegisterFunction: PUBLIC PROC [function: Function] ~ { functions ¬ CONS[function, functions]; }; GetFunctions: PUBLIC PROC RETURNS [LIST OF Function] ~ {RETURN[functions]}; GetFunction: PUBLIC PROC [name: ROPE] RETURNS [f: Function] ~ { FOR l: LIST OF Function ¬ GetFunctions[], l.rest WHILE l # NIL DO IF Rope.Equal[l.first.name, name, FALSE] THEN RETURN[l.first]; ENDLOOP; }; Data: TYPE ~ REF DataRep; DataRep: TYPE ~ RECORD [ outerData: Controls.OuterData ¬ NIL, ticks: BOOL ¬ TRUE, graphData: GraphData ¬ NIL, graphProc: GraphProc ¬ NIL]; GraphFunction: PUBLIC PROC [ function: Function, xMin: REAL ¬ 0.0, xMax: REAL ¬ 1.0, scale: REAL ¬ 1.0, a: REAL ¬ 1.0, clientData: REF ANY ¬ NIL] RETURNS [error: ROPE] ~ { g: GraphData ¬ NEW[G2dGraph.GraphDataRep ¬ [a: a, xMin: xMin, xMax: xMax, scale: scale, clientData: clientData]]; d: Data ¬ NEW[DataRep ¬ [graphData: g, graphProc: function.proc]]; IF ABS[xMax-xMin] < 0.0001 THEN RETURN["x range too small"]; IF d.graphProc = Wyvill THEN { w: REF WyvillData ¬ g.clientData ¬ NEW[WyvillData]; aa: REAL ~ -4.0/9.0; bb: REAL ~ 17.0/9.0; cc: REAL ~ -22.0/9.0; IF g.a = 0.0 THEN g.a ¬ 1.0; w.R2 ¬ 1.0/(d.graphData.a*d.graphData.a); w.R4 ¬ w.R2*w.R2; w.R6 ¬ w.R2*w.R4; w.R2 ¬ cc*w.R2; w.R4 ¬ bb*w.R4; w.R6 ¬ aa*w.R6; }; d.outerData ¬ Controls.OuterViewer[ name: IO.PutFLR["2dGraph %g -xMin %g -xMax %g -scale %g -a %g", LIST[IO.rope[function.name], IO.real[xMin], IO.real[xMax], IO.real[scale], IO.real[a]]], graphicsHeight: 200, drawProc: DrawProc, typescriptHeight: 18, buttons: LIST[ Controls.ClickButton["IPOut", IPOut, d], Controls.ClickButton["Ticks: On", TicksToggle, d]], clientData: d]; }; TicksToggle: Controls.ClickProc ~ { d: Data ¬ NARROW[clientData]; Controls.ButtonToggle[d.outerData, d.ticks ¬ NOT d.ticks, "Ticks: On", "Ticks: Off"]; }; IPOut: Controls.ClickProc ~ { d: Data ¬ NARROW[clientData]; r: Rope.ROPE ¬ Controls.TypescriptReadFileName[d.outerData.typescript]; IF r # NIL THEN Draw2d.IPOut[FileNames.ResolveRelativePath[r], DrawProc, clientData]; }; DrawProc: Controls.DrawProc ~ { RealFunction: TYPE ~ PROC [v: REAL] RETURNS [REAL]; XToScreen: RealFunction ~ {RETURN[leftMargin+v*xToScreen]}; YToScreen: RealFunction ~ {RETURN[botMargin+v*yToScreen]}; XFromScreen: RealFunction ~ {RETURN[g.xMin+(v-leftMargin)*xFromScreen]}; YFromScreen: RealFunction ~ {RETURN[(v-botMargin)*yFromScreen]}; tick: INTEGER ~ 5; leftMargin: INTEGER ~ 27; botMargin: INTEGER ~ 17; d: Data ~ NARROW[clientData]; g: GraphData ¬ d.graphData; graphics: ViewerClasses.Viewer ¬ d.outerData.graphics; xToScreen: REAL ~ (graphics.cw-leftMargin)/(g.xMax-g.xMin); yToScreen: REAL ~ (graphics.ch-botMargin)*g.scale; xFromScreen: REAL ~ 1.0/xToScreen; yFromScreen: REAL ~ 1.0/yToScreen; IF d.ticks THEN { Imager.SetFont[context, ImagerFont.Find["xerox/tiogafonts/helvetica7"]]; Imager.MaskRectangle[context, [leftMargin, botMargin, graphics.cw, 1]]; Imager.MaskRectangle[context, [leftMargin, botMargin, 1, graphics.ch]]; FOR n: NAT ¬ botMargin, n+20 WHILE n < graphics.ch DO -- left edge ticks y: REAL ~ YFromScreen[n]; Imager.MaskRectangle[context, [leftMargin-tick, n, tick, 1]]; Draw2d.Label[context, [3, n], IO.PutFR1["%3.2f", IO.real[y]]]; ENDLOOP; FOR n: NAT ¬ leftMargin, n+40 WHILE n < graphics.cw DO -- bottom edge ticks x: REAL ~ XFromScreen[n]; Imager.MaskRectangle[context, [n, botMargin-tick, 1, tick]]; Draw2d.Label[context, [n, 3], IO.PutFR1["%3.2f", IO.real[x]]]; ENDLOOP; }; IF whatChanged # $IPOut THEN FOR i: NAT IN [leftMargin..graphics.cw] DO y: REAL ~ d.graphProc[XFromScreen[i], g ! UNCAUGHT => LOOP]; Imager.MaskRectangle[context, [i, YToScreen[y], 1, 1]]; ENDLOOP ELSE { y0: REAL ¬ YToScreen[d.graphProc[XFromScreen[leftMargin], g]]; Imager.SetStrokeWidth[context, 2.0]; FOR i: NAT ¬ leftMargin+1, i+3 WHILE i <= graphics.cw DO y: REAL ~ YToScreen[d.graphProc[XFromScreen[i], g ! UNCAUGHT => LOOP]]; Imager.MaskVector[context, [i, y0], [i+3, y]]; y0 ¬ y; ENDLOOP; }; }; functions ¬ LIST[ ["Bump", Bump, "\t\ta second order curve"], ["Gauss", Gauss, "\t\tthe normal distribution curve"], ["Poisson", Poisson, "\t\tthe poisson curve, with a the scalar"], ["Power", Power, "\t\ta power curve, with a the exponent"], ["Sin", Sin, "\t\t\ta sin curve raised to the a power"], ["Ln", Ln, "\t\t\tnatural logarithm"], ["Log", Log, "\t\t\tlogarithm to the base a"], ["Exp", Exp, "\t\t\tan exponential function"], ["Perlin", Perlin, "\t\tKen's curve, with a the scalar"], ["Wyvill", Wyvill, "\t\tWyvill's soft function"], ["SlowInOut", SlowInOut, "\tslow in and out curve"], ["Compress", Compress, "\t\tlike Gauss"], ["Pavicic", Pavicic, "\t\tPavicic's radial weighting filter"], ["PerspZ", PerspZ, "\t\ttransformed perspective Z"], ["SquashStretch", SquashStretch, "squash/stretch ala JB + BW"], ["Ease", Ease, "\t\t\tGlassner's slow-in-out, a > 0: slower easing"] ]; END. 0 G2dGraphImpl.mesa Copyright Σ 1985, 1992 by Xerox Corporation. All rights reserved. Bloomenthal, July 2, 1992 5:09 pm PDT Glassner, November 30, 1990 7:13 pm PST Types Functions Function Registration Graphing ! Real.RealException, Real.RealError, FloatingPointCommon.Error => LOOP]; Start Code Κ V–"cedarcode" style•NewlineDelimiter ™™Jšœ Οeœ6™BJ™%J™'J˜JšΟk œ]˜fJ˜—šΠbn œžœž˜JšžœC˜JJšžœ ˜—Jšœž˜headšΟl™Jšžœžœžœ˜Jšœ žœ˜%Jšœ žœ˜%Jšœ žœ˜$—š  ™ šŸœžœ˜Jšœžœžœ ˜Jšžœ˜J˜J˜—šŸœžœ˜Jšœžœ˜Jšœžœ˜Jšœžœ˜Jšœ žœ1˜>Jšœ žœ0˜=Jšœžœ ˜Jšžœ&˜,J˜J˜—JšŸœžœžœ˜@J˜šŸœžœžœ˜:J˜—JšŸœžœžœ.˜MJ˜JšŸœžœžœ˜/J˜šŸœžœžœ˜6J˜—šŸœžœ˜Jš œžœžœ žœžœ˜*Jšžœ$˜*Jšœ˜J˜—šŸœžœ˜Jšžœ žœ žœžœ˜+Jšžœ@˜FJ˜J˜—šœ žœžœžœ˜-J˜—šŸœžœ˜Jšœžœžœ˜)Jšœžœ˜Jšœžœ ˜Jšœžœ ˜Jšžœžœžœžœ ˜$J˜J˜—šŸ œžœ˜Jšžœ˜J˜J˜—šŸœžœ˜Jšžœ˜"J˜J˜—šŸœžœ˜Jšœžœ˜JšœžœΟc.˜CJšœžœ ˜Jšœžœ'˜/Jšžœ˜J˜J˜—šŸœžœ˜Jšœžœ˜Jšœžœ ˜Jš œžœžœžœžœ˜/J˜J˜—šŸ œžœ˜#Jšœžœ˜"Jšœžœ˜J˜>J˜J˜—šŸœžœ˜Jš Οnœžœžœžœžœžœ!˜OJšœ žœ˜Jšžœ:˜@J˜——š ™šœ žœžœ žœ˜"J˜—š’œžœžœ˜6Jšœ žœ˜&J˜J˜—š ’ œž œžœžœžœžœ ˜KJ˜—š ’ œžœžœžœžœ˜?š žœžœžœ#žœžœž˜AJšžœ žœžœžœ ˜>Jšžœ˜—J˜——š ™Jšœ žœžœ ˜šœ žœžœ˜Jšœ#žœ˜'Jšœ žœžœ˜Jšœžœ˜Jšœžœ˜J˜—š’ œžœžœ˜J˜Jšœžœ˜Jšœžœ˜Jšœžœ˜Jšœžœ˜Jšœ žœžœžœ˜Jšžœ žœ˜Jšœ˜šœ Οsœ£žœ˜*JšœF˜F—Jšœ žœ5˜BJšžœžœžœžœ˜<šžœžœ˜Jšœžœžœ ˜3Jšœžœ ˜Jšœžœ ˜Jšœžœ ˜Jšžœ žœ ˜Jšœžœ%˜)Jšœžœžœžœ˜Jšœžœžœžœ˜Jšœžœžœ˜Jšœžœžœ˜Jšœžœžœ˜J˜—˜#šœžœ7˜?Jš žœžœžœ žœ žœžœ ˜X—J˜J˜J˜šœ žœ˜Jšœ(˜(Jšœ3˜3—J˜—J˜J˜—š’ œ˜#Jšœ žœ ˜Jšœ-žœ%˜UJ˜J˜—š’œ˜Jšœ žœ ˜Jšœžœ;˜GJšžœžœžœF˜UJ˜J˜—š’œ˜Jš œžœžœžœžœžœ˜3Jš’ œžœ˜;Jš’ œžœ˜:Jš’ œžœ%˜HJš’ œžœ˜@Jšœžœ˜Jšœ žœ˜Jšœ žœ˜Jšœ žœ ˜J˜J˜6Jšœ žœ,˜;Jšœ žœ#˜2Jšœ žœ˜"Jšœ žœ˜"šžœ žœ˜J˜HJ˜GJ˜Gš žœžœžœžœ‘˜HJšœžœ˜J˜=Jšœžœžœ ˜>Jšžœ˜—š žœžœžœžœ‘˜KJšœžœ˜J˜Jšžœ˜—J˜—šžœ˜šž˜šžœžœžœž˜*šœžœ#žœžœ˜Jšœ$˜$šžœžœžœž˜8Jš œžœ(£œ£ž£œ£žœ˜GJ˜.J˜Jšžœ˜—J˜——J˜——š  ™ šœ žœ˜J˜1J˜