DIRECTORY Commander, Controls, Draw2d, G3dBasic, G3dControl, G3dDraw, G3dFunction, G3dMatrix, G3dSpline, G3dTool, Imager, IO, Real, RealFns, Rope, ViewerOps; G3dGraphCmdImpl: CEDAR PROGRAM IMPORTS Controls, G3dControl, G3dDraw, G3dFunction, Draw2d, G3dSpline, G3dTool, Imager, IO, Real, RealFns, Rope, ViewerOps ~ BEGIN ROPE: TYPE ~ Rope.ROPE; Viewer: TYPE ~ Controls.Viewer; ClickProc: TYPE ~ Controls.ClickProc; OuterData: TYPE ~ Controls.OuterData; Control: TYPE ~ Controls.Control; Request: TYPE ~ Controls.Request; Triple: TYPE ~ G3dBasic.Triple; Camera: TYPE ~ G3dControl.CameraControl; Matrix: TYPE ~ G3dMatrix.Matrix; arraySize: NAT ~ 40; GraphData: TYPE ~ REF GraphDataRep; GraphDataRep: TYPE ~ RECORD [ a: Control ¬ NIL, xMin: Control ¬ NIL, xMax: Control ¬ NIL, yMin: Control ¬ NIL, yMax: Control ¬ NIL, zScale: Control ¬ NIL, grain: Control ¬ NIL, values: ARRAY [0..arraySize) OF ARRAY [0..arraySize) OF REAL, graphics: Viewer ¬ NIL, outer: Viewer ¬ NIL, outerData: OuterData ¬ NIL, camera: Camera ¬ NIL, view: Matrix ¬ NIL, axesOn: BOOL ¬ TRUE, graphProc: GraphProc ¬ Gauss ]; GraphProc: TYPE ~ PROC [x: REAL, g: GraphData] RETURNS [v: REAL]; RealFunction: TYPE ~ PROC [v: REAL] RETURNS [REAL]; Function: TYPE ~ RECORD [name: ROPE, use: ROPE, proc: GraphProc]; Graph: Commander.CommandProc ~ { g: GraphData ¬ NEW[GraphDataRep]; g.camera ¬ G3dControl.InitCameraControl[proc: CameraControl, clientData: g]; Controls.SetSliderDialValue[g.camera.par.zMov, -0.5]; g.a ¬ Controls.NewControl["A", , g, , , , Controller]; g.xMin ¬ Controls.NewControl["Xmin", , g, -1.0, 1.0, 0.0, Controller]; g.yMin ¬ Controls.NewControl["Ymin", , g, -1.0, 1.0, 0.0, Controller]; g.xMax ¬ Controls.NewControl["Xmax", , g, -1.0, 1.0, 1.0, Controller]; g.yMax ¬ Controls.NewControl["Ymax", , g, -1.0, 1.0, 1.0, Controller]; g.zScale ¬ Controls.NewControl["Zscale", , g, -5.0, 5.0, 1.0, Controller]; g.grain ¬ Controls.NewControl["Grain", , g, 0.05, 1.0, 0.1, Controller]; ComputeValues[g]; g.outerData ¬ Controls.OuterViewer[ name: "3dGraph Gauss", buttons: LIST[ Controls.ClickButton["Interpress-Out", InterpressOut, g], Controls.ClickButton["Function", FunctionSelect, g], Controls.ClickButton["Axes-On", ToggleAxes, g] ], controls: LIST[ g.camera.proxySelect, g.camera.proxy.xMov, g.camera.proxy.yMov, g.camera.proxy.zMov, g.camera.proxy.xRot, g.camera.proxy.yRot, g.camera.proxy.zRot, g.xMin, g.xMax, g.yMin, g.yMax, g.zScale, g.grain], controlSizes: [17, 200, 60, 20, 60, 150, 150], graphicsHeight: 300, drawProc: DrawProc, typescriptHeight: 18, clientData: g]; g.outer ¬ g.outerData.parent; g.graphics ¬ g.outerData.graphics; }; Controller: Controls.ControlProc ~ { g: GraphData ¬ NARROW[control.clientData]; Set: PROC [control: Control, value: REAL] ~ {Controls.SetSliderDialValue[control, value]}; SELECT control FROM g.xMin => IF g.xMin.value > g.xMax.value THEN Set[g.xMax, g.xMin.value]; g.yMin => IF g.yMin.value > g.yMax.value THEN Set[g.yMax, g.yMin.value]; g.xMax => IF g.xMax.value < g.xMin.value THEN Set[g.xMin, g.xMax.value]; g.yMax => IF g.xMax.value < g.xMin.value THEN Set[g.yMin, g.yMax.value]; ENDCASE; Set[g.grain, MAX[g.grain.value, (g.xMax.value-g.xMin.value)/(arraySize-1), (g.yMax.value-g.yMin.value)/(arraySize-1)]]; IF control.whatChanged = $TypedIn OR control.mouse.button = right THEN Repaint[g, $Controller]; }; InterpressOut: ClickProc ~ { g: GraphData ¬ NARROW[clientData]; Draw2d.IPOut[Controls.TypescriptReadFileName[g.outerData.typescript], DrawAction, g]; }; ToggleAxes: ClickProc ~ { g: GraphData ¬ NARROW[clientData]; Controls.ButtonToggle[g.outerData, g.axesOn ¬ NOT g.axesOn, "Axes-On", "Axes-Off"]; IF mouseButton = blue THEN Repaint[g, $Axes]; }; FunctionSelect: ClickProc ~ { Reverse: PROC [in: LIST OF Request] RETURNS [out: LIST OF Request] ~ { FOR r: LIST OF Request ¬ in, r.rest WHILE r # NIL DO out ¬ CONS[r.first, out]; ENDLOOP; }; g: GraphData ¬ NARROW[clientData]; n, choice: INTEGER ¬ 1; requests: LIST OF Request ¬ NIL; FOR l: LIST OF Function ¬ functions, l.rest WHILE l # NIL DO requests ¬ CONS[[l.first.name, l.first.use], requests]; ENDLOOP; choice ¬ Controls.PopUpRequest[["Function Select"], Reverse[requests]]; FOR l: LIST OF Function ¬ functions, l.rest WHILE l # NIL DO IF n = choice THEN { g.graphProc ¬ l.first.proc; g.outer.name ¬ Rope.Concat["3dGraph ", l.first.name]; ViewerOps.PaintViewer[g.outer, caption]; EXIT; }; n ¬ n+1; ENDLOOP; Repaint[g, $FunctionSelect]; }; CameraControl: Controls.ControlProc ~ { g: GraphData ¬ NARROW[clientData]; IF control.mouse.button # right THEN RETURN; Repaint[g, $Camera]; }; Repaint: PROC [g: GraphData, whatChanged: REF ANY ¬ NIL] ~ { IF whatChanged # $Camera THEN ComputeValues[g]; ViewerOps.PaintViewer[g.graphics, client, FALSE, whatChanged]; }; DrawProc: Controls.DrawProc ~ { g: GraphData ~ NARROW[clientData]; Action: PROC ~ { g.view ¬ G3dControl.InitContext[context, g.camera, viewer, , g.view]; DrawAction[context, g, whatChanged, viewer]; }; Draw2d.DoWithBuffer[context, Action]; }; ComputeValues: PROC [g: GraphData] ~ { ix, iy: NAT ¬ 0; FOR x: REAL ¬ g.xMin.value, x+g.grain.value WHILE x < g.xMax.value DO xValue: REAL ¬ 0.0; xValue ¬ g.graphProc[x, g ! Real.RealException => CONTINUE]; iy ¬ 0; FOR y: REAL ¬ g.yMin.value, y+g.grain.value WHILE y < g.yMax.value DO yValue: REAL ¬ 0.0; yValue ¬ g.graphProc[y, g ! Real.RealException => CONTINUE]; g.values[ix][iy] ¬ g.zScale.value*xValue*yValue; iy ¬ iy+1; ENDLOOP; ix ¬ ix+1; ENDLOOP; }; DrawAction: Controls.DrawProc ~ { g: GraphData ~ NARROW[clientData]; ix, iy: NAT ¬ 0; FOR x: REAL ¬ g.xMin.value, x+g.grain.value WHILE x < g.xMax.value DO p0: Triple ¬ [x, g.yMin.value, g.values[ix][iy ¬ 0]]; FOR y: REAL ¬ g.yMin.value+g.grain.value, y+g.grain.value WHILE y < g.yMax.value DO p1: Triple ¬ [x, y, g.values[ix][iy ¬ iy+1]]; G3dDraw.Segment[context, p0, p1, g.view, []]; p0 ¬ p1; ENDLOOP; ix ¬ ix+1; ENDLOOP; iy ¬ 0; FOR y: REAL ¬ g.yMin.value, y+g.grain.value WHILE y < g.yMax.value DO p0: Triple ¬ [g.xMin.value, y, g.values[ix ¬ 0][iy]]; FOR x: REAL ¬ g.xMin.value+g.grain.value, x+g.grain.value WHILE x < g.xMax.value DO p1: Triple ¬ [x, y, g.values[ix ¬ ix+1][iy]]; G3dDraw.Segment[context, p0, p1, g.view, []]; p0 ¬ p1; ENDLOOP; iy ¬ iy+1; ENDLOOP; IF g.axesOn THEN G3dDraw.Axes[context, g.view, []]; }; Spike: GraphProc ~ {v ¬ G3dFunction.Spike[x]}; Gauss: GraphProc ~ {v ¬ G3dFunction.Gauss[x]}; Poisson: GraphProc ~ {v ¬ G3dFunction.Poisson[x, g.a.value]}; Power: GraphProc ~ {v ¬ IF x>0 THEN RealFns.Power[x, g.a.value] ELSE 0}; Sin: GraphProc ~ {v ¬ RealFns.Power[0.5+0.5*RealFns.Sin[x], g.a.value]}; Ln: GraphProc ~ {v ¬ RealFns.Ln[x]}; Log: GraphProc ~ {v ¬ RealFns.Log[g.a.value, x]}; Perlin: GraphProc ~ {v ¬ G3dFunction.Perlin[x, g.a.value]}; Wyvill: GraphProc ~ {v ¬ IF x>0 THEN G3dFunction.Wyvill[x/g.a.value] ELSE 0}; XSquared: GraphProc ~ {v ¬ IF x>0 THEN 1-x*x ELSE 0}; SlowInOut: GraphProc ~ {v ¬ IF x>0 THEN G3dSpline.SlowInOut[0.0, 1.0, x] ELSE 0}; functions: LIST OF Function ~ LIST[ ["Spike", "a second order curve", Spike], ["Gauss", "the normal distribution curve", Gauss], ["Poisson", "the poisson curve, with a the scalar", Poisson], ["Power", "a power curve, with a the exponent", Power], ["Sin", "a sin curve raised to the a power", Sin], ["Ln", "natural logarithm", Ln], ["Log", "logarithm to the base a", Log], ["Perlin", "Ken's curve, with a the scalar", Perlin], ["Wyvill", "Wyvill's soft function", Wyvill], ["xSquared", "simplifiied Wyvill", XSquared], ["SlowInOut", "Slow in and out curve", SlowInOut]]; use: ROPE ¬ "graph [-option]\n\tfunctions are:\n"; FOR l: LIST OF Function ¬ functions, l.rest WHILE l # NIL DO use ¬ IO.PutFR["%g\t\t%g:\t%g\n", IO.rope[use], IO.rope[l.first.name], IO.rope[l.first.use]]; ENDLOOP; use ¬ Rope.Concat[use, "\toptions are: -scale (default = 1) -xMin (default = 0) -xMax (default = 1) -a (default = 1)"]; G3dTool.Register["Graph", Graph, use]; END. L G3dGraphCmdImpl.mesa Copyright Σ 1988, 1992 by Xerox Corporation. All rights reserved. Bloomenthal, October 20, 1992 5:38 pm PDT Glassner, September 30, 1988 12:41:52 pm PDT Imported Types Local Types Viewer Setup biScrollable: TRUE, Options View Control LF Display G3dControl.UpdateCamera[g.camera]; GraphProcs Start Code Κ:•NewlineDelimiter –"cedarcode" style™™Jšœ Οeœ6™BJ™)J™,J˜JšΟk œqžœ!˜J˜—šΠbnœžœž˜JšžœQžœ ˜z—Jšœž˜headšΟl™Jšžœžœžœ˜Jšœ žœ˜#Jšœžœ˜(Jšœžœ˜(Jšœ žœ˜%Jšœ žœ˜%Jšœ žœ˜#Jšœ žœ˜,Jšœ žœ˜$—š  ™ šœ žœ˜J˜—Jšœ žœžœ˜$šœžœžœ˜Jšœžœ˜Jšœžœ˜Jšœžœ˜Jšœžœ˜Jšœžœ˜Jšœžœ˜Jšœžœ˜Jš œ žœžœžœžœžœ˜AJšœžœ˜Jšœžœ˜Jšœžœ˜Jšœžœ˜Jšœžœ˜Jšœ žœžœ˜J˜J˜J˜—Jš œ žœžœžœžœžœ˜BJš œžœžœžœžœžœ˜3Jš œ žœžœžœžœ˜C—š  ™ šΟbœ˜ Jšœžœ˜!J˜LJšœ5˜5J˜6J˜FJ˜FJ˜FJ˜FJ˜JJ˜HJšœ˜˜#J˜šœ žœ˜J˜9J˜4J˜.J˜—šœ žœ˜J˜J˜>J˜>J˜3—J˜.J˜J˜J˜Jšœžœ™J˜—J˜J˜"J˜J˜—šΟn œ˜$Jšœžœ˜*Jš’œžœžœ2˜Zšžœ ž˜Jšœ žœžœ˜HJšœ žœžœ˜HJšœ žœžœ˜HJšœ žœžœ˜HJšžœ˜—Jšœ žœg˜wšžœ žœ˜AJšžœ˜—J˜——š ™š’ œ˜Jšœžœ ˜"J˜UJ˜J˜—š‘ œ˜Jšœžœ ˜"Jšœ-žœ"˜SJšžœžœ˜-J˜J˜—š‘œ˜š’œžœžœžœ žœžœžœ ˜FJšžœžœžœžœžœžœžœžœ˜WJ˜—Jšœžœ ˜"Jšœ žœ˜Jšœ žœžœ žœ˜ š žœžœžœžœžœž˜J˜J˜—š‘œ˜Jšœžœ ˜"š’œžœ˜J™"J˜EJ˜,J˜—J˜%J˜J˜—š’ œžœ˜&Jšœžœ˜šžœžœ!žœž˜EJšœžœ˜Jšœ2žœ˜JšŸœžœžœžœ˜IJšŸœG˜JJšŸœ$˜&JšŸœ0˜3JšŸœ6˜