\documentclass{article} \usepackage{open-axiom} \begin{document} \title{\$SPAD/src/algebra view2D.spad} \author{James Wen} \maketitle \begin{abstract} \end{abstract} \tableofcontents \eject \section{domain GRIMAGE GraphImage} <>= )abbrev domain GRIMAGE GraphImage ++ Author: Jim Wen ++ Date Created: 27 April 1989 ++ Date Last Updated: 1995 September 20, Mike Richardson (MGR) ++ Basic Operations: ++ Related Constructors: ++ Also See: ++ AMS Classifications: ++ Keywords: ++ References: ++ Description: TwoDimensionalGraph creates virtual two dimensional graphs ++ (to be displayed on TwoDimensionalViewports). GraphImage (): Exports == Implementation where VIEW ==> _$ViewportServer$Lisp sendI ==> sockSendInt sendSF ==> sockSendFloat sendSTR ==> sockSendString getI ==> sockGetInt getSF ==> sockGetFloat typeGRAPH ==> 2 typeVIEW2D ==> 3 makeGRAPH ==> (-1)$SingleInteger makeVIEW2D ==> (-1)$SingleInteger I ==> Integer PI ==> PositiveInteger NNI ==> NonNegativeInteger SF ==> DoubleFloat F ==> Float L ==> List P ==> Point(SF) V ==> Vector SEG ==> Segment RANGESF ==> L SEG SF RANGEF ==> L SEG F UNITSF ==> L SF UNITF ==> L F PAL ==> Palette E ==> OutputForm DROP ==> DrawOption PP ==> PointPackage(SF) COORDSYS ==> CoordinateSystems(SF) Exports ==> SetCategory with graphImage : () -> $ ++ graphImage() returns an empty graph with 0 point lists ++ of the domain \spadtype{GraphImage}. A graph image contains ++ the graph data component of a two dimensional viewport. makeGraphImage : $ -> $ ++ makeGraphImage(gi) takes the given graph, \spad{gi} of the ++ domain \spadtype{GraphImage}, and sends it's data to the ++ viewport manager where it waits to be included in a two-dimensional ++ viewport window. \spad{gi} cannot be an empty graph, and it's ++ elements must have been created using the \spadfun{point} or ++ \spadfun{component} functions, not by a previous ++ \spadfun{makeGraphImage}. makeGraphImage : (L L P) -> $ ++ makeGraphImage(llp) returns a graph of the domain ++ \spadtype{GraphImage} which is composed of the points and ++ lines from the list of lists of points, \spad{llp}, with ++ default point size and default point and line colours. The graph ++ data is then sent to the viewport manager where it waits to be ++ included in a two-dimensional viewport window. makeGraphImage : (L L P,L PAL,L PAL,L PI) -> $ ++ makeGraphImage(llp,lpal1,lpal2,lp) returns a graph of the ++ domain \spadtype{GraphImage} which is composed of the points ++ and lines from the list of lists of points, \spad{llp}, whose ++ point colors are indicated by the list of palette colors, ++ \spad{lpal1}, and whose lines are colored according to the list ++ of palette colors, \spad{lpal2}. The paramater lp is a list of ++ integers which denote the size of the data points. The graph ++ data is then sent to the viewport manager where it waits to be ++ included in a two-dimensional viewport window. makeGraphImage : (L L P,L PAL,L PAL,L PI,L DROP) -> $ ++ makeGraphImage(llp,lpal1,lpal2,lp,lopt) returns a graph of ++ the domain \spadtype{GraphImage} which is composed of the ++ points and lines from the list of lists of points, \spad{llp}, ++ whose point colors are indicated by the list of palette colors, ++ \spad{lpal1}, and whose lines are colored according to the list ++ of palette colors, \spad{lpal2}. The paramater lp is a list of ++ integers which denote the size of the data points, and \spad{lopt} ++ is the list of draw command options. The graph data is then sent ++ to the viewport manager where it waits to be included in a ++ two-dimensional viewport window. pointLists : $ -> L L P ++ pointLists(gi) returns the list of lists of points which compose ++ the given graph, \spad{gi}, of the domain \spadtype{GraphImage}. key : $ -> I ++ key(gi) returns the process ID of the given graph, \spad{gi}, ++ of the domain \spadtype{GraphImage}. ranges : $ -> RANGEF ++ ranges(gi) returns the list of ranges of the point components from ++ the indicated graph, \spad{gi}, of the domain \spadtype{GraphImage}. ranges : ($,RANGEF) -> RANGEF ++ ranges(gi,lr) modifies the list of ranges for the given graph, ++ \spad{gi} of the domain \spadtype{GraphImage}, to be that of the ++ list of range segments, \spad{lr}, and returns the new range list ++ for \spad{gi}. units : $ -> UNITF ++ units(gi) returns the list of unit increments for the x and y ++ axes of the indicated graph, \spad{gi}, of the domain ++ \spadtype{GraphImage}. units : ($,UNITF) -> UNITF ++ units(gi,lu) modifies the list of unit increments for the x and y ++ axes of the given graph, \spad{gi} of the domain ++ \spadtype{GraphImage}, to be that of the list of unit increments, ++ \spad{lu}, and returns the new list of units for \spad{gi}. component : ($,L P,PAL,PAL,PI) -> Void ++ component(gi,lp,pal1,pal2,p) sets the components of the ++ graph, \spad{gi} of the domain \spadtype{GraphImage}, to the ++ values given. The point list for \spad{gi} is set to the list ++ \spad{lp}, the color of the points in \spad{lp} is set to ++ the palette color \spad{pal1}, the color of the lines which ++ connect the points \spad{lp} is set to the palette color ++ \spad{pal2}, and the size of the points in \spad{lp} is given ++ by the integer p. component : ($,P) -> Void ++ component(gi,pt) modifies the graph \spad{gi} of the domain ++ \spadtype{GraphImage} to contain one point component, \spad{pt} ++ whose point color, line color and point size are determined by ++ the default functions \spadfun{pointColorDefault}, ++ \spadfun{lineColorDefault}, and \spadfun{pointSizeDefault}. component : ($,P,PAL,PAL,PI) -> Void ++ component(gi,pt,pal1,pal2,ps) modifies the graph \spad{gi} of ++ the domain \spadtype{GraphImage} to contain one point component, ++ \spad{pt} whose point color is set to the palette color \spad{pal1}, ++ line color is set to the palette color \spad{pal2}, and point ++ size is set to the positive integer \spad{ps}. appendPoint : ($,P) -> Void ++ appendPoint(gi,pt) appends the point \spad{pt} to the end ++ of the list of points component for the graph, \spad{gi}, which is ++ of the domain \spadtype{GraphImage}. point : ($,P,PAL) -> Void ++ point(gi,pt,pal) modifies the graph \spad{gi} of the domain ++ \spadtype{GraphImage} to contain one point component, \spad{pt} ++ whose point color is set to be the palette color \spad{pal}, and ++ whose line color and point size are determined by the default ++ functions \spadfun{lineColorDefault} and \spadfun{pointSizeDefault}. coerce : L L P -> $ ++ coerce(llp) ++ component(gi,pt) creates and returns a graph of the domain ++ \spadtype{GraphImage} which is composed of the list of list ++ of points given by \spad{llp}, and whose point colors, line colors ++ and point sizes are determined by the default functions ++ \spadfun{pointColorDefault}, \spadfun{lineColorDefault}, and ++ \spadfun{pointSizeDefault}. The graph data is then sent to the ++ viewport manager where it waits to be included in a two-dimensional ++ viewport window. putColorInfo : (L L P,L PAL) -> L L P ++ putColorInfo(llp,lpal) takes a list of list of points, \spad{llp}, ++ and returns the points with their hue and shade components ++ set according to the list of palette colors, \spad{lpal}. figureUnits : L L P -> UNITSF Implementation ==> add import Color() import Palette() import ViewDefaultsPackage() import PlotTools() import DrawOptionFunctions0 import P import PP import COORDSYS Rep := Record(key: I, rangesField: RANGESF, unitsField: UNITSF, _ llPoints: L L P, pointColors: L PAL, lineColors: L PAL, pointSizes: L PI, _ optionsField: L DROP) --%Internal Functions graph : RANGEF -> $ scaleStep : SF -> SF makeGraph : $ -> $ numberCheck(nums:Point SF):Void == for i in minIndex(nums)..maxIndex(nums) repeat COMPLEXP(nums.(i::PositiveInteger))$Lisp => error "An unexpected complex number was encountered in the calculations." doOptions(g:Rep):Void == lr : RANGEF := ranges(g.optionsField,ranges g) if (#lr > 1$I) then g.rangesField := [segment(convert(lo(lr.1))@SF,convert(hi(lr.1))@SF)$(Segment(SF)), segment(convert(lo(lr.2))@SF,convert(hi(lr.2))@SF)$(Segment(SF))] else g.rangesField := [] lu : UNITF := units(g.optionsField,units g) if (#lu > 1$I) then g.unitsField := [convert(lu.1)@SF,convert(lu.2)@SF] else g.unitsField := [] -- etc - graphimage specific stuff... putColorInfo(llp,listOfPalettes) == llp2 : L L P := [] for lp in llp for pal in listOfPalettes repeat lp2 : L P := [] daHue := (hue(hue pal))::SF daShade := (shade pal)::SF for p in lp repeat if (d := dimension p) < 3 then p := extend(p,[daHue,daShade]) else p.3 := daHue d < 4 => p := extend(p,[daShade]) p.4 := daShade lp2 := cons(p,lp2) llp2 := cons(reverse! lp2,llp2) reverse! llp2 graph demRanges == null demRanges => [ 0, [], [], [], [], [], [], [] ] demRangesSF : RANGESF := _ [ segment(convert(lo demRanges.1)@SF,convert(hi demRanges.1)@SF)$(Segment(SF)), _ segment(convert(lo demRanges.1)@SF,convert(hi demRanges.1)@SF)$(Segment(SF)) ] [ 0, demRangesSF, [], [], [], [], [], [] ] scaleStep(range) == -- MGR adjust:NNI tryStep:SF scaleDown:SF numerals:String adjust := 0 while range < 100.0::SF repeat adjust := adjust + 1 range := range * 10.0::SF -- might as well take big steps tryStep := range/10.0::SF numerals := string(((retract(ceiling(tryStep)$SF)$SF)@I))$String scaleDown := (10@I **$I (((#(numerals)@I) - 1$I) pretend PI))::SF scaleDown*ceiling(tryStep/scaleDown - 0.5::SF)/((10 **$I adjust)::SF) figureUnits(listOfListsOfPoints) == -- figure out the min/max and divide by 10 for unit markers xMin := xMax := xCoord first first listOfListsOfPoints yMin := yMax := yCoord first first listOfListsOfPoints if xMin ~= xMin then xMin:=max() if xMax ~= xMax then xMax:=min() if yMin ~= yMin then yMin:=max() if yMax ~= yMax then yMax:=min() for pL in listOfListsOfPoints repeat for p in pL repeat if ((px := (xCoord p)) < xMin) then xMin := px if px > xMax then xMax := px if ((py := (yCoord p)) < yMin) then yMin := py if py > yMax then yMax := py if xMin = xMax then xMin := xMin - convert(0.5)$Float xMax := xMax + convert(0.5)$Float if yMin = yMax then yMin := yMin - convert(0.5)$Float yMax := yMax + convert(0.5)$Float [scaleStep(xMax-xMin),scaleStep(yMax-yMin)] plotLists(graf:Rep,listOfListsOfPoints:L L P,listOfPointColors:L PAL,listOfLineColors:L PAL,listOfPointSizes:L PI):$ == givenLen := #listOfListsOfPoints -- take out point lists that are actually empty listOfListsOfPoints := [ l for l in listOfListsOfPoints | not null l ] if (null listOfListsOfPoints) then error "GraphImage was given a list that contained no valid point lists" if ((len := #listOfListsOfPoints) ~= givenLen) then sayBrightly([" Warning: Ignoring pointless point list"::E]$List(E))$Lisp graf.llPoints := listOfListsOfPoints -- do point colors if ((givenLen := #listOfPointColors) > len) then -- pad or discard elements if given list has length different from the point list graf.pointColors := concat(listOfPointColors, new((len - givenLen)::NonNegativeInteger + 1, pointColorDefault())) else graf.pointColors := first(listOfPointColors, len) -- do line colors if ((givenLen := #listOfLineColors) > len) then graf.lineColors := concat(listOfLineColors, new((len - givenLen)::NonNegativeInteger + 1, lineColorDefault())) else graf.lineColors := first(listOfLineColors, len) -- do point sizes if ((givenLen := #listOfPointSizes) > len) then graf.pointSizes := concat(listOfPointSizes, new((len - givenLen)::NonNegativeInteger + 1, pointSizeDefault())) else graf.pointSizes := first(listOfPointSizes, len) graf makeGraph graf == doOptions(graf) (n := #(graf.llPoints)) = 0 => error "You are trying to make a graph with no points" key graf ~= 0 => error "You are trying to draw over an existing graph" transform := coord(graf.optionsField,cartesian$COORDSYS)$DrawOptionFunctions0 graf.llPoints:= putColorInfo(graf.llPoints,graf.pointColors) if null(ranges graf) then -- figure out best ranges for points graf.rangesField := calcRanges(graf.llPoints) --::V SEG SF if null(units graf) then -- figure out best ranges for points graf.unitsField := figureUnits(graf.llPoints) --::V SEG SF sayBrightly([" Graph data being transmitted to the viewport manager..."::E]$List(E))$Lisp sendI(VIEW,typeGRAPH)$Lisp sendI(VIEW,makeGRAPH)$Lisp tonto := (graf.rangesField)::RANGESF sendSF(VIEW,lo(first tonto))$Lisp sendSF(VIEW,hi(first tonto))$Lisp sendSF(VIEW,lo(second tonto))$Lisp sendSF(VIEW,hi(second tonto))$Lisp sendSF(VIEW,first (graf.unitsField))$Lisp sendSF(VIEW,second (graf.unitsField))$Lisp sendI(VIEW,n)$Lisp -- how many lists of points are being sent for aList in graf.llPoints for pColor in graf.pointColors for lColor in graf.lineColors for s in graf.pointSizes repeat sendI(VIEW,#aList)$Lisp -- how many points in this list for p in aList repeat aPoint := transform p sendSF(VIEW,xCoord aPoint)$Lisp sendSF(VIEW,yCoord aPoint)$Lisp sendSF(VIEW,hue(p)$PP)$Lisp -- ?use aPoint as well...? sendSF(VIEW,shade(p)$PP)$Lisp hueShade := hue hue pColor + shade pColor * numberOfHues() sendI(VIEW,hueShade)$Lisp hueShade := (hue hue lColor -1)*5 + shade lColor sendI(VIEW,hueShade)$Lisp sendI(VIEW,s)$Lisp graf.key := getI(VIEW)$Lisp graf --%Exported Functions makeGraphImage(graf:$) == makeGraph graf key graf == graf.key pointLists graf == graf.llPoints ranges graf == null graf.rangesField => [] [segment(convert(lo graf.rangesField.1)@F,convert(hi graf.rangesField.1)@F), _ segment(convert(lo graf.rangesField.2)@F,convert(hi graf.rangesField.2)@F)] ranges(graf,rangesList) == graf.rangesField := [segment(convert(lo rangesList.1)@SF,convert(hi rangesList.1)@SF), _ segment(convert(lo rangesList.2)@SF,convert(hi rangesList.2)@SF)] rangesList units graf == null(graf.unitsField) => [] [convert(graf.unitsField.1)@F,convert(graf.unitsField.2)@F] units (graf,unitsToBe) == graf.unitsField := [convert(unitsToBe.1)@SF,convert(unitsToBe.2)@SF] unitsToBe graphImage == graph [] makeGraphImage(llp: L L P) == l := #llp makeGraphImage(llp, [pointColorDefault() for i in 1..l], [lineColorDefault() for i in 1..l], [pointSizeDefault() for i in 1..l]) makeGraphImage(llp,lpc,llc,lps) == makeGraphImage(llp,lpc,llc,lps,[]) makeGraphImage(llp,lpc,llc,lps,opts) == graf := graph(ranges(opts,[])) graf.optionsField := opts graf := plotLists(graf,llp,lpc,llc,lps) transform := coord(graf.optionsField,cartesian$COORDSYS)$DrawOptionFunctions0 for aList in graf.llPoints repeat for p in aList repeat aPoint := transform p numberCheck aPoint makeGraph graf component (graf:$,ListOfPoints:L P,PointColor:PAL,LineColor:PAL,PointSize:PI) == graf.llPoints := append(graf.llPoints,[ListOfPoints]) graf.pointColors := append(graf.pointColors,[PointColor]) graf.lineColors := append(graf.lineColors,[LineColor]) graf.pointSizes := append(graf.pointSizes,[PointSize]) component (graf,aPoint) == component(graf,aPoint,pointColorDefault(),lineColorDefault(),pointSizeDefault()) component (graf:$,aPoint:P,PointColor:PAL,LineColor:PAL,PointSize:PI) == component (graf,[aPoint],PointColor,LineColor,PointSize) appendPoint (graf,aPoint) == num : I := #(graf.llPoints) - 1 negative? num => error "No point lists to append to!" (graf.llPoints.num) := append((graf.llPoints.num),[aPoint]) point (graf,aPoint,PointColor) == component(graf,aPoint,PointColor,lineColorDefault(),pointSizeDefault()) coerce (llp : L L P) : $ == l := #llp makeGraphImage(llp, [pointColorDefault() for i in 1..l], [lineColorDefault() for i in 1..l], [pointSizeDefault() for i in 1..l]) coerce (graf : $) : E == hconcat( ["Graph with " :: E,(p := # pointLists graf) :: E, (p=1 => " point list"; " point lists") :: E]) @ \section{domain VIEW2D TwoDimensionalViewport} \subsection{Creating multiple graphs in a Viewport} We want to graph $x^3 * (a+b*x)$ on the interval $x=-1\ldots1$ so we clear out the workspace <>= )clear all @ We assign values to the constants <>= a:=0.5 b:=0.5 @ We draw the first case of the graph <>= y1:=draw(x^3*(a+b*x),x=-1..1,title=="2.2.10 explicit") @ We fetch the graph of the first object <>= g1:=getGraph(y1,1) @ We extract its points <>= pointLists g1 @ Now we create a second graph with a changed parameter <>= b:=1.0 @ We draw it <>= y2:=draw(x^3*(a+b*x),x=-1..1) @ We fetch this new graph <>= g2:=getGraph(y2,1) @ We get the points from this graph <>= pointLists g2 @ and we put these points, $g2$ onto the first graph $y1$ as graph $2$ <>= putGraph(y1,g2,2) @ And now we do the whole sequence again <>= b:=2.0 y3:=draw(x^3*(a+b*x),x=-1..1) g3:=getGraph(y3,1) pointLists g3 @ and put the third graphs points $g3$ onto the first graph $y1$ as graph $3$ <>= putGraph(y1,g3,3) @ Finally we show the combined result <>= vp:=makeViewport2D(y1) @ <>= )abbrev domain VIEW2D TwoDimensionalViewport ++ Author: Jim Wen ++ Date Created: 28 April 1989 ++ Date Last Updated: 29 October 1991, Jon Steinbach ++ Basic Operations: ++ Related Constructors: ++ Also See: ++ AMS Classifications: ++ Keywords: ++ References: ++ Description: TwoDimensionalViewport creates viewports to display graphs. TwoDimensionalViewport ():Exports == Implementation where VIEW ==> _$ViewportServer$Lisp sendI ==> sockSendInt sendSF ==> sockSendFloat sendSTR ==> sockSendString getI ==> sockGetInt getSF ==> sockGetFloat typeGRAPH ==> 2 typeVIEW2D ==> 3 makeGRAPH ==> (-1)$SingleInteger makeVIEW2D ==> (-1)$SingleInteger I ==> Integer PI ==> PositiveInteger NNI ==> NonNegativeInteger XY ==> Record( X:I, Y:I ) XYP ==> Record( X:PI, Y:PI ) XYNN ==> Record( X:NNI, Y:NNI ) F ==> Float SF ==> DoubleFloat STR ==> String L ==> List V ==> Vector E ==> OutputForm FLAG ==> Record( showCP:I ) PAL ==> Palette() B ==> Boolean G ==> GraphImage GS ==> Record( scaleX:SF, scaleY:SF, deltaX:SF, deltaY:SF, _ points:I, connect:I, spline:I, _ axes:I, axesColor:PAL, units:I, unitsColor:PAL, _ showing:I) GU ==> Union(G,"undefined") DROP ==> DrawOption POINT ==> Point(SF) TRANSLATE2D ==> 0$I SCALE2D ==> 1$I pointsOnOff ==> 2 connectOnOff ==> 3 spline2D ==> 4 -- used for controlling regions, now reset2D ==> 5 hideControl2D ==> 6 closeAll2D ==> 7 axesOnOff2D ==> 8 unitsOnOff2D ==> 9 SPADBUTTONPRESS ==> 100 MOVE ==> 102 RESIZE ==> 103 TITLE ==> 104 showing2D ==> 105 -- as defined in include/actions.h putGraph2D ==> 106 writeView ==> 110 axesColor2D ==> 112 unitsColor2D ==> 113 getPickedPTS ==> 119 graphStart ==> 13 -- as defined in include/actions.h noControl ==> 0$I yes ==> 1$I no ==> 0$I maxGRAPHS ==> 9::I -- should be the same as maxGraphs in include/view2D.h fileTypeDefs ==> ["PIXMAP"] -- see include/write.h for things to include Exports ==> SetCategory with getPickedPoints : $ -> L POINT ++ getPickedPoints(x) ++ returns a list of small floats for the points the ++ user interactively picked on the viewport ++ for full integration into the system, some design ++ issues need to be addressed: e.g. how to go through ++ the GraphImage interface, how to default to graphs, etc. viewport2D : () -> $ ++ viewport2D() returns an undefined two-dimensional viewport ++ of the domain \spadtype{TwoDimensionalViewport} whose ++ contents are empty. makeViewport2D : $ -> $ ++ makeViewport2D(v) takes the given two-dimensional viewport, ++ v, of the domain \spadtype{TwoDimensionalViewport} and ++ displays a viewport window on the screen which contains ++ the contents of v. options : $ -> L DROP ++ options(v) takes the given two-dimensional viewport, v, of the ++ domain \spadtype{TwoDimensionalViewport} and returns a list ++ containing the draw options from the domain \spadtype{DrawOption} ++ for v. options : ($,L DROP) -> $ ++ options(v,lopt) takes the given two-dimensional viewport, v, ++ of the domain \spadtype{TwoDimensionalViewport} and returns ++ v with it's draw options modified to be those which are indicated ++ in the given list, \spad{lopt} of domain \spadtype{DrawOption}. makeViewport2D : (G,L DROP) -> $ ++ makeViewport2D(gi,lopt) creates and displays a viewport window ++ of the domain \spadtype{TwoDimensionalViewport} whose graph ++ field is assigned to be the given graph, \spad{gi}, of domain ++ \spadtype{GraphImage}, and whose options field is set to be ++ the list of options, \spad{lopt} of domain \spadtype{DrawOption}. graphState : ($,PI,SF,SF,SF,SF,I,I,I,I,PAL,I,PAL,I) -> Void ++ graphState(v,num,sX,sY,dX,dY,pts,lns,box,axes,axesC,un,unC,cP) ++ sets the state of the characteristics for the graph indicated ++ by \spad{num} in the given two-dimensional viewport v, of domain ++ \spadtype{TwoDimensionalViewport}, to the values given as ++ parameters. The scaling of the graph in the x and y component ++ directions is set to be \spad{sX} and \spad{sY}; the window ++ translation in the x and y component directions is set to be ++ \spad{dX} and \spad{dY}; The graph points, lines, bounding box, ++ axes, or units will be shown in the viewport if their given ++ parameters \spad{pts}, \spad{lns}, \spad{box}, \spad{axes} or ++ \spad{un} are set to be \spad{1}, but will not be shown if they ++ are set to \spad{0}. The color of the axes and the color of the ++ units are indicated by the palette colors \spad{axesC} and ++ \spad{unC} respectively. To display the control panel when ++ the viewport window is displayed, set \spad{cP} to \spad{1}, ++ otherwise set it to \spad{0}. graphStates : $ -> V GS ++ graphStates(v) returns and shows a listing of a record containing ++ the current state of the characteristics of each of the ten graph ++ records in the given two-dimensional viewport, v, which is of ++ domain \spadtype{TwoDimensionalViewport}. graphs : $ -> V GU ++ graphs(v) returns a vector, or list, which is a union of all ++ the graphs, of the domain \spadtype{GraphImage}, which are ++ allocated for the two-dimensional viewport, v, of domain ++ \spadtype{TwoDimensionalViewport}. Those graphs which have ++ no data are labeled "undefined", otherwise their contents ++ are shown. title : ($,STR) -> Void ++ title(v,s) changes the title which is shown in the two-dimensional ++ viewport window, v of domain \spadtype{TwoDimensionalViewport}. putGraph : ($,G,PI) -> Void ++ putGraph(v,gi,n) sets the graph field indicated by n, of the ++ indicated two-dimensional viewport, v, which is of domain ++ \spadtype{TwoDimensionalViewport}, to be the graph, \spad{gi} ++ of domain \spadtype{GraphImage}. The contents of viewport, v, ++ will contain \spad{gi} when the function \spadfun{makeViewport2D} ++ is called to create the an updated viewport v. getGraph : ($,PI) -> G ++ getGraph(v,n) returns the graph which is of the domain ++ \spadtype{GraphImage} which is located in graph field n ++ of the given two-dimensional viewport, v, which is of the ++ domain \spadtype{TwoDimensionalViewport}. axes : ($,PI,STR) -> Void ++ axes(v,n,s) displays the axes of the graph in field n of ++ the given two-dimensional viewport, v, which is of domain ++ \spadtype{TwoDimensionalViewport}, if s is "on", or does ++ not display the axes if s is "off". axes : ($,PI,PAL) -> Void ++ axes(v,n,c) displays the axes of the graph in field n of ++ the given two-dimensional viewport, v, which is of domain ++ \spadtype{TwoDimensionalViewport}, with the axes color set to ++ the given palette color c. units : ($,PI,STR) -> Void ++ units(v,n,s) displays the units of the graph in field n of ++ the given two-dimensional viewport, v, which is of domain ++ \spadtype{TwoDimensionalViewport}, if s is "on", or does ++ not display the units if s is "off". units : ($,PI,PAL) -> Void ++ units(v,n,c) displays the units of the graph in field n of ++ the given two-dimensional viewport, v, which is of domain ++ \spadtype{TwoDimensionalViewport}, with the units color set to ++ the given palette color c. points : ($,PI,STR) -> Void ++ points(v,n,s) displays the points of the graph in field n of ++ the given two-dimensional viewport, v, which is of domain ++ \spadtype{TwoDimensionalViewport}, if s is "on", or does ++ not display the points if s is "off". region : ($,PI,STR) -> Void ++ region(v,n,s) displays the bounding box of the graph in ++ field n of the given two-dimensional viewport, v, which is ++ of domain \spadtype{TwoDimensionalViewport}, if s is "on", ++ or does not display the bounding box if s is "off". connect : ($,PI,STR) -> Void ++ connect(v,n,s) displays the lines connecting the graph ++ points in field n of the given two-dimensional viewport, v, ++ which is of domain \spadtype{TwoDimensionalViewport}, if s ++ is "on", or does not display the lines if s is "off". controlPanel : ($,STR) -> Void ++ controlPanel(v,s) displays the control panel of the given ++ two-dimensional viewport, v, which is of domain ++ \spadtype{TwoDimensionalViewport}, if s is "on", or hides ++ the control panel if s is "off". close : $ -> Void ++ close(v) closes the viewport window of the given ++ two-dimensional viewport, v, which is of domain ++ \spadtype{TwoDimensionalViewport}, and terminates the ++ corresponding process ID. dimensions : ($,NNI,NNI,PI,PI) -> Void ++ dimensions(v,x,y,width,height) sets the position of the ++ upper left-hand corner of the two-dimensional viewport, v, ++ which is of domain \spadtype{TwoDimensionalViewport}, to ++ the window coordinate x, y, and sets the dimensions of the ++ window to that of \spad{width}, \spad{height}. The new ++ dimensions are not displayed until the function ++ \spadfun{makeViewport2D} is executed again for v. scale : ($,PI,F,F) -> Void ++ scale(v,n,sx,sy) displays the graph in field n of the given ++ two-dimensional viewport, v, which is of domain ++ \spadtype{TwoDimensionalViewport}, scaled by the factor \spad{sx} ++ in the x-coordinate direction and by the factor \spad{sy} in ++ the y-coordinate direction. translate : ($,PI,F,F) -> Void ++ translate(v,n,dx,dy) displays the graph in field n of the given ++ two-dimensional viewport, v, which is of domain ++ \spadtype{TwoDimensionalViewport}, translated by \spad{dx} in ++ the x-coordinate direction from the center of the viewport, and ++ by \spad{dy} in the y-coordinate direction from the center. ++ Setting \spad{dx} and \spad{dy} to \spad{0} places the center ++ of the graph at the center of the viewport. show : ($,PI,STR) -> Void ++ show(v,n,s) displays the graph in field n of the given ++ two-dimensional viewport, v, which is of domain ++ \spadtype{TwoDimensionalViewport}, if s is "on", or does not ++ display the graph if s is "off". move : ($,NNI,NNI) -> Void ++ move(v,x,y) displays the two-dimensional viewport, v, which ++ is of domain \spadtype{TwoDimensionalViewport}, with the upper ++ left-hand corner of the viewport window at the screen ++ coordinate position x, y. update :($,G,PI) -> Void ++ update(v,gr,n) drops the graph \spad{gr} in slot \spad{n} ++ of viewport \spad{v}. The graph gr must have been ++ transmitted already and acquired an integer key. resize : ($,PI,PI) -> Void ++ resize(v,w,h) displays the two-dimensional viewport, v, which ++ is of domain \spadtype{TwoDimensionalViewport}, with a width ++ of w and a height of h, keeping the upper left-hand corner ++ position unchanged. write : ($,STR) -> STR ++ write(v,s) takes the given two-dimensional viewport, v, which ++ is of domain \spadtype{TwoDimensionalViewport}, and creates ++ a directory indicated by s, which contains the graph data ++ files for v. write : ($,STR,STR) -> STR ++ write(v,s,f) takes the given two-dimensional viewport, v, which ++ is of domain \spadtype{TwoDimensionalViewport}, and creates ++ a directory indicated by s, which contains the graph data ++ files for v and an optional file type f. write : ($,STR,L STR) -> STR ++ write(v,s,lf) takes the given two-dimensional viewport, v, which ++ is of domain \spadtype{TwoDimensionalViewport}, and creates ++ a directory indicated by s, which contains the graph data ++ files for v and the optional file types indicated by the list lf. reset : $ -> Void ++ reset(v) sets the current state of the graph characteristics ++ of the given two-dimensional viewport, v, which is of domain ++ \spadtype{TwoDimensionalViewport}, back to their initial settings. key : $ -> I ++ key(v) returns the process ID number of the given two-dimensional ++ viewport, v, which is of domain \spadtype{TwoDimensionalViewport}. Implementation ==> add import GraphImage() import Color() import Palette() import ViewDefaultsPackage() import DrawOptionFunctions0 import POINT Rep := Record (key:I, graphsField:V GU, graphStatesField:V GS, _ title:STR, moveTo:XYNN, size:XYP, flags:FLAG, optionsField:L DROP) defaultGS : GS := [convert(0.9)@SF, convert(0.9)@SF, 0$SF, 0$SF, _ yes, yes, no, _ yes, axesColorDefault(), no, unitsColorDefault(), _ yes] --% Local Functions checkViewport (viewport:$):B == -- checks to see if this viewport still exists -- by sending the key to the viewport manager and -- waiting for its reply after it checks it against -- the viewports in its list. a -1 means it doesn't -- exist. sendI(VIEW,viewport.key)$Lisp i: Integer := getI(VIEW)$Lisp negative? i => viewport.key := 0$I error "This viewport has already been closed!" true doOptions(v:Rep):Void == v.title := title(v.optionsField,"AXIOM2D") -- etc - 2D specific stuff... --% Exported Functions options viewport == viewport.optionsField options(viewport,opts) == viewport.optionsField := opts viewport putGraph (viewport,aGraph,which) == if ((which > maxGRAPHS) or (which < 1)) then error "Trying to put a graph with a negative index or too big an index" viewport.graphsField.which := aGraph getGraph (viewport,which) == if ((which > maxGRAPHS) or (which < 1)) then error "Trying to get a graph with a negative index or too big an index" viewport.graphsField.which case "undefined" => error "Graph is undefined!" viewport.graphsField.which::GraphImage graphStates viewport == viewport.graphStatesField graphs viewport == viewport.graphsField key viewport == viewport.key dimensions(viewport,ViewX,ViewY,ViewWidth,ViewHeight) == viewport.moveTo := [ViewX,ViewY] viewport.size := [ViewWidth,ViewHeight] move(viewport,xLoc,yLoc) == viewport.moveTo := [xLoc,yLoc] (key(viewport) ~= 0$I) => sendI(VIEW,typeVIEW2D)$Lisp sendI(VIEW,MOVE)$Lisp checkViewport viewport => sendI(VIEW,xLoc)$Lisp sendI(VIEW,yLoc)$Lisp getI(VIEW)$Lisp -- acknowledge update(viewport,graph,slot) == (key(viewport) ~= 0$I) => sendI(VIEW,typeVIEW2D)$Lisp sendI(VIEW,putGraph2D)$Lisp checkViewport viewport => sendI(VIEW,key graph)$Lisp sendI(VIEW,slot)$Lisp getI(VIEW)$Lisp -- acknowledge resize(viewport,xSize,ySize) == viewport.size := [xSize,ySize] (key(viewport) ~= 0$I) => sendI(VIEW,typeVIEW2D)$Lisp sendI(VIEW,RESIZE)$Lisp checkViewport viewport => sendI(VIEW,xSize)$Lisp sendI(VIEW,ySize)$Lisp getI(VIEW)$Lisp -- acknowledge translate(viewport,graphIndex,xTranslateF,yTranslateF) == xTranslate := convert(xTranslateF)@SF yTranslate := convert(yTranslateF)@SF if (graphIndex > maxGRAPHS) then error "Referring to a graph with too big an index" viewport.graphStatesField.graphIndex.deltaX := xTranslate viewport.graphStatesField.graphIndex.deltaY := yTranslate (key(viewport) ~= 0$I) => sendI(VIEW,typeVIEW2D)$Lisp sendI(VIEW,TRANSLATE2D)$Lisp checkViewport viewport => sendI(VIEW,graphIndex)$Lisp sendSF(VIEW,xTranslate)$Lisp sendSF(VIEW,yTranslate)$Lisp getI(VIEW)$Lisp -- acknowledge scale(viewport,graphIndex,xScaleF,yScaleF) == xScale := convert(xScaleF)@SF yScale := convert(yScaleF)@SF if (graphIndex > maxGRAPHS) then error "Referring to a graph with too big an index" viewport.graphStatesField.graphIndex.scaleX := xScale -- check union (undefined?) viewport.graphStatesField.graphIndex.scaleY := yScale -- check union (undefined?) (key(viewport) ~= 0$I) => sendI(VIEW,typeVIEW2D)$Lisp sendI(VIEW,SCALE2D)$Lisp checkViewport viewport => sendI(VIEW,graphIndex)$Lisp sendSF(VIEW,xScale)$Lisp sendSF(VIEW,yScale)$Lisp getI(VIEW)$Lisp -- acknowledge viewport2D == [0,new(maxGRAPHS,"undefined"), _ new(maxGRAPHS,copy defaultGS),"AXIOM2D", _ [viewPosDefault().1,viewPosDefault().2],[viewSizeDefault().1,viewSizeDefault().2], _ [noControl], [] ] makeViewport2D(g:G,opts:L DROP) == viewport := viewport2D() viewport.graphsField.1 := g viewport.optionsField := opts makeViewport2D viewport makeViewport2D viewportDollar == viewport := viewportDollar::Rep doOptions viewport --local function to extract and assign optional arguments for 2D viewports sayBrightly([" AXIOM2D data being transmitted to the viewport manager..."::E]$List(E))$Lisp sendI(VIEW,typeVIEW2D)$Lisp sendI(VIEW,makeVIEW2D)$Lisp sendSTR(VIEW,viewport.title)$Lisp sendI(VIEW,viewport.moveTo.X)$Lisp sendI(VIEW,viewport.moveTo.Y)$Lisp sendI(VIEW,viewport.size.X)$Lisp sendI(VIEW,viewport.size.Y)$Lisp sendI(VIEW,viewport.flags.showCP)$Lisp for i in 1..maxGRAPHS repeat g := (graphs viewport).i if g case "undefined" then sendI(VIEW,0$I)$Lisp else sendI(VIEW,key(g::G))$Lisp gs := (graphStates viewport).i sendSF(VIEW,gs.scaleX)$Lisp sendSF(VIEW,gs.scaleY)$Lisp sendSF(VIEW,gs.deltaX)$Lisp sendSF(VIEW,gs.deltaY)$Lisp sendI(VIEW,gs.points)$Lisp sendI(VIEW,gs.connect)$Lisp sendI(VIEW,gs.spline)$Lisp sendI(VIEW,gs.axes)$Lisp hueShade := hue hue gs.axesColor + shade gs.axesColor * numberOfHues() sendI(VIEW,hueShade)$Lisp sendI(VIEW,gs.units)$Lisp hueShade := hue hue gs.unitsColor + shade gs.unitsColor * numberOfHues() sendI(VIEW,hueShade)$Lisp sendI(VIEW,gs.showing)$Lisp viewport.key := getI(VIEW)$Lisp viewport graphState(viewport,num,sX,sY,dX,dY,Points,Lines,Spline, _ Axes,AxesColor,Units,UnitsColor,Showing) == viewport.graphStatesField.num := [sX,sY,dX,dY,Points,Lines,Spline, _ Axes,AxesColor,Units,UnitsColor,Showing] title(viewport,Title) == viewport.title := Title (key(viewport) ~= 0$I) => sendI(VIEW,typeVIEW2D)$Lisp sendI(VIEW,TITLE)$Lisp checkViewport viewport => sendSTR(VIEW,Title)$Lisp getI(VIEW)$Lisp -- acknowledge reset viewport == (key(viewport) ~= 0$I) => sendI(VIEW,typeVIEW2D)$Lisp sendI(VIEW,SPADBUTTONPRESS)$Lisp checkViewport viewport => sendI(VIEW,reset2D)$Lisp getI(VIEW)$Lisp -- acknowledge axes (viewport:$,graphIndex:PI,onOff:STR) : Void == if (graphIndex > maxGRAPHS) then error "Referring to a graph with too big an index" if onOff = "on" then status := yes else status := no viewport.graphStatesField.graphIndex.axes := status -- check union (undefined?) (key(viewport) ~= 0$I) => sendI(VIEW,typeVIEW2D)$Lisp sendI(VIEW,axesOnOff2D)$Lisp checkViewport viewport => sendI(VIEW,graphIndex)$Lisp sendI(VIEW,status)$Lisp getI(VIEW)$Lisp -- acknowledge axes (viewport:$,graphIndex:PI,color:PAL) : Void == if (graphIndex > maxGRAPHS) then error "Referring to a graph with too big an index" viewport.graphStatesField.graphIndex.axesColor := color (key(viewport) ~= 0$I) => sendI(VIEW,typeVIEW2D)$Lisp sendI(VIEW,axesColor2D)$Lisp checkViewport viewport => sendI(VIEW,graphIndex)$Lisp hueShade := hue hue color + shade color * numberOfHues() sendI(VIEW,hueShade)$Lisp getI(VIEW)$Lisp -- acknowledge units (viewport:$,graphIndex:PI,onOff:STR) : Void == if (graphIndex > maxGRAPHS) then error "Referring to a graph with too big an index" if onOff = "on" then status := yes else status := no viewport.graphStatesField.graphIndex.units := status -- check union (undefined?) (key(viewport) ~= 0$I) => sendI(VIEW,typeVIEW2D)$Lisp sendI(VIEW,unitsOnOff2D)$Lisp checkViewport viewport => sendI(VIEW,graphIndex)$Lisp sendI(VIEW,status)$Lisp getI(VIEW)$Lisp -- acknowledge units (viewport:$,graphIndex:PI,color:PAL) : Void == if (graphIndex > maxGRAPHS) then error "Referring to a graph with too big an index" viewport.graphStatesField.graphIndex.unitsColor := color (key(viewport) ~= 0$I) => sendI(VIEW,typeVIEW2D)$Lisp sendI(VIEW,unitsColor2D)$Lisp checkViewport viewport => sendI(VIEW,graphIndex)$Lisp hueShade := hue hue color + shade color * numberOfHues() sendI(VIEW,hueShade)$Lisp getI(VIEW)$Lisp -- acknowledge connect (viewport:$,graphIndex:PI,onOff:STR) : Void == if (graphIndex > maxGRAPHS) then error "Referring to a graph with too big an index" if onOff = "on" then status := 1$I else status := 0$I viewport.graphStatesField.graphIndex.connect := status -- check union (undefined?) (key(viewport) ~= 0$I) => sendI(VIEW,typeVIEW2D)$Lisp sendI(VIEW,connectOnOff)$Lisp checkViewport viewport => sendI(VIEW,graphIndex)$Lisp sendI(VIEW,status)$Lisp getI(VIEW)$Lisp -- acknowledge points (viewport:$,graphIndex:PI,onOff:STR) : Void == if (graphIndex > maxGRAPHS) then error "Referring to a graph with too big an index" if onOff = "on" then status := 1$I else status := 0$I viewport.graphStatesField.graphIndex.points := status -- check union (undefined?) (key(viewport) ~= 0$I) => sendI(VIEW,typeVIEW2D)$Lisp sendI(VIEW,pointsOnOff)$Lisp checkViewport viewport => sendI(VIEW,graphIndex)$Lisp sendI(VIEW,status)$Lisp getI(VIEW)$Lisp -- acknowledge region (viewport:$,graphIndex:PI,onOff:STR) : Void == if (graphIndex > maxGRAPHS) then error "Referring to a graph with too big an index" if onOff = "on" then status := 1$I else status := 0$I viewport.graphStatesField.graphIndex.spline := status -- check union (undefined?) (key(viewport) ~= 0$I) => sendI(VIEW,typeVIEW2D)$Lisp sendI(VIEW,spline2D)$Lisp checkViewport viewport => sendI(VIEW,graphIndex)$Lisp sendI(VIEW,status)$Lisp getI(VIEW)$Lisp -- acknowledge show (viewport,graphIndex,onOff) == if (graphIndex > maxGRAPHS) then error "Referring to a graph with too big an index" if onOff = "on" then status := 1$I else status := 0$I viewport.graphStatesField.graphIndex.showing := status -- check union (undefined?) (key(viewport) ~= 0$I) => sendI(VIEW,typeVIEW2D)$Lisp sendI(VIEW,showing2D)$Lisp checkViewport viewport => sendI(VIEW,graphIndex)$Lisp sendI(VIEW,status)$Lisp getI(VIEW)$Lisp -- acknowledge controlPanel (viewport,onOff) == if onOff = "on" then viewport.flags.showCP := yes else viewport.flags.showCP := no (key(viewport) ~= 0$I) => sendI(VIEW,typeVIEW2D)$Lisp sendI(VIEW,hideControl2D)$Lisp checkViewport viewport => sendI(VIEW,viewport.flags.showCP)$Lisp getI(VIEW)$Lisp -- acknowledge close viewport == (key(viewport) ~= 0$I) => sendI(VIEW,typeVIEW2D)$Lisp sendI(VIEW,closeAll2D)$Lisp checkViewport viewport => getI(VIEW)$Lisp -- acknowledge viewport.key := 0$I coerce viewport == (key(viewport) = 0$I) => hconcat ["Closed or Undefined TwoDimensionalViewport: "::E, (viewport.title)::E] hconcat ["TwoDimensionalViewport: "::E, (viewport.title)::E] write(viewport:$,Filename:STR,aThingToWrite:STR) == write(viewport,Filename,[aThingToWrite]) write(viewport,Filename) == write(viewport,Filename,viewWriteDefault()) write(viewport:$,Filename:STR,thingsToWrite:L STR) == stringToSend : STR := "" (key(viewport) ~= 0$I) => sendI(VIEW,typeVIEW2D)$Lisp sendI(VIEW,writeView)$Lisp checkViewport viewport => sendSTR(VIEW,Filename)$Lisp m := minIndex(avail := viewWriteAvailable()) for aTypeOfFile in thingsToWrite repeat if negative?(writeTypeInt:= position(upperCase aTypeOfFile,avail)-m) then sayBrightly([" > "::E,(concat(aTypeOfFile, _ " is not a valid file type for writing a 2D viewport"))::E]$List(E))$Lisp else sendI(VIEW,writeTypeInt+(1$I))$Lisp -- stringToSend := concat [stringToSend,"%",aTypeOfFile] -- sendSTR(VIEW,stringToSend)$Lisp sendI(VIEW,0$I)$Lisp -- no more types of things to write getI(VIEW)$Lisp -- acknowledge Filename "" -- FIXME: We should be indicating failure "" -- FIXME: We should be indicating failure @ \subsection{TEST VIEW2D} <>= <> @ \section{License} <>= --Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd. --All rights reserved. -- --Redistribution and use in source and binary forms, with or without --modification, are permitted provided that the following conditions are --met: -- -- - Redistributions of source code must retain the above copyright -- notice, this list of conditions and the following disclaimer. -- -- - Redistributions in binary form must reproduce the above copyright -- notice, this list of conditions and the following disclaimer in -- the documentation and/or other materials provided with the -- distribution. -- -- - Neither the name of The Numerical ALgorithms Group Ltd. nor the -- names of its contributors may be used to endorse or promote products -- derived from this software without specific prior written permission. -- --THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS --IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED --TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A --PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER --OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, --EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, --PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR --PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF --LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING --NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS --SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. @ <<*>>= <> <> <> @ \eject \begin{thebibliography}{99} \bibitem{1} nothing \end{thebibliography} \end{document}