\documentclass{article} \usepackage{open-axiom} \begin{document} \title{\$SPAD/src/algebra draw.spad} \author{Clifton J. Williamson, Scott Morrison, Jon Steinbach, Mike Dewar} \maketitle \begin{abstract} \end{abstract} \eject \tableofcontents \eject \section{package DRAWCFUN TopLevelDrawFunctionsForCompiledFunctions} <>= )abbrev package DRAWCFUN TopLevelDrawFunctionsForCompiledFunctions ++ Author: Clifton J. Williamson ++ Date Created: 22 June 1990 ++ Date Last Updated: January 1992 by Scott Morrison ++ Basic Operations: draw, recolor ++ Related Constructors: ++ Also See: ++ AMS Classifications: ++ Keywords: ++ References: ++ Description: TopLevelDrawFunctionsForCompiledFunctions provides top level ++ functions for drawing graphics of expressions. TopLevelDrawFunctionsForCompiledFunctions(): Exports == Implementation where ANY1 ==> AnyFunctions1 B ==> Boolean F ==> Float L ==> List SEG ==> Segment Float SF ==> DoubleFloat DROP ==> DrawOption PLOT ==> Plot PPC ==> ParametricPlaneCurve(SF -> SF) PSC ==> ParametricSpaceCurve(SF -> SF) PSF ==> ParametricSurface((SF,SF) -> SF) Pt ==> Point SF PSFUN ==> (SF, SF) -> Pt PCFUN ==> SF -> Pt SPACE3 ==> ThreeSpace(SF) VIEW2 ==> TwoDimensionalViewport VIEW3 ==> ThreeDimensionalViewport Exports ==> with --% Two Dimensional Function Plots draw: (SF -> SF,SEG,L DROP) -> VIEW2 ++ draw(f,a..b,l) draws the graph of \spad{y = f(x)} as x ++ ranges from \spad{min(a,b)} to \spad{max(a,b)}. ++ The options contained in the list l of ++ the domain \spad{DrawOption} are applied. draw: (SF -> SF,SEG) -> VIEW2 ++ draw(f,a..b) draws the graph of \spad{y = f(x)} as x ++ ranges from \spad{min(a,b)} to \spad{max(a,b)}. --% Parametric Plane Curves draw: (PPC,SEG,L DROP) -> VIEW2 ++ draw(curve(f,g),a..b,l) draws the graph of the parametric ++ curve \spad{x = f(t), y = g(t)} as t ranges from \spad{min(a,b)} to ++ \spad{max(a,b)}. ++ The options contained in the list l of the domain \spad{DrawOption} ++ are applied. draw: (PPC,SEG) -> VIEW2 ++ draw(curve(f,g),a..b) draws the graph of the parametric ++ curve \spad{x = f(t), y = g(t)} as t ranges from \spad{min(a,b)} to ++ \spad{max(a,b)}. --% Parametric Space Curves draw: (PSC,SEG,L DROP) -> VIEW3 ++ draw(curve(f,g,h),a..b,l) draws the graph of the parametric ++ curve \spad{x = f(t), y = g(t), z = h(t)} as t ranges from ++ \spad{min(a,b)} to \spad{max(a,b)}. ++ The options contained in the list l of the domain ++ \spad{DrawOption} are applied. draw: (PSC,SEG) -> VIEW3 ++ draw(curve(f,g,h),a..b,l) draws the graph of the parametric ++ curve \spad{x = f(t), y = g(t), z = h(t)} as t ranges from ++ \spad{min(a,b)} to \spad{max(a,b)}. draw: (PCFUN,SEG,L DROP) -> VIEW3 ++ draw(f,a..b,l) draws the graph of the parametric ++ curve \spad{f} as t ranges from ++ \spad{min(a,b)} to \spad{max(a,b)}. ++ The options contained in the list l of the domain ++ \spad{DrawOption} are applied. draw: (PCFUN,SEG) -> VIEW3 ++ draw(f,a..b,l) draws the graph of the parametric ++ curve \spad{f} as t ranges from ++ \spad{min(a,b)} to \spad{max(a,b)}. makeObject: (PSC,SEG,L DROP) -> SPACE3 ++ makeObject(curve(f,g,h),a..b,l) returns a space of the ++ domain \spadtype{ThreeSpace} which contains the graph of the ++ parametric curve \spad{x = f(t), y = g(t), z = h(t)} as t ranges from ++ \spad{min(a,b)} to \spad{max(a,b)}; ++ The options contained in the list l of the domain ++ \spad{DrawOption} are applied. makeObject: (PSC,SEG) -> SPACE3 ++ makeObject(sp,curve(f,g,h),a..b) returns the space \spad{sp} ++ of the domain \spadtype{ThreeSpace} with the addition of the graph ++ of the parametric curve \spad{x = f(t), y = g(t), z = h(t)} as t ++ ranges from \spad{min(a,b)} to \spad{max(a,b)}. makeObject: (PCFUN,SEG,L DROP) -> SPACE3 ++ makeObject(curve(f,g,h),a..b,l) returns a space of the ++ domain \spadtype{ThreeSpace} which contains the graph of the ++ parametric curve \spad{x = f(t), y = g(t), z = h(t)} as t ranges from ++ \spad{min(a,b)} to \spad{max(a,b)}. ++ The options contained in the list l of the domain ++ \spad{DrawOption} are applied. makeObject: (PCFUN,SEG) -> SPACE3 ++ makeObject(sp,curve(f,g,h),a..b) returns the space \spad{sp} ++ of the domain \spadtype{ThreeSpace} with the addition of the graph ++ of the parametric curve \spad{x = f(t), y = g(t), z = h(t)} as t ++ ranges from \spad{min(a,b)} to \spad{max(a,b)}. --% Three Dimensional Function Plots draw: ((SF,SF) -> SF,SEG,SEG,L DROP) -> VIEW3 ++ draw(f,a..b,c..d,l) draws the graph of \spad{z = f(x,y)} ++ as x ranges from \spad{min(a,b)} to \spad{max(a,b)} and y ranges from ++ \spad{min(c,d)} to \spad{max(c,d)}. ++ and the options contained in the list l of the domain ++ \spad{DrawOption} are applied. draw: ((SF,SF) -> SF,SEG,SEG) -> VIEW3 ++ draw(f,a..b,c..d) draws the graph of \spad{z = f(x,y)} ++ as x ranges from \spad{min(a,b)} to \spad{max(a,b)} and y ranges from ++ \spad{min(c,d)} to \spad{max(c,d)}. makeObject: ((SF,SF) -> SF,SEG,SEG,L DROP) -> SPACE3 ++ makeObject(f,a..b,c..d,l) returns a space of the domain ++ \spadtype{ThreeSpace} which contains the graph of \spad{z = f(x,y)} ++ as x ranges from \spad{min(a,b)} to \spad{max(a,b)} and y ranges from ++ \spad{min(c,d)} to \spad{max(c,d)}, and the options contained in the ++ list l of the domain \spad{DrawOption} are applied. makeObject: ((SF,SF) -> SF,SEG,SEG) -> SPACE3 ++ makeObject(f,a..b,c..d) returns a space of the domain ++ \spadtype{ThreeSpace} which contains the graph of \spad{z = f(x,y)} ++ as x ranges from \spad{min(a,b)} to \spad{max(a,b)} and y ranges from ++ \spad{min(c,d)} to \spad{max(c,d)}. --% Parametric Surfaces draw: (PSFUN, SEG, SEG, L DROP) -> VIEW3 ++ draw(f,a..b,c..d) draws the ++ graph of the parametric surface \spad{f(u,v)} ++ as u ranges from \spad{min(a,b)} to \spad{max(a,b)} ++ and v ranges from \spad{min(c,d)} to \spad{max(c,d)}. ++ The options contained in the ++ list l of the domain \spad{DrawOption} are applied. draw: (PSFUN, SEG, SEG) -> VIEW3 ++ draw(f,a..b,c..d) draws the ++ graph of the parametric surface \spad{f(u,v)} ++ as u ranges from \spad{min(a,b)} to \spad{max(a,b)} ++ and v ranges from \spad{min(c,d)} to \spad{max(c,d)} ++ The options contained in the list ++ l of the domain \spad{DrawOption} are applied. makeObject: (PSFUN, SEG, SEG, L DROP) -> SPACE3 ++ makeObject(f,a..b,c..d,l) returns a ++ space of the domain \spadtype{ThreeSpace} which contains the ++ graph of the parametric surface \spad{f(u,v)} ++ as u ranges from \spad{min(a,b)} to ++ \spad{max(a,b)} and v ranges from \spad{min(c,d)} to \spad{max(c,d)}; ++ The options contained in the ++ list l of the domain \spad{DrawOption} are applied. makeObject: (PSFUN, SEG, SEG) -> SPACE3 ++ makeObject(f,a..b,c..d,l) returns a ++ space of the domain \spadtype{ThreeSpace} which contains the ++ graph of the parametric surface \spad{f(u,v)} ++ as u ranges from \spad{min(a,b)} to ++ \spad{max(a,b)} and v ranges from \spad{min(c,d)} to \spad{max(c,d)}. draw: (PSF,SEG,SEG,L DROP) -> VIEW3 ++ draw(surface(f,g,h),a..b,c..d) draws the ++ graph of the parametric surface \spad{x = f(u,v)}, \spad{y = g(u,v)}, ++ \spad{z = h(u,v)} as u ranges from \spad{min(a,b)} to \spad{max(a,b)} ++ and v ranges from \spad{min(c,d)} to \spad{max(c,d)}; ++ The options contained in the ++ list l of the domain \spad{DrawOption} are applied. draw: (PSF,SEG,SEG) -> VIEW3 ++ draw(surface(f,g,h),a..b,c..d) draws the ++ graph of the parametric surface \spad{x = f(u,v)}, \spad{y = g(u,v)}, ++ \spad{z = h(u,v)} as u ranges from \spad{min(a,b)} to \spad{max(a,b)} ++ and v ranges from \spad{min(c,d)} to \spad{max(c,d)}; makeObject: (PSF,SEG,SEG,L DROP) -> SPACE3 ++ makeObject(surface(f,g,h),a..b,c..d,l) returns a ++ space of the domain \spadtype{ThreeSpace} which contains the ++ graph of the parametric surface \spad{x = f(u,v)}, \spad{y = g(u,v)}, ++ \spad{z = h(u,v)} as u ranges from \spad{min(a,b)} to ++ \spad{max(a,b)} and v ranges from \spad{min(c,d)} to \spad{max(c,d)}. ++ The options contained in the ++ list l of the domain \spad{DrawOption} are applied. makeObject: (PSF,SEG,SEG) -> SPACE3 ++ makeObject(surface(f,g,h),a..b,c..d,l) returns a ++ space of the domain \spadtype{ThreeSpace} which contains the ++ graph of the parametric surface \spad{x = f(u,v)}, \spad{y = g(u,v)}, ++ \spad{z = h(u,v)} as u ranges from \spad{min(a,b)} to ++ \spad{max(a,b)} and v ranges from \spad{min(c,d)} to \spad{max(c,d)}. recolor: ((SF,SF) -> Pt,(SF,SF,SF) -> SF) -> ((SF,SF) -> Pt) ++ recolor(), uninteresting to top level user; exported in order to ++ compile package. Implementation ==> add --!! I have had to work my way around the following bug in the compiler: --!! When a local variable is given a mapping as a value, e.g. --!! foo : SF -> SF := makeFloatFunction(f,t), --!! the compiler cannot distinguish that local variable from a local --!! function defined elsewhere in the package. Thus, when 'foo' is --!! passed to a function, e.g. --!! bird := fcn(foo), --!! foo will often be compiled as |DRAW;foo| rather than |foo|. This, --!! of course, causes a run-time error. --!! To avoid this problem, local variables are not given mappings as --!! values, but rather (singleton) lists of mappings. The first element --!! of the list can always be extracted and everything goes through --!! as before. There is no major loss in efficiency, as the computation --!! of points will always dominate the computation time. --!! - cjw, 22 June MCMXC import PLOT import TwoDimensionalPlotClipping import GraphicsDefaults import ViewportPackage import ThreeDimensionalViewport import DrawOptionFunctions0 import MakeFloatCompiledFunction(Ex) import MeshCreationRoutinesForThreeDimensions import SegmentFunctions2(SF,Float) import ViewDefaultsPackage import AnyFunctions1(Pt -> Pt) import AnyFunctions1((SF,SF,SF) -> SF) import DrawOptionFunctions0 import SPACE3 import DROP EXTOVARERROR : String := _ "draw: when specifying function, left hand side must be a variable" SMALLRANGEERROR : String := _ "draw: range is in interval with only one point" DEPVARERROR : String := _ "draw: independent variable appears on lhs of function definition" ------------------------------------------------------------------------ -- 2D - draw's ------------------------------------------------------------------------ drawToScaleRanges: (Segment SF,Segment SF) -> L SEG drawToScaleRanges(xVals,yVals) == -- warning: assumes window is square xHi := convert(hi xVals)@Float; xLo := convert(lo xVals)@Float yHi := convert(hi yVals)@Float; yLo := convert(lo yVals)@Float xDiff := xHi - xLo; yDiff := yHi - yLo pad := abs(yDiff - xDiff)/2 yDiff > xDiff => [segment(xLo - pad,xHi + pad),map(convert(#1)@Float,yVals)] [map(convert(#1)@Float,xVals),segment(yLo - pad,yHi + pad)] drawPlot: (PLOT,L DROP) -> VIEW2 drawPlot(plot,l) == branches := listBranches plot xRange := xRange plot; yRange := yRange plot -- process clipping information if (cl := option(l,"clipSegment" :: Symbol)) case "failed" then if clipBoolean(l,clipPointsDefault()) then clipInfo := parametric? plot => clipParametric plot clip plot branches := clipInfo.brans xRange := clipInfo.xValues; yRange := clipInfo.yValues else "No explicit user-specified clipping" else segList := retract(cl :: Any)$ANY1(L SEG) empty? segList => error "draw: you may specify at least 1 segment for 2D clipping" #segList > 2 => error "draw: you may specify at most 2 segments for 2D clipping" xLo : SF := 0; xHi : SF := 0; yLo : SF := 0; yHi : SF := 0 if empty? rest segList then xLo := lo xRange; xHi := hi xRange yRangeF := first segList yLo := convert(lo yRangeF)@SF; yHi := convert(hi yRangeF)@SF else xRangeF := first segList xLo := convert(lo xRangeF)@SF; xHi := convert(hi xRangeF)@SF yRangeF := second segList yLo := convert(lo yRangeF)@SF; yHi := convert(hi yRangeF)@SF clipInfo := clipWithRanges(branches,xLo,xHi,yLo,yHi) branches := clipInfo.brans xRange := clipInfo.xValues; yRange := clipInfo.yValues -- process scaling information if toScale(l,drawToScale()) then scaledRanges := drawToScaleRanges(xRange,yRange) -- add scaled ranges to list of options l := concat(ranges scaledRanges,l) else xRangeFloat : SEG := map(convert(#1)@Float,xRange) yRangeFloat : SEG := map(convert(#1)@Float,yRange) -- add ranges to list of options l := concat(ranges(ll : L SEG := [xRangeFloat,yRangeFloat]),l) -- process color information ptCol := pointColorPalette(l,pointColorDefault()) crCol := curveColorPalette(l,lineColorDefault()) -- draw drawCurves(branches,ptCol,crCol,pointSizeDefault(),l) normalize: SEG -> Segment SF normalize seg == -- normalize [a,b]: -- error if a = b, returns [a,b] if a < b, returns [b,a] if b > a a := convert(lo seg)@SF; b := convert(hi seg)@SF a = b => error SMALLRANGEERROR a < b => segment(a,b) segment(b,a) --% functions for creation of maps SF -> Point SF (two dimensional) myTrap1: (SF-> SF, SF) -> SF myTrap1(ff:SF-> SF, f:SF):SF == s: Maybe SF := trapNumericErrors(ff(f))$Lisp s case nothing => quietDoubleNaN()$Foreign(Builtin) r := s@SF r > max()$SF or r < min()$SF => quietDoubleNaN()$Foreign(Builtin) r makePt2: (SF,SF) -> Point SF makePt2(x,y) == point(l : List SF := [x,y]) --% Two Dimensional Function Plots draw(f:SF -> SF,seg:SEG,l:L DROP) == -- set adaptive plotting off or on oldAdaptive := adaptive?()$PLOT setAdaptive(adaptive(l,oldAdaptive))$PLOT -- create function SF -> Point SF ff : L(SF -> Point SF) := [makePt2(myTrap1(f,#1),#1)] -- process change of coordinates if (c := option(l,"coordinates" :: Symbol)) case "failed" then -- default coordinate transformation ff := [makePt2(#1,myTrap1(f,#1))] else cc : L(Pt -> Pt) := [retract(c :: Any)$ANY1(Pt -> Pt)] ff := [(first cc)((first ff)(#1))] -- create PLOT pl := pointPlot(first ff,normalize seg) -- reset adaptive plotting setAdaptive(oldAdaptive)$PLOT -- draw drawPlot(pl,l) draw(f:SF -> SF,seg:SEG) == draw(f,seg,nil()) --% Parametric Plane Curves draw(ppc:PPC,seg:SEG,l:L DROP) == -- set adaptive plotting off or on oldAdaptive := adaptive?()$PLOT setAdaptive(adaptive(l,oldAdaptive))$PLOT -- create function SF -> Point SF f := coordinate(ppc,1); g := coordinate(ppc,2) fcn : L(SF -> Pt) := [makePt2(myTrap1(f,#1),myTrap1(g,#1))] -- process change of coordinates if not (c := option(l,"coordinates" :: Symbol)) case "failed" then cc : L(Pt -> Pt) := [retract(c :: Any)$ANY1(Pt -> Pt)] fcn := [(first cc)((first fcn)(#1))] -- create PLOT pl := pointPlot(first fcn,normalize seg) -- reset adaptive plotting setAdaptive(oldAdaptive)$PLOT -- draw drawPlot(pl,l) draw(ppc:PPC,seg:SEG) == draw(ppc,seg,nil()) ------------------------------------------------------------------------ -- 3D - Curves ------------------------------------------------------------------------ --% functions for creation of maps SF -> Point SF (three dimensional) makePt4: (SF,SF,SF,SF) -> Point SF makePt4(x,y,z,c) == point(l : List SF := [x,y,z,c]) --% Parametric Space Curves id: SF -> SF id x == x zCoord: (SF,SF,SF) -> SF zCoord(x,y,z) == z colorPoints: (List List Pt,(SF,SF,SF) -> SF) -> List List Pt colorPoints(llp,func) == for lp in llp repeat for p in lp repeat p.4 := func(p.1,p.2,p.3) llp makeObject(psc:PSC,seg:SEG,l:L DROP) == sp := space l -- obtain dependent variable and coordinate functions f := coordinate(psc,1); g := coordinate(psc,2); h := coordinate(psc,3) -- create function SF -> Point SF with default or user-specified -- color function fcn : L(SF -> Pt) := [makePt4(myTrap1(f,#1),myTrap1(g,#1),myTrap1(h,#1),_ myTrap1(id,#1))] pointsColored? : Boolean := false if not (c1 := option(l,"colorFunction1" :: Symbol)) case "failed" then pointsColored? := true fcn := [makePt4(myTrap1(f,#1),myTrap1(g,#1),myTrap1(h,#1),_ retract(c1 :: Any)$ANY1(SF -> SF)(#1))] -- process change of coordinates if not (c := option(l,"coordinates" :: Symbol)) case "failed" then cc : L(Pt -> Pt) := [retract(c :: Any)$ANY1(Pt -> Pt)] fcn := [(first cc)((first fcn)(#1))] -- create PLOT pl := pointPlot(first fcn,normalize seg)$Plot3D -- create ThreeSpace s := sp -- draw Tube -- print(pl::OutputForm) option?(l,"tubeRadius" :: Symbol) => pts := tubePoints(l,8) rad := convert(tubeRadius(l,0.25))@DoubleFloat tub := tube(pl,rad,pts)$NumericTubePlot(Plot3D) loops := listLoops tub -- color points if this has not been done already if not pointsColored? then if (c3 := option(l,"colorFunction3" :: Symbol)) case "failed" then colorPoints(loops,zCoord) -- default color function else colorPoints(loops,retract(c3 :: Any)$ANY1((SF,SF,SF) -> SF)) mesh(s,loops,false,false) s -- draw curve br := listBranches pl for b in br repeat curve(s,b) s makeObject(psc:PCFUN,seg:SEG,l:L DROP) == sp := space l -- create function SF -> Point SF with default or user-specified -- color function fcn : L(SF -> Pt) := [psc] pointsColored? : Boolean := false if not (c1 := option(l,"colorFunction1" :: Symbol)) case "failed" then pointsColored? := true fcn := [concat(psc(#1), retract(c1 :: Any)$ANY1(SF -> SF)(#1))] -- process change of coordinates if not (c := option(l,"coordinates" :: Symbol)) case "failed" then cc : L(Pt -> Pt) := [retract(c :: Any)$ANY1(Pt -> Pt)] fcn := [(first cc)((first fcn)(#1))] -- create PLOT pl := pointPlot(first fcn,normalize seg)$Plot3D -- create ThreeSpace s := sp -- draw Tube option?(l,"tubeRadius" :: Symbol) => pts := tubePoints(l,8) rad := convert(tubeRadius(l,0.25))@DoubleFloat tub := tube(pl,rad,pts)$NumericTubePlot(Plot3D) loops := listLoops tub -- color points if this has not been done already mesh(s,loops,false,false) s -- draw curve br := listBranches pl for b in br repeat curve(s,b) s makeObject(psc:PSC,seg:SEG) == makeObject(psc,seg,nil()) makeObject(psc:PCFUN,seg:SEG) == makeObject(psc,seg,nil()) draw(psc:PSC,seg:SEG,l:L DROP) == sp := makeObject(psc,seg,l) makeViewport3D(sp, l) draw(psc:PSC,seg:SEG) == draw(psc,seg,nil()) draw(psc:PCFUN,seg:SEG,l:L DROP) == sp := makeObject(psc,seg,l) makeViewport3D(sp, l) draw(psc:PCFUN,seg:SEG) == draw(psc,seg,nil()) ------------------------------------------------------------------------ -- 3D - Surfaces ------------------------------------------------------------------------ myTrap2: ((SF, SF) -> SF, SF, SF) -> SF myTrap2(ff:(SF, SF) -> SF, u:SF, v:SF):SF == s: Maybe SF := trapNumericErrors(ff(u, v))$Lisp s case nothing => quietDoubleNaN()$Foreign(Builtin) r := s@SF r > max()$SF or r < min()$SF => quietDoubleNaN()$Foreign(Builtin) r recolor(ptFunc,colFunc) == pt := ptFunc(#1,#2) pt.4 := colFunc(pt.1,pt.2,pt.3) pt xCoord: (SF,SF) -> SF xCoord(x,y) == x --% Three Dimensional Function Plots makeObject(f:(SF,SF) -> SF,xSeg:SEG,ySeg:SEG,l:L DROP) == sp := space l -- process color function of two variables col2 : L((SF,SF) -> SF) := [xCoord] -- dummy color function pointsColored? : Boolean := false if not (c2 := option(l,"colorFunction2" :: Symbol)) case "failed" then pointsColored? := true col2 := [retract(c2 :: Any)$ANY1((SF,SF) -> SF)] fcn : L((SF,SF) -> Pt) := [makePt4(myTrap2(f,#1,#2),#1,#2,(first col2)(#1,#2))] -- process change of coordinates if (c := option(l,"coordinates" :: Symbol)) case "failed" then -- default coordinate transformation fcn := [makePt4(#1,#2,myTrap2(f,#1,#2),(first col2)(#1,#2))] else cc : L(Pt -> Pt) := [retract(c :: Any)$ANY1(Pt -> Pt)] fcn := [(first cc)((first fcn)(#1,#2))] -- process color function of three variables, if there was no -- color function of two variables if not pointsColored? then c := option(l,"colorFunction3" :: Symbol) fcn := c case "failed" => [recolor((first fcn),zCoord)] [recolor((first fcn),retract(c :: Any)$ANY1((SF,SF,SF) -> SF))] -- create mesh mesh := meshPar2Var(sp,first fcn,normalize xSeg,normalize ySeg,l) mesh makeObject(f:(SF,SF) -> SF,xSeg:SEG,ySeg:SEG) == makeObject(f,xSeg,ySeg,nil()) draw(f:(SF,SF) -> SF,xSeg:SEG,ySeg:SEG,l:L DROP) == sp := makeObject(f, xSeg, ySeg, l) makeViewport3D(sp, l) draw(f:(SF,SF) -> SF,xSeg:SEG,ySeg:SEG) == draw(f,xSeg,ySeg,nil()) --% parametric surface makeObject(s:PSF,uSeg:SEG,vSeg:SEG,l:L DROP) == sp := space l -- create functions from expressions f : L((SF,SF) -> SF) := [coordinate(s,1)] g : L((SF,SF) -> SF) := [coordinate(s,2)] h : L((SF,SF) -> SF) := [coordinate(s,3)] -- process color function of two variables col2 : L((SF,SF) -> SF) := [xCoord] -- dummy color function pointsColored? : Boolean := false if not (c2 := option(l,"colorFunction2" :: Symbol)) case "failed" then pointsColored? := true col2 := [retract(c2 :: Any)$ANY1((SF,SF) -> SF)] fcn : L((SF,SF) -> Pt) := [makePt4(myTrap2((first f),#1,#2),myTrap2((first g),#1,#2),myTrap2((first h),#1,#2),_ myTrap2((first col2),#1,#2))] -- process change of coordinates if not (c := option(l,"coordinates" :: Symbol)) case "failed" then cc : L(Pt -> Pt) := [retract(c :: Any)$ANY1(Pt -> Pt)] fcn := [(first cc)((first fcn)(#1,#2))] -- process color function of three variables, if there was no -- color function of two variables if not pointsColored? then col3 : L((SF,SF,SF) -> SF) := [zCoord] -- default color function if not (c := option(l,"colorFunction3" :: Symbol)) case "failed" then col3 := [retract(c :: Any)$ANY1((SF,SF,SF) -> SF)] fcn := [recolor((first fcn),(first col3))] -- create mesh mesh := meshPar2Var(sp,first fcn,normalize uSeg,normalize vSeg,l) mesh makeObject(s:PSFUN,uSeg:SEG,vSeg:SEG,l:L DROP) == sp := space l -- process color function of two variables col2 : L((SF,SF) -> SF) := [xCoord] -- dummy color function pointsColored? : Boolean := false if not (c2 := option(l,"colorFunction2" :: Symbol)) case "failed" then pointsColored? := true col2 := [retract(c2 :: Any)$ANY1((SF,SF) -> SF)] fcn : L((SF,SF) -> Pt) := pointsColored? => [concat(s(#1, #2), (first col2)(#1, #2))] [s] -- process change of coordinates if not (c := option(l,"coordinates" :: Symbol)) case "failed" then cc : L(Pt -> Pt) := [retract(c :: Any)$ANY1(Pt -> Pt)] fcn := [(first cc)((first fcn)(#1,#2))] -- create mesh mesh := meshPar2Var(sp,first fcn,normalize uSeg,normalize vSeg,l) mesh makeObject(s:PSF,uSeg:SEG,vSeg:SEG) == makeObject(s,uSeg,vSeg,nil()) draw(s:PSF,uSeg:SEG,vSeg:SEG,l:L DROP) == -- draw mesh := makeObject(s,uSeg,vSeg,l) makeViewport3D(mesh,l) draw(s:PSF,uSeg:SEG,vSeg:SEG) == draw(s,uSeg,vSeg,nil()) makeObject(s:PSFUN,uSeg:SEG,vSeg:SEG) == makeObject(s,uSeg,vSeg,nil()) draw(s:PSFUN,uSeg:SEG,vSeg:SEG,l:L DROP) == -- draw mesh := makeObject(s,uSeg,vSeg,l) makeViewport3D(mesh,l) draw(s:PSFUN,uSeg:SEG,vSeg:SEG) == draw(s,uSeg,vSeg,nil()) @ \section{package DRAW TopLevelDrawFunctions} <>= )abbrev package DRAW TopLevelDrawFunctions ++ Author: Clifton J. Williamson ++ Date Created: 23 January 1990 ++ Date Last Updated: October 1991 by Jon Steinbach ++ Basic Operations: draw ++ Related Constructors: ++ Also See: ++ AMS Classifications: ++ Keywords: ++ References: ++ Description: TopLevelDrawFunctions provides top level functions for ++ drawing graphics of expressions. TopLevelDrawFunctions(Ex:Join(ConvertibleTo InputForm,SetCategory)): Exports == Implementation where B ==> Boolean BIND ==> SegmentBinding Float L ==> List SF ==> DoubleFloat DROP ==> DrawOption PPC ==> ParametricPlaneCurve Ex PPCF ==> ParametricPlaneCurve(SF -> SF) PSC ==> ParametricSpaceCurve Ex PSCF ==> ParametricSpaceCurve(SF -> SF) PSF ==> ParametricSurface Ex PSFF ==> ParametricSurface((SF,SF) -> SF) SPACE3 ==> ThreeSpace(SF) VIEW2 ==> TwoDimensionalViewport VIEW3 ==> ThreeDimensionalViewport Exports ==> with --% Two Dimensional Function Plots draw: (Ex,BIND,L DROP) -> VIEW2 ++ draw(f(x),x = a..b,l) draws the graph of \spad{y = f(x)} as x ++ ranges from \spad{min(a,b)} to \spad{max(a,b)}; \spad{f(x)} is the ++ default title, and the options contained in the list l of ++ the domain \spad{DrawOption} are applied. draw: (Ex,BIND) -> VIEW2 ++ draw(f(x),x = a..b) draws the graph of \spad{y = f(x)} as x ++ ranges from \spad{min(a,b)} to \spad{max(a,b)}; \spad{f(x)} appears ++ in the title bar. --% Parametric Plane Curves draw: (PPC,BIND,L DROP) -> VIEW2 ++ draw(curve(f(t),g(t)),t = a..b,l) draws the graph of the parametric ++ curve \spad{x = f(t), y = g(t)} as t ranges from \spad{min(a,b)} to ++ \spad{max(a,b)}; \spad{(f(t),g(t))} is the default title, and the ++ options contained in the list l of the domain \spad{DrawOption} ++ are applied. draw: (PPC,BIND) -> VIEW2 ++ draw(curve(f(t),g(t)),t = a..b) draws the graph of the parametric ++ curve \spad{x = f(t), y = g(t)} as t ranges from \spad{min(a,b)} to ++ \spad{max(a,b)}; \spad{(f(t),g(t))} appears in the title bar. --% Parametric Space Curves draw: (PSC,BIND,L DROP) -> VIEW3 ++ draw(curve(f(t),g(t),h(t)),t = a..b,l) draws the graph of the ++ parametric curve \spad{x = f(t)}, \spad{y = g(t)}, \spad{z = h(t)} ++ as t ranges from \spad{min(a,b)} to \spad{max(a,b)}; \spad{h(t)} ++ is the default title, and the options contained in the list l of ++ the domain \spad{DrawOption} are applied. draw: (PSC,BIND) -> VIEW3 ++ draw(curve(f(t),g(t),h(t)),t = a..b) draws the graph of the parametric ++ curve \spad{x = f(t)}, \spad{y = g(t)}, \spad{z = h(t)} as t ranges ++ from \spad{min(a,b)} to \spad{max(a,b)}; \spad{h(t)} is the default ++ title. makeObject: (PSC,BIND,L DROP) -> SPACE3 ++ makeObject(curve(f(t),g(t),h(t)),t = a..b,l) returns a space of ++ the domain \spadtype{ThreeSpace} which contains the graph of the ++ parametric curve \spad{x = f(t)}, \spad{y = g(t)}, \spad{z = h(t)} ++ as t ranges from \spad{min(a,b)} to \spad{max(a,b)}; \spad{h(t)} ++ is the default title, and the options contained in the list l of ++ the domain \spad{DrawOption} are applied. makeObject: (PSC,BIND) -> SPACE3 ++ makeObject(curve(f(t),g(t),h(t)),t = a..b) returns a space of the ++ domain \spadtype{ThreeSpace} which contains the graph of the ++ parametric curve \spad{x = f(t)}, \spad{y = g(t)}, \spad{z = h(t)} ++ as t ranges from \spad{min(a,b)} to \spad{max(a,b)}; \spad{h(t)} is ++ the default title. --% Three Dimensional Function Plots draw: (Ex,BIND,BIND,L DROP) -> VIEW3 ++ draw(f(x,y),x = a..b,y = c..d,l) draws the graph of \spad{z = f(x,y)} ++ as x ranges from \spad{min(a,b)} to \spad{max(a,b)} and y ranges from ++ \spad{min(c,d)} to \spad{max(c,d)}; \spad{f(x,y)} is the default ++ title, and the options contained in the list l of the domain ++ \spad{DrawOption} are applied. draw: (Ex,BIND,BIND) -> VIEW3 ++ draw(f(x,y),x = a..b,y = c..d) draws the graph of \spad{z = f(x,y)} ++ as x ranges from \spad{min(a,b)} to \spad{max(a,b)} and y ranges from ++ \spad{min(c,d)} to \spad{max(c,d)}; \spad{f(x,y)} appears in the title bar. makeObject: (Ex,BIND,BIND,L DROP) -> SPACE3 ++ makeObject(f(x,y),x = a..b,y = c..d,l) returns a space of the ++ domain \spadtype{ThreeSpace} which contains the graph of ++ \spad{z = f(x,y)} as x ranges from \spad{min(a,b)} to \spad{max(a,b)} ++ and y ranges from \spad{min(c,d)} to \spad{max(c,d)}; \spad{f(x,y)} ++ is the default title, and the options contained in the list l of the ++ domain \spad{DrawOption} are applied. makeObject: (Ex,BIND,BIND) -> SPACE3 ++ makeObject(f(x,y),x = a..b,y = c..d) returns a space of the domain ++ \spadtype{ThreeSpace} which contains the graph of \spad{z = f(x,y)} ++ as x ranges from \spad{min(a,b)} to \spad{max(a,b)} and y ranges from ++ \spad{min(c,d)} to \spad{max(c,d)}; \spad{f(x,y)} appears as the ++ default title. --% Parametric Surfaces draw: (PSF,BIND,BIND,L DROP) -> VIEW3 ++ draw(surface(f(u,v),g(u,v),h(u,v)),u = a..b,v = c..d,l) draws the ++ graph of the parametric surface \spad{x = f(u,v)}, \spad{y = g(u,v)}, ++ \spad{z = h(u,v)} as u ranges from \spad{min(a,b)} to \spad{max(a,b)} ++ and v ranges from \spad{min(c,d)} to \spad{max(c,d)}; \spad{h(t)} ++ is the default title, and the options contained in the list l of ++ the domain \spad{DrawOption} are applied. draw: (PSF,BIND,BIND) -> VIEW3 ++ draw(surface(f(u,v),g(u,v),h(u,v)),u = a..b,v = c..d) draws the ++ graph of the parametric surface \spad{x = f(u,v)}, \spad{y = g(u,v)}, ++ \spad{z = h(u,v)} as u ranges from \spad{min(a,b)} to \spad{max(a,b)} ++ and v ranges from \spad{min(c,d)} to \spad{max(c,d)}; \spad{h(t)} is ++ the default title. makeObject: (PSF,BIND,BIND,L DROP) -> SPACE3 ++ makeObject(surface(f(u,v),g(u,v),h(u,v)),u = a..b,v = c..d,l) returns ++ a space of the domain \spadtype{ThreeSpace} which contains the graph ++ of the parametric surface \spad{x = f(u,v)}, \spad{y = g(u,v)}, ++ \spad{z = h(u,v)} as u ranges from \spad{min(a,b)} to \spad{max(a,b)} ++ and v ranges from \spad{min(c,d)} to \spad{max(c,d)}; \spad{h(t)} is ++ the default title, and the options contained in the list l of ++ the domain \spad{DrawOption} are applied. makeObject: (PSF,BIND,BIND) -> SPACE3 ++ makeObject(surface(f(u,v),g(u,v),h(u,v)),u = a..b,v = c..d) returns ++ a space of the domain \spadtype{ThreeSpace} which contains the ++ graph of the parametric surface \spad{x = f(u,v)}, \spad{y = g(u,v)}, ++ \spad{z = h(u,v)} as u ranges from \spad{min(a,b)} to \spad{max(a,b)} ++ and v ranges from \spad{min(c,d)} to \spad{max(c,d)}; \spad{h(t)} is ++ the default title. Implementation ==> add import TopLevelDrawFunctionsForCompiledFunctions import MakeFloatCompiledFunction(Ex) import ParametricPlaneCurve(SF -> SF) import ParametricSpaceCurve(SF -> SF) import ParametricSurface((SF,SF) -> SF) import ThreeSpace(SF) ------------------------------------------------------------------------ -- 2D - draw's (given by formulae) ------------------------------------------------------------------------ --% Two Dimensional Function Plots draw(f:Ex,bind:BIND,l:L DROP) == import DROP -- create title if necessary if not option?(l,"title" :: Symbol) then s:String := unparse(convert(f)@InputForm) if sayLength(s)$DisplayPackage > 50 then l := concat(title "AXIOM2D",l) else l := concat(title s,l) -- call 'draw' draw(makeFloatFunction(f,variable bind),segment bind,l) draw(f:Ex,bind:BIND) == draw(f,bind,nil()) --% Parametric Plane Curves draw(ppc:PPC,bind:BIND,l:L DROP) == import DROP f := coordinate(ppc,1); g := coordinate(ppc,2) -- create title if necessary if not option?(l,"title" :: Symbol) then s:String := unparse(convert(f)@InputForm) if sayLength(s)$DisplayPackage > 50 then l := concat(title "AXIOM2D",l) else l := concat(title s,l) -- create curve with functions as coordinates curve : PPCF := curve(makeFloatFunction(f,variable bind),_ makeFloatFunction(g,variable bind))$PPCF -- call 'draw' draw(curve,segment bind,l) draw(ppc:PPC,bind:BIND) == draw(ppc,bind,nil()) ------------------------------------------------------------------------ -- 3D - Curves (given by formulas) ------------------------------------------------------------------------ makeObject(psc:PSC,tBind:BIND,l:L DROP) == import DROP -- obtain dependent variable and coordinate functions t := variable tBind; tSeg := segment tBind f := coordinate(psc,1); g := coordinate(psc,2); h := coordinate(psc,3) -- create title if necessary if not option?(l,"title" :: Symbol) then s:String := unparse(convert(f)@InputForm) if sayLength(s)$DisplayPackage > 50 then l := concat(title "AXIOM3D",l) else l := concat(title s,l) -- indicate draw style if necessary if not option?(l,"style" :: Symbol) then l := concat(style unparse(convert(f)@InputForm),l) -- create curve with functions as coordinates curve : PSCF := curve(makeFloatFunction(f,t),_ makeFloatFunction(g,t),_ makeFloatFunction(h,t)) -- call 'draw' makeObject(curve,tSeg,l) makeObject(psc:PSC,tBind:BIND) == makeObject(psc,tBind,nil()) draw(psc:PSC,tBind:BIND,l:L DROP) == import DROP -- obtain dependent variable and coordinate functions t := variable tBind; tSeg := segment tBind f := coordinate(psc,1); g := coordinate(psc,2); h := coordinate(psc,3) -- create title if necessary if not option?(l,"title" :: Symbol) then s:String := unparse(convert(f)@InputForm) if sayLength(s)$DisplayPackage > 50 then l := concat(title "AXIOM3D",l) else l := concat(title s,l) -- indicate draw style if necessary if not option?(l,"style" :: Symbol) then l := concat(style unparse(convert(f)@InputForm),l) -- create curve with functions as coordinates curve : PSCF := curve(makeFloatFunction(f,t),_ makeFloatFunction(g,t),_ makeFloatFunction(h,t)) -- call 'draw' draw(curve,tSeg,l) draw(psc:PSC,tBind:BIND) == draw(psc,tBind,nil()) ------------------------------------------------------------------------ -- 3D - Surfaces (given by formulas) ------------------------------------------------------------------------ --% Three Dimensional Function Plots makeObject(f:Ex,xBind:BIND,yBind:BIND,l:L DROP) == import DROP -- create title if necessary if not option?(l,"title" :: Symbol) then s:String := unparse(convert(f)@InputForm) if sayLength(s)$DisplayPackage > 50 then l := concat(title "AXIOM3D",l) else l := concat(title s,l) -- indicate draw style if necessary if not option?(l,"style" :: Symbol) then l := concat(style unparse(convert(f)@InputForm),l) -- obtain dependent variables and their ranges x := variable xBind; xSeg := segment xBind y := variable yBind; ySeg := segment yBind -- call 'draw' makeObject(makeFloatFunction(f,x,y),xSeg,ySeg,l) makeObject(f:Ex,xBind:BIND,yBind:BIND) == makeObject(f,xBind,yBind,nil()) draw(f:Ex,xBind:BIND,yBind:BIND,l:L DROP) == import DROP -- create title if necessary if not option?(l,"title" :: Symbol) then s:String := unparse(convert(f)@InputForm) if sayLength(s)$DisplayPackage > 50 then l := concat(title "AXIOM3D",l) else l := concat(title s,l) -- indicate draw style if necessary if not option?(l,"style" :: Symbol) then l := concat(style unparse(convert(f)@InputForm),l) -- obtain dependent variables and their ranges x := variable xBind; xSeg := segment xBind y := variable yBind; ySeg := segment yBind -- call 'draw' draw(makeFloatFunction(f,x,y),xSeg,ySeg,l) draw(f:Ex,xBind:BIND,yBind:BIND) == draw(f,xBind,yBind,nil()) --% parametric surface makeObject(s:PSF,uBind:BIND,vBind:BIND,l:L DROP) == import DROP f := coordinate(s,1); g := coordinate(s,2); h := coordinate(s,3) if not option?(l,"title" :: Symbol) then s:String := unparse(convert(f)@InputForm) if sayLength(s)$DisplayPackage > 50 then l := concat(title "AXIOM3D",l) else l := concat(title s,l) if not option?(l,"style" :: Symbol) then l := concat(style unparse(convert(f)@InputForm),l) u := variable uBind; uSeg := segment uBind v := variable vBind; vSeg := segment vBind surf : PSFF := surface(makeFloatFunction(f,u,v),_ makeFloatFunction(g,u,v),_ makeFloatFunction(h,u,v)) makeObject(surf,uSeg,vSeg,l) makeObject(s:PSF,uBind:BIND,vBind:BIND) == makeObject(s,uBind,vBind,nil()) draw(s:PSF,uBind:BIND,vBind:BIND,l:L DROP) == import DROP f := coordinate(s,1); g := coordinate(s,2); h := coordinate(s,3) -- create title if necessary if not option?(l,"title" :: Symbol) then s:String := unparse(convert(f)@InputForm) if sayLength(s)$DisplayPackage > 50 then l := concat(title "AXIOM3D",l) else l := concat(title s,l) -- indicate draw style if necessary if not option?(l,"style" :: Symbol) then l := concat(style unparse(convert(f)@InputForm),l) -- obtain dependent variables and their ranges u := variable uBind; uSeg := segment uBind v := variable vBind; vSeg := segment vBind -- create surface with functions as coordinates surf : PSFF := surface(makeFloatFunction(f,u,v),_ makeFloatFunction(g,u,v),_ makeFloatFunction(h,u,v)) -- call 'draw' draw(surf,uSeg,vSeg,l) draw(s:PSF,uBind:BIND,vBind:BIND) == draw(s,uBind,vBind,nil()) @ \section{package DRAWCURV TopLevelDrawFunctionsForAlgebraicCurves} <>= )abbrev package DRAWCURV TopLevelDrawFunctionsForAlgebraicCurves ++ Author: Clifton J. Williamson ++ Date Created: 26 June 1990 ++ Date Last Updated: October 1991 by Jon Steinbach ++ Basic Operations: draw ++ Related Constructors: ++ Also See: ++ AMS Classifications: ++ Keywords: ++ References: ++ Description: TopLevelDrawFunctionsForAlgebraicCurves provides top level ++ functions for drawing non-singular algebraic curves. TopLevelDrawFunctionsForAlgebraicCurves(R,Ex): Exports == Implementation where R : Join(IntegralDomain, OrderedSet, RetractableTo Integer) Ex : FunctionSpace(R) ANY1 ==> AnyFunctions1 DROP ==> DrawOption EQ ==> Equation F ==> Float FRAC ==> Fraction I ==> Integer L ==> List P ==> Polynomial RN ==> Fraction Integer SEG ==> Segment SY ==> Symbol VIEW2 ==> TwoDimensionalViewport Exports ==> with draw: (EQ Ex,SY,SY,L DROP) -> VIEW2 ++ draw(f(x,y) = g(x,y),x,y,l) draws the graph of a polynomial ++ equation. The list l of draw options must specify a region ++ in the plane in which the curve is to sketched. Implementation ==> add import ViewportPackage import PlaneAlgebraicCurvePlot import ViewDefaultsPackage import GraphicsDefaults import DrawOptionFunctions0 import SegmentFunctions2(RN,F) import SegmentFunctions2(F,RN) import AnyFunctions1(L SEG RN) import DROP drawToScaleRanges: (SEG F,SEG F) -> L SEG F drawToScaleRanges(xVals,yVals) == -- warning: assumes window is square xHi := hi xVals; xLo := lo xVals yHi := hi yVals; yLo := lo yVals xDiff := xHi - xLo; yDiff := yHi - yLo pad := abs(yDiff - xDiff)/2 yDiff > xDiff => [segment(xLo - pad,xHi + pad),yVals] [xVals,segment(yLo - pad,yHi + pad)] intConvert: R -> I intConvert r == (nn := retractIfCan(r)@Union(I,"failed")) case "failed" => error "draw: polynomial must have rational coefficients" nn :: I polyEquation: EQ Ex -> P I polyEquation eq == ff := lhs(eq) - rhs(eq) (r := retractIfCan(ff)@Union(FRAC P R,"failed")) case "failed" => error "draw: not a polynomial equation" rat := r :: FRAC P R retractIfCan(denom rat)@Union(R,"failed") case "failed" => error "draw: non-constant denominator" map(intConvert,numer rat)$PolynomialFunctions2(R,I) draw(eq,x,y,l) == -- obtain polynomial equation p := polyEquation eq -- extract ranges from option list floatRange := option(l,"rangeFloat" :: Symbol) ratRange := option(l,"rangeRat" :: Symbol) (floatRange case "failed") and (ratRange case "failed") => error "draw: you must specify ranges for an implicit plot" ranges : L SEG RN := nil() -- dummy value floatRanges : L SEG F := nil() -- dummy value xRange : SEG RN := segment(0,0) -- dummy value yRange : SEG RN := segment(0,0) -- dummy value xRangeFloat : SEG F := segment(0,0) -- dummy value yRangeFloat : SEG F := segment(0,0) -- dummy value if not ratRange case "failed" then ranges := retract(ratRange :: Any)$ANY1(L SEG RN) #ranges ~= 2 => error "draw: you must specify two ranges" xRange := first ranges; yRange := second ranges xRangeFloat := map(convert(#1)@Float,xRange)@(SEG F) yRangeFloat := map(convert(#1)@Float,yRange)@(SEG F) floatRanges := [xRangeFloat,yRangeFloat] else floatRanges := retract(floatRange :: Any)$ANY1(L SEG F) #floatRanges ~= 2 => error "draw: you must specify two ranges" xRangeFloat := first floatRanges yRangeFloat := second floatRanges xRange := map(retract(#1)@RN,xRangeFloat)@(SEG RN) yRange := map(retract(#1)@RN,yRangeFloat)@(SEG RN) ranges := [xRange,yRange] -- create curve plot acplot := makeSketch(p,x,y,xRange,yRange) -- process scaling information if toScale(l,drawToScale()) then scaledRanges := drawToScaleRanges(xRangeFloat,yRangeFloat) -- add scaled ranges to list of options l := concat(ranges scaledRanges,l) else -- add ranges to list of options l := concat(ranges floatRanges,l) -- process color information ptCol := pointColorPalette(l,pointColorDefault()) crCol := curveColorPalette(l,lineColorDefault()) -- draw drawCurves(listBranches acplot,ptCol,crCol,pointSizeDefault(),l) @ \section{package DRAWPT TopLevelDrawFunctionsForPoints} <>= )abbrev package DRAWPT TopLevelDrawFunctionsForPoints ++ Author: Mike Dewar ++ Date Created: 24 May 1995 ++ Date Last Updated: 25 November 1996 ++ Basic Operations: draw ++ Related Constructors: ++ Also See: ++ AMS Classifications: ++ Keywords: ++ References: ++ Description: TopLevelDrawFunctionsForPoints provides top level functions for ++ drawing curves and surfaces described by sets of points. TopLevelDrawFunctionsForPoints(): Exports == Implementation where DROP ==> DrawOption L ==> List SF ==> DoubleFloat Pt ==> Point SF VIEW2 ==> TwoDimensionalViewport VIEW3 ==> ThreeDimensionalViewport Exports ==> with draw: (L SF,L SF) -> VIEW2 ++ draw(lx,ly) plots the curve constructed of points (x,y) for x ++ in \spad{lx} for y in \spad{ly}. draw: (L SF,L SF,L DROP) -> VIEW2 ++ draw(lx,ly,l) plots the curve constructed of points (x,y) for x ++ in \spad{lx} for y in \spad{ly}. ++ The options contained in the list l of ++ the domain \spad{DrawOption} are applied. draw: (L Pt) -> VIEW2 ++ draw(lp) plots the curve constructed from the list of points lp. draw: (L Pt,L DROP) -> VIEW2 ++ draw(lp,l) plots the curve constructed from the list of points lp. ++ The options contained in the list l of the domain \spad{DrawOption} ++ are applied. draw: (L SF, L SF, L SF) -> VIEW3 ++ draw(lx,ly,lz) draws the surface constructed by projecting the values ++ in the \axiom{lz} list onto the rectangular grid formed by the ++ \axiom{lx X ly}. draw: (L SF, L SF, L SF, L DROP) -> VIEW3 ++ draw(lx,ly,lz,l) draws the surface constructed by projecting the values ++ in the \axiom{lz} list onto the rectangular grid formed by the ++ The options contained in the list l of the domain \spad{DrawOption} ++ are applied. Implementation ==> add draw(lp:L Pt,l:L DROP):VIEW2 == makeViewport2D(makeGraphImage([lp])$GraphImage,l)$VIEW2 draw(lp:L Pt):VIEW2 == draw(lp,[]) draw(lx: L SF, ly: L SF, l:L DROP):VIEW2 == draw([point([x,y])$Pt for x in lx for y in ly],l) draw(lx: L SF, ly: L SF):VIEW2 == draw(lx,ly,[]) draw(x:L SF,y:L SF,z:L SF):VIEW3 == draw(x,y,z,[]) draw(x:L SF,y:L SF,z:L SF,l:L DROP):VIEW3 == m : Integer := #x zero? m => error "No X values" n : Integer := #y zero? n => error "No Y values" zLen : Integer := #z zLen ~= (m*n) => zLen > (m*n) => error "Too many Z-values to fit grid" error "Not enough Z-values to fit grid" points : L L Pt := [] for j in n..1 by -1 repeat row : L Pt := [] for i in m..1 by -1 repeat zval := (j-1)*m+i row := cons(point([x.i,y.j,z.zval,z.zval]),row) points := cons(row,points) makeViewport3D(mesh points,l) @ \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}