(***************************************************************************) (* *) (* FKT - Funktionenplotter *) (* *) (* Grundversion : MPG, KB, KN, LP 23.05.84 | 7756 Byte Code *) (* Version 6.20 : MPG, Rainer Kottmann 23.09.85 | 7196 Byte Paketdaten *) (* Angepasst an MPG-Turtle-Standard : 07.03.85 | 1374 Zeilen *) (* Version 8.21 : MPG,Beat Jegerlehner 18.09.87 | *) (* Angepasst an MPG EUMELGRAPHIK/EUMEL Version 1.8.1| *) (* *) (***************************************************************************) PACKET funktionen DEFINES fkt plot, (*************************************) y grenzen, (* Interaktives Programm *) wertetafel, (* Einzelprozeduren fuer "do" *) ~, (* BOOL OP "ungefaehr gleich" *) luecke : (* Dummykonstante fuer "undefiniert" *) (*************************************) (* Autoren: Klaus Bovermann *) (* Kai Nikisch *) (* Lutz Prechelt *) (* Rainer Kottmann *) (* Beat Jegerlehner *) (*************************************) LET fkpos = 1, (* Diese LETs sind Bildschirmpositionen *) inpos = 2, wpos = 3, fehlerpos = 5, eingpos = 7, textpos = 11, wahlpos = 24, xupos = 16, yupos = 16, xopos = 32, yopos = 32, stuetzpktpos = 48, endgeraetepos = 20; LET punkte = 512, (* maximale Anzahl der Stuetzpunkte *) ug1 = 0.15051, (* Hilfswerte fuer 'gauss' *) ug2 = 0.5, ug3 = 0.84948, din a 4 hoehe = 5.0, (* Hoehe der Beschriftung *) din a 4 breite = 5.0, (* in mm *) ziffern = 12, (* Genauigkeitsangabe *) gross = 8.888888e88, epsilon = 1.0e-11; LET wahlstring = ""8""2"fdwsazntlLAqeb~?", farbstr = "Standard ot lau ruen chwarz", farbchars = ""13"rbgs", graphikvater = "GRAPHIK", helpfile = "FKT.help"; ROW punkte REAL VAR graph; TEXT VAR term :: "", rohterm :: "", picfilename :: "", prefix :: "PICFILE.", postfix :: "", fehlernachricht :: "", proc, inline; REAL VAR x min :: -gross, x max :: gross, y min :: maxreal, y max :: -maxreal, xstep; INT VAR nachkomma :: 2, stuetzen :: punkte, endgeraet :: 1, endgeraete :: highest entry(plotters); BOOL VAR intervall definiert :: FALSE, wertebereich bestimmt :: FALSE, wertetafel vorhanden :: FALSE, fehlerzustand :: FALSE; REAL CONST luecke :: gross; PICTURE VAR dummy picture :: nilpicture; move (dummy picture,0.0,0.0); (***************************************************************************) (* Alte Prozeduren (Graphik-unabhaengig) *) (***************************************************************************) PROC get (TEXT VAR text): (* moeglichkeit, ueberall abzubrechen! *) text := ""; TEXT VAR exit char; editget (text,""27"","",exit char); IF exit char = ""27"" THEN errorstop("Abgebrochen") FI END PROC get; PROC get (INT VAR nr): TEXT VAR t; get(t); line; nr := int(t) END PROC get; PROC get (REAL VAR nr): TEXT VAR t; get(t); line; nr := real(t) END PROC get; PROC editget (TEXT VAR t): TEXT VAR t2 :: t,exit char; editget(t2,""27"","",exit char); IF exit char = ""27"" THEN errorstop("Abgebrochen") FI; t := t2 END PROC editget; PROC inchar (TEXT VAR a,TEXT CONST b): REP inchar (a) UNTIL pos(b,a) <> 0 OR a = ""27"" PER; IF a = ""27"" THEN errorstop("Abgebrochen") FI END PROC inchar; BOOL OP ~ (REAL CONST left , right) : abs (left - right) <= xstep END OP ~; (******************* MAIN PROGRAMM *****************************) PROC fkt plot: auswahlbild; select plotter(name(plotters,endgeraet)); REP bild; auswahl (inline) UNTIL inline = "q" PER END PROC fkt plot; (****************** LAY OUT *****************************) PROC auswahlbild: page; cursor (1,textpos); put ("(f) Funktionsterm eingeben "); putline ("(?) Hilfestellung "); put ("(d) Definitionsbereich waehlen "); putline ("(q) in die Kommandoebene zurueck "); put ("(w) Wertebereich ermitteln lassen "); putline ("(s) Anzahl der Stuetzpunkte waehlen "); put ("(z) Zeichnung anfertigen "); putline ("(n) Nachkommastellenzahl waehlen "); put ("(a) Ausgabe der Zeichnung auf Endgeraet"); putline ("(e) Arbeit beenden "); put ("(t) Wertetafel erstellen lassen "); putline ("(L) Zeichnungen loeschen "); put ("(l) Zeichnungen auflisten "); putline ("(A) Zeichnungen archivieren "); put (" "); putline ("(b) Zeichnung beschriften "); cursor (1,wahlpos); put ("Ihre Wahl:") END PROC auswahlbild; PROC bild: cursor (1,fkpos); put ("f(x) = " + rohterm); out (""5""); cursor (1,inpos); put ("Def.Bereich: [ / ]"); cursor (xupos,inpos); put (text (x min,ziffern,nachkomma)); cursor (xopos,inpos); put (text (x max,ziffern,nachkomma)); cursor (1,wpos); put ("Wertebereich: [ / ]"); cursor (yupos,wpos); put (text (y min,ziffern,nachkomma)); cursor (yopos,wpos); put (text (y max,ziffern,nachkomma)); cursor (1,endgeraetepos); put endgeraetestring; cursor (stuetzpktpos,inpos); put ("Anzahl der Stuetzpunkte: " + text (stuetzen,3)); drei zeilen ab eingpos loeschen. END PROC bild; (****************** MONITOR *****************************) PROC auswahl 1 (TEXT VAR wahl): enable stop; SELECT code (wahl) OF CASE 8 : endgeraet := max(endgeraet-1,1); select plotter(name(plotters,endgeraet)) CASE 2 : endgeraet := min(endgeraet+1,endgeraete); select plotter(name(plotters,endgeraet)) CASE 102 : fkt lesen (* f *) CASE 100 : defbereich waehlen (* d *) CASE 119 : wertebereich erstellen (* w *) CASE 116 : wertetafel erstellen (* t *) CASE 113 : LEAVE auswahl 1 (* q *) CASE 122 : graph erstellen (* z *) CASE 97 : graph zeigen (* a *) CASE 110 : genauigkeitsangabe (* n *) CASE 65 : dm; (* A *) auswahlbild CASE 108 : dateien listen (* l *) CASE 76 : dateien aus task raeumen (* L *) CASE 101 : unterbrechung (* e *) CASE 126 : spezialeingabe (* TIL *) CASE 63 : hilfe (* ? *) CASE 115 : stuetzpunkte setzen (* s *) CASE 98 : zeichnung beschriften (* b *) END SELECT; END PROC auswahl 1; PROC auswahl (TEXT VAR wahl): (* Faengerebene *) cursor (12,24); out (""5""); inchar (wahl,wahlstring); fehlerloeschen; disable stop; auswahl 1 (wahl); IF is error THEN fehlersetzen (error message); clear error FI; enable stop; IF fehlerzustand THEN fehleraus (fehlernachricht) FI END PROC auswahl; PROC put endgeraetestring: TEXT VAR s :: "Endgeraet: "; INT VAR i; THESAURUS CONST t :: plotters; FOR i FROM 1 UPTO endgeraete REP IF length(s)+length(name(t,i))+4 > 79 THEN putline(s+""5""); s := " " FI; IF i = endgeraet THEN s CAT ""15"" + name(t,i) + " "14" " ELSE s CAT " "+name(t,i) + " " FI PER; putline(s+""5"") END PROC put endgeraetestring; (**************************** f *******************************************) PROC fkt lesen: reset wertebereich; cursor (1,eingpos); put ("f(x) ="); out (""5""); cursor (1,eingpos + 1); out(""5""); cursor (8,eingpos); editget (rohterm); change int to real (rohterm,term); change all (term,"X","x"); change all (term,"=","~"); (* Ueberdeckung von = *) change all (term,"<~","<="); (* ruecksetzen von <= *) change all (term,">~",">="); (* " >= *) term testen; wertetafel vorhanden := FALSE. term testen: disable stop; proc := "REAL PROC f (REAL CONST x):"; proc CAT term; proc CAT " END PROC f"; do ("do ("""+proc+""")"); (* komischer do-Fehler *) IF is error THEN fehlersetzen ("Term fehlerhaft"); clear error; LEAVE fkt lesen FI END PROC fkt lesen; (**************************** d *******************************************) PROC defbereich waehlen: cursor (1,eingpos); put ("Untergrenze :"); out (""5""); get (x min); obergrenze lesen; intervall definiert := TRUE; reset wertebereich. obergrenze lesen: REP put ("Obergrenze :"); out (""5""); get (x max); IF x max <= x min THEN out (""7""13""3""5"") FI UNTIL x max > x min PER END PROC defbereich waehlen; (**************************** w *******************************************) PROC wertebereich erstellen: IF rohterm = "" THEN fehlersetzen ("Erst Fkts.Term eingeben! (f)"); LEAVE wertebereich erstellen ELIF NOT intervall definiert THEN fehlersetzen ("Erst Def.Bereich waehlen (d)"); LEAVE wertebereich erstellen ELIF wertebereich bestimmt THEN fehlersetzen ("Wertebereich ist bereits bestimmt"); LEAVE wertebereich erstellen FI; proc := "REAL PROC f (REAL CONST x):"+ term; proc CAT " END PROC f; ygrenzen (PROC f)"; do (proc) END PROC wertebereich erstellen; PROC ygrenzen (REAL PROC (REAL CONST) f): REAL VAR x, f von x; INT VAR i :: 1; disable stop; xstep := (x max - x min) / real (stuetzen - 1); x := x min; y min := maxreal; y max := -maxreal; cursor (1,eingpos); putline ("Wertebereich wird ermittelt"); out (""5""); out ("bei Stuetzpunkt Nr.: "); wertegrenzen berechnen; IF is error THEN fehler setzen (error message); reset wertebereich; LEAVE ygrenzen ELIF fehlerzustand THEN reset wertebereich; LEAVE ygrenzen ELSE wertebereich bestimmt := TRUE FI; IF y min = y max THEN y min DECR 1.0; y max INCR 1.0 FI. wertegrenzen berechnen: FOR i FROM 1 UPTO stuetzen REP x := real (i-1) * xstep + x min; cout (i); f von x := f (x); graph [i] := f von x; IF f von x <> luecke THEN y min := min (y min, f von x); y max := max (y max, f von x) FI UNTIL is error OR interrupt PER . interrupt: IF incharety = ""27"" THEN fehlersetzen ("Abgebrochen"); TRUE ELSE FALSE FI END PROC ygrenzen; (**************************** t *******************************************) PROC wertetafel erstellen: IF rohterm = "" THEN fehleraus ("Erst Fkts.Term eingeben (f)"); LEAVE wertetafel erstellen ELIF NOT intervall definiert THEN fehleraus ("Erst Def.Bereich waehlen (d)"); LEAVE wertetafel erstellen FI; proc := "REAL PROC f (REAL CONST x):"+ term; proc CAT " END PROC f; wertetafel (PROC f)"; do (proc) END PROC wertetafel erstellen; PROC wertetafel (REAL PROC (REAL CONST ) f): FILE VAR g :: sequential file (output,rohterm); REAL VAR x, f von x; INT VAR i :: 0; REP schrittweite einlesen UNTIL (xstep > 0.0) CAND ((x max-x min) / xstep < real (punkte)) PER; x := x min; evtl ueberschrift; disable stop; REP datei erstellen UNTIL x > x max OR is error PER; fehleraus in tafel; enable stop; modify (g); edit (g); line; IF yes("Tafel drucken") THEN print (rohterm) FI; line (2); IF yes("Tafel loeschen") THEN forget(rohterm,quiet); wertetafel vorhanden := FALSE ELSE wertetafel vorhanden := TRUE FI; auswahlbild. evtl ueberschrift: IF NOT wertetafel vorhanden THEN putline (g, " W E R T E T A F E L"); line (g); putline (g, " x ! " + rohterm); putline (g, "----------------!----------------") FI. fehleraus in tafel: IF is error THEN fehlernachricht := errormessage; clearerror; line (g,2); putline (g,fehlernachricht); fehlernachricht := "" FI. datei erstellen: i INCR 1; cout (i); put (g, text (x,ziffern,nachkomma)); put (g, " !"); f von x := f (x); IF f von x <> luecke THEN put (g, text (f von x,ziffern,nachkomma)) ELSE put (g, "Definitionsluecke") FI; line (g); x INCR xstep. schrittweite einlesen: cursor (1,eingpos); put ("Schrittweite:"); out (""5""); cursor (1,eingpos + 1); out (""5""); cursor (15,eingpos); get (xstep); put ("Zwischenpunkt :"); IF (xstep <= 0.0) COR ((x max-x min) / xstep > real (punkte)) THEN fehleraus ("Schrittweite zu klein"); LEAVE wertetafel FI END PROC wertetafel; (*********************************** n *************************************) PROC genauigkeitsangabe: cursor (1,eingpos); put ("Anzahl der Nachkommastellen : "); get (nachkomma); disable stop; nachkomma := min (nachkomma, ziffern - 3); nachkomma := max (nachkomma, 0); IF is error THEN fehlersetzen ("Falscher Wert"); clear error; nachkomma := 2 FI END PROC genauigkeitsangabe; (********************************l ****************************************) PROC dateien listen: th(all LIKE (prefix+"*")); auswahlbild END PROC dateien listen; (********************************L ****************************************) PROC dateien aus task raeumen: forget(some(all LIKE (prefix+"*"))); auswahlbild END PROC dateien aus task raeumen; (**************************** s *******************************************) PROC stuetzpunkte setzen: cursor (1,eingpos); put ("Anzahl der Stuetzpunkte :"); get (stuetzen); disable stop; IF stuetzen <= 1 OR stuetzen > punkte THEN fehler setzen ("Achtung Stuetzpunkte fehlerhaft") FI; stuetzen := max (stuetzen, 2) ; stuetzen := min (stuetzen, punkte); IF is error THEN fehlersetzen ("Falscher Wert"); clear error; stuetzen := punkte FI; reset wertebereich END PROC stuetzpunkte setzen; (**************************** e *******************************************) PROC unterbrechung: break; auswahlbild END PROC unterbrechung; (****************************** ? ******************************************) PROC hilfe: IF NOT exists(helpfile) THEN fetch(helpfile,task (graphikvater)) FI; FILE VAR f :: sequential file(input,helpfile); headline(f,"Verlassen mit "); open editor(f,FALSE); edit (groesster editor,"q",PROC (TEXT CONST) dummy ed); auswahlbild END PROC hilfe; PROC dummy ed (TEXT CONST t): IF t = "q" THEN quit ELSE out(""7"") FI END PROC dummy ed; (**************************** TILDE ****************************************) PROC spezialeingabe: TEXT CONST termeingabename :: "Bitte Funktionsrumpf eingeben"; TEXT VAR t; FILE VAR f :: sequential file (modify, termeingabename); edit (f); lese den term aus; teste den term; rohterm := "spezial"; reset wertebereich; auswahlbild. lese den term aus: term := ""; input (f); WHILE NOT eof (f) REP getline (f,t); term CAT t; term CAT " " PER. teste den term: disable stop; proc := "REAL PROC f (REAL CONST x):"; proc CAT term; proc CAT " END PROC f"; do (proc); IF is error THEN fehlersetzen ("Funktionsrumpf fehlerhaft"); clear error; term := ""; rohterm := ""; reset wertebereich; auswahlbild; LEAVE spezialeingabe FI END PROC spezialeingabe; (***************************************************************************) (********* Ab hier Hilfsprozeduren *********) (***************************************************************************) PROC fehleraus (TEXT CONST t): cursor (1,fehlerpos); out (""7"F E H L E R : ", t); fehlerzustand := FALSE END PROC fehleraus; PROC fehlerloeschen: cursor (1,fehlerpos); out (""5""); fehlernachricht := ""; fehlerzustand := FALSE END PROC fehlerloeschen; PROC fehler setzen (TEXT CONST message): fehlernachricht := message; fehlerzustand := TRUE; clear error END PROC fehler setzen; REAL PROC gauss (REAL CONST z): IF is integer (z) THEN round (z,0) ELIF sign (z) = -1 THEN floor (z) - 1.0 ELSE floor (z) FI END PROC gauss; BOOL PROC is integer (REAL CONST x): abs (x - floor (x)) < epsilon END PROC is integer; PROC berechnung (REAL CONST min, max, REAL VAR sweite, INT VAR styp): sweite := faktor * round (10.0 ** expo,11). faktor: IF nachkomma < ug1 THEN styp := 1; 1.0 ELIF nachkomma < ug2 THEN styp := 2; 2.0 ELIF nachkomma < ug3 THEN styp := 5; 5.0 ELSE styp := 1; 10.0 FI. nachkomma: IF frac (logwert) < -epsilon THEN 1.0 + frac (logwert) ELIF frac (logwert) > epsilon THEN frac (logwert) ELSE 0.0 FI. differenz: max - min. expo: gauss (logwert) - 1.0. logwert: round (log10 (differenz),8) END PROC berechnung; REAL PROC runde ab (REAL CONST was, auf): auf * gauss (was / auf) END PROC runde ab; REAL PROC runde auf (REAL CONST was, auf): REAL VAR hilf :: runde ab (was,auf); IF abs (hilf - was) < epsilon THEN was ELSE hilf + auf FI END PROC runde auf; PROC loesche zeile (INT CONST zeile): cursor (1,zeile); out (""5"") END PROC loesche zeile; PROC drei zeilen ab eingpos loeschen: loesche zeile (eingpos); loesche zeile (eingpos + 1); loesche zeile (eingpos + 2); END PROC drei zeilen ab eingpos loeschen; PROC change int to real (TEXT CONST term alt,TEXT VAR term neu): TEXT VAR symbol :: "", presymbol :: ""; INT VAR type :: 0, pretype :: 0, position; LET number = 3, tag = 1, end of scan = 7, pot = "**"; term neu := ""; scan (term alt); WHILE type <> end of scan REP presymbol := symbol; pretype := type; next symbol (symbol,type); IF type <> number OR presymbol = pot THEN term neu CAT evtl mal und symbol ELSE term neu CAT changed symbol FI PER. evtl mal und symbol: IF pretype = number AND type = tag THEN "*" + symbol ELSE symbol FI. changed symbol: position := pos (symbol,"e"); IF position <> 0 THEN text (symbol,position - 1) + ".0" + subtext (symbol,position,length (symbol)) ELIF pos (symbol,".") = 0 THEN symbol CAT ".0"; symbol ELSE symbol FI END PROC change int to real; PROC reset wertebereich: y min := -maxreal; y max := maxreal; wertebereich bestimmt := FALSE END PROC reset wertebereich; TEXT PROC textreal (REAL CONST z): TEXT VAR t :: text (z); IF (t SUB length (t)) = "." THEN subtext (t,1,length (t) - 1) ELIF (t SUB 1) = "." THEN "0" + t ELIF (t SUB 2) = "." AND sign (z) = -1 THEN "-0" + subtext (t,2) ELIF t = "0.0" THEN "0" ELSE t FI END PROC textreal; INT PROC length (REAL CONST z): length (text (z)) END PROC length; PROC put format(INT CONST wo, REAL CONST xxmi,xxma,yymi,yyma): cursor (1,wo); put ("Aktuelles Format: xmin xmax" + " ymin ymax"); cursor (19,wo + 1); put (text (xx mi,ziffern,nachkomma)); cursor (34,wo + 1); put (text (xx ma,ziffern,nachkomma)); cursor (49,wo + 1); put (text (yy mi,ziffern,nachkomma)); cursor (64,wo + 1); put (text (yy ma,ziffern,nachkomma)) END PROC put format; PROC out (TEXT CONST a, b) : out (a); out (b) END PROC out; (***************************************************************************) (* Neue Prozeduren *) (***************************************************************************) PROC graph erstellen: PICFILE VAR funktionen; PICTURE VAR funktionsgraph :: nilpicture, formatpic :: nilpicture; REAL VAR xx min :: x min, xx max :: x max, yy min :: y min, yy max :: y max; IF rohterm = "" THEN fehlersetzen ("Erst Funktionsterm waehlen (f)"); LEAVE graph erstellen ELIF NOT wertebereich bestimmt THEN fehlersetzen ("Erst Wertebereich bestimmen lassen (w)"); LEAVE graph erstellen FI; hole filenamen; funktionen := picture file (picfilename); initialisiere stifte; waehle format; zeichne graphen; pictures ins picfile. hole filenamen: TEXT VAR t :: ""; REP namen lesen UNTIL t = "l" OR t = "e" PER. namen lesen: cursor (1,eingpos); out ("Welchen Namen soll die Zeichnung haben: "+ prefix); postfix:= rohterm; editget (postfix); line; IF (postfix SUB 1) = "?" THEN picfilename := one(all LIKE (prefix+"*")); auswahlbild; bild; cursor(1,eingpos) ELSE picfilename := prefix + postfix; picfilename := compress (picfilename) FI; IF NOT exists (picfilename) THEN LEAVE hole filenamen FI; putline ("Zeichnung gibt es schon!"); put ("loeschen (l), Namen neuwaehlen (n), " + "alte Zeichnung ergaenzen (e):"); inchar (t,"lne"); IF t = "l" THEN forget (picfilename,quiet) ELIF t = "n" THEN drei zeilen ab eingpos loeschen FI. initialisiere stifte: select pen (funktionen, 1, 1, 0, 1, TRUE); (* Standardfarbe *) select pen (funktionen, 2, 2, 0, 1, TRUE); (* Rot *) select pen (funktionen, 3, 3, 0, 1, TRUE); (* Blau *) select pen (funktionen, 4, 4, 0, 1, TRUE); (* Gruen *) select pen (funktionen, 5, 5, 0, 1, TRUE). (* Schwarz *) waehle format: IF altes picfile THEN ergaenze wertebereich FI; drei zeilen ab eingpos loeschen; REAL VAR step; INT VAR i dummy; berechnung (yy min, yy max, step, idummy); yy min := runde ab (yy min, step); yy max := runde auf (yy max, step); put format(eingpos, xx min, xx max, yy min, yy max); pause ; drei zeilen ab eingpos loeschen; cursor(1,eingpos); IF yes("Format aendern") THEN interactive change of format (xx min,xx max,yy min,yy max) FI; drei zeilen ab eingpos loeschen. ergaenze wertebereich: to pic (funktionen,3); (* Formatpicture *) read picture (funktionen,formatpic); move (formatpic, xx min, yy min); move (formatpic, xx max, yy max); extrema (formatpic, xx min, xx max, yy min, yy max). altes picfile: t = "e". zeichne graphen: REAL VAR x :: x min, x schrittweite :: (x max - x min) / real (stuetzen - 1); INT VAR i; cursor (1,eingpos); put ("Graph bei Stuetzpunkt Nr. "); FOR i FROM 1 UPTO stuetzen REP cout (i); IF graph[i] <> luecke THEN IF zuletzt luecke THEN move (funktionsgraph, x, graph[i]) ELSE draw (funktionsgraph, x, graph[i]) FI FI; x INCR x schrittweite UNTIL abbruch PER; drei zeilen ab eingpos loeschen. abbruch: IF incharety = ""27"" THEN errorstop("Abgebrochen"); TRUE ELSE FALSE FI. zuletzt luecke: i = 1 COR graph[i-1] = luecke. pictures ins picfile: setze graphenfarbe; to first pic(funktionen); IF altes picfile THEN down (funktionen); (* Skip *) down (funktionen) ELSE put picture (funktionen, dummy picture); (* Zusaetzliche Beschr.*) put picture (funktionen, dummy picture) FI; formatpic := nilpicture; move (formatpic, xx min, yy min); move (formatpic, xx max, yy max); IF altes picfile THEN write picture (funktionen, formatpic) ELSE put picture (funktionen, formatpic) FI; put picture (funktionen, funktionsgraph). setze graphenfarbe: cursor (1,eingpos); put("Farbe des Graphen :"); pen (funktionsgraph, farbe). farbe : TEXT VAR ff; put(farbstr); inchar (ff,farbchars); out(ff); pos (farbchars,ff). END PROC graph erstellen; PROC interactive change of format (REAL VAR x mi,x ma,y mi,y ma): TEXT VAR tt; REP cursor (1,eingpos + 2); put ("Geben Sie die neuen Koordinaten ein"); out (""5""); pause (20); loesche zeile (eingpos + 2); cursor (1,eingpos + 2); put ("xmin:"); tt := text (xmi); editget (tt); xmi := real (tt); cursor (1,eingpos + 2); put ("xmax:"); out (""5""); tt := text (xma); editget (tt); xma := real (tt); cursor (1,eingpos + 2); put ("ymin:"); out (""5""); tt := text (ymi); editget (tt); ymi := real (tt); cursor (1,eingpos + 2); put ("ymax:"); out (""5""); tt := text (yma); editget (tt); yma := real (tt); UNTIL format ok PER. format ok: IF xma <= xmi OR yma <= ymi THEN fehlersetzen ("Format falsch"); FALSE ELSE TRUE FI END PROC interactive change of format; PROC geraet waehlen: END PROC geraet waehlen; PROC zeichnung beschriften: namen holen; PICFILE VAR funktionen :: picture file(picfilename); PICTURE VAR beschr; to pic(funktionen,2); read picture(funktionen,beschr); cursor(1,eingpos); put("Beschriftung (e) rgaenzen , (l) oeschen oder (a) bbruch"); TEXT VAR t; inchar(t,"ela"); IF t = "l" THEN to pic(funktionen,2); beschr := nilpicture; write picture(funktionen,beschr) ELIF t = "e" THEN beschrifte FI; cursor(1,eingpos); drei zeilen ab eingpos loeschen. beschrifte: farbe holen; REAL VAR rx,ry,hx,bx; to pic(funktionen,3); PICTURE VAR format; read picture(funktionen,format); extrema(format,rx,ry,hx,bx); drei zeilen ab eingpos loeschen; put format (eingpos,rx,ry,hx,bx); pause; REP drei zeilen ab eingpos loeschen; cursor(1,eingpos); put("Text :"); TEXT VAR btext; getline(btext); put("Koordinaten in (c)m oder in (r)eal "); inchar(t,"cra"); drei zeilen ab eingpos loeschen; cursor(1,eingpos); put("X-Koordinate:"); get(rx); put("Y-Koordinate:"); get(ry); IF t = "c" THEN move cm(beschr,rx,ry) ELSE move (beschr,rx,ry) FI; drei zeilen ab eingpos loeschen; cursor(1,eingpos); put("Hoehe der Zeichen in mm :"); get(hx); put("Breite der Zeichen in mm:"); get(bx); draw(beschr,btext,0.0,hx,bx); drei zeilen ab eingpos loeschen; cursor(1,eingpos) UNTIL no("Weitere Beschriftungen") PER; to pic(funktionen,2); write picture(funktionen,beschr). farbe holen: drei zeilen ab eingpos loeschen; cursor(1,eingpos); put("Farbe der Beschriftungen: "); TEXT VAR ff; put(farbstr); inchar (ff,farbchars); out(ff); pen(beschr,pos (farbchars,ff)). namen holen: cursor(1,eingpos); put("Wie heisst die Zeichnung:"); out(prefix); editget(postfix); picfilename := prefix + postfix; IF (postfix SUB 1) = "?" THEN picfilename := one(all LIKE (prefix + "*")); auswahlbild; bild FI; IF NOT exists(picfilename) THEN fehlersetzen("Zeichnung gibt es nicht"); LEAVE zeichnung beschriften FI END PROC zeichnung beschriften; PROC graph zeigen: REAL VAR xx max,xx min,yy max,yy min; cursor (1,eingpos); put ("Wie heisst die Zeichnung :"); out(prefix); editget(postfix); picfilename := prefix+postfix; IF (postfix SUB 1) = "?" THEN picfilename := one(all LIKE (prefix+"*")); postfix := subtext(picfilename,length(prefix)+1); auswahlbild; bild ELIF NOT exists (picfilename) THEN fehlersetzen ("Zeichnung gibt es nicht"); LEAVE graph zeigen FI; drei zeilen ab eingpos loeschen; PICFILE VAR funktionen :: picture file (picfilename); PICTURE VAR rahmen :: nilpicture; hole ausschnitt; hole headline; erzeuge rahmen; gib bild aus. gib bild aus: REAL VAR x cm,y cm; INT VAR i,j; drawing area (x cm,y cm,i,j); viewport (funktionen, 0.0, x cm/y cm, 0.0, 1.0); erweitere bereich; (* Rundungsfehler beim clippen vermeiden !!! *) window (funktionen, xx min, xx max, yy min, yy max); plot (picfilename); auswahlbild. erweitere bereich: xx max := xx max + (xx max - xx min) / real(i). erzeuge rahmen: to pic (funktionen,1); waehle achsenart; IF achsenart = "r" THEN rahmen := frame (xx min,xx max,yy min,yy max) ELSE rahmen := axis (xx min,xx max,yy min,yy max) FI; rahmen CAT beschriftung (xx min,xx max,yy min,yy max,headline, achsenart = "r"); cursor (1,eingpos); put ("Farbe des"); IF achsenart = "k" THEN put("Koordinatensystems :") ELSE put("Rahmens :") FI; pen (rahmen,farbe); drei zeilen ab eingpos loeschen; write picture (funktionen,rahmen). farbe : TEXT VAR ff; put(farbstr); inchar (ff,farbchars); out(ff); pos (farbchars,ff). waehle achsenart: TEXT VAR achsenart :: "r"; IF koord moeglich THEN frage nach achsenart FI. frage nach achsenart: cursor (1,eingpos); put("oordinatensystem oder ahmen zeichnen ?"); inchar (achsenart,"kr"); putline(achsenart); drei zeilen ab eingpos loeschen. koord moeglich: NOT (xmin >= 0.0 OR xx max <= 0.0 OR yy min >= 0.0 OR yy max <= 0.0). hole ausschnitt: PICTURE VAR format; to pic (funktionen,3); read picture (funktionen,format); extrema (format, xx min, xx max, yy min, yy max); cursor (1,eingpos); put format (eingpos, xx min, xx max, yy min, yy max); pause; drei zeilen ab eingpos loeschen; cursor (1,eingpos); IF yes ("Wollen Sie den Ausschnitt veraendern") THEN interactive change of format (xx min,xx max,yy min,yy max) FI; drei zeilen ab eingpos loeschen. hole headline: cursor (1,eingpos); TEXT VAR headline :: rohterm; put ("Ueberschrift :"); editget (headline); drei zeilen ab eingpos loeschen END PROC graph zeigen; PICTURE PROC frame (REAL CONST xx min,xx max,yy min,yy max): PICTURE VAR rahmen :: nilpicture; zeichne achsen; zeichne restrahmen; rahmen. zeichne restrahmen: move (rahmen,xx min,yy max); draw (rahmen,xx max,yy max); draw (rahmen,xx max,yy min). zeichne achsen: rahmen := axis (xx min,xx max,yy min,(yy max - yy min) / 90.0,0,0); rahmen CAT axis (yy min,yy max,xx min,(xx max - xx min) / 90.0,1,0) END PROC frame; PICTURE PROC axis (REAL VAR xx min,xx max,yy min,yy max): PICTURE VAR rahmen :: nilpicture; rahmen := axis (xx min,xx max,0.0,(yy max - yy min) / 180.0,0,1); rahmen CAT axis (yy min,yy max,0.0,(xx max - xx min) / 180.0,1,1); rahmen END PROC axis; PICTURE PROC axis (REAL CONST min, max, pos,strich, INT CONST dir,mode): PICTURE VAR achse :: nilpicture; REAL VAR step, feinstep, wert; INT VAR type; berechnung (min,max,step,type); feinstep := step / real(zwischenstriche); IF min MOD feinstep <> 0.0 THEN wert := runde auf (min,feinstep); ELSE wert := min FI; INT VAR zaehler :: int( wert MOD step / feinstep + 0.5); WHILE wert <= max REP IF wert = 0.0 THEN ziehe nullstrich ELIF zaehler MOD zwischenstriche = 0 THEN ziehe normstrich ELSE ziehe feinstrich FI; wert INCR feinstep; zaehler INCR 1 PER; zeichne achse; achse. zwischenstriche: IF type = 2 THEN 4 ELSE 5 FI. ziehe nullstrich: REAL VAR p0 :: pos + real (mode) * strich * 3.0, p1 :: pos - strich * 3.0; ziehe linie. ziehe normstrich: p0 := pos + real (mode) * strich * 2.0; p1 := pos - strich * 2.0; ziehe linie. ziehe feinstrich: p0 := pos + real (mode) * strich; p1 := pos - strich; ziehe linie. zeichne achse: IF dir = 0 THEN move (achse,min,pos); draw (achse,max,pos) ELSE move (achse,pos,min); draw (achse,pos,max) FI. ziehe linie: IF dir = 0 THEN move (achse,wert,p0); draw (achse,wert,p1) ELSE move (achse,p0,wert); draw (achse,p1,wert) FI END PROC axis; PICTURE PROC beschriftung (REAL VAR xx min,xx max,yy min,yy max, TEXT CONST ueberschrift, BOOL CONST mode): PICTURE VAR rahmen :: nilpicture; beschrifte; rahmen. beschrifte : REAL VAR x cm,y cm; INT VAR dummy; drawing area (x cm,y cm,dummy,dummy); erweitere; zeichne x achse; zeichne y achse; zeichne ueberschrift; xx max := xn max; xx min := xn min; yy max := yn max; yy min := yn min. erweitere: REAL VAR hoehe :: din a4 hoehe / 23.5 * y cm, { der Zeichen } breite :: din a4 breite / 30.5 * x cm; INT CONST anzahl y stellen :: max (stellen (yy min),stellen (yy max)), anzahl x stellen :: max (stellen (xx min),stellen (xx max)); REAL VAR xn min :: xx min, xn max :: xx max, yn min :: yy min; IF mode { rahmen wg clipping } THEN xn min DECR (xx max - xx min) / 30.0; yn min DECR (yy max - yy min) / 30.0 FI; REAL VAR xx dif :: xx max - xn min, yy dif :: yy max - yn min, yn dif :: y cm / (y cm - 2.0 * hoehe / 10.0 - 0.4) * yy dif, xn dif :: x cm / (x cm - x erweiterung) * xx dif, y 1 mm :: yn dif / y cm / 10.0, r hoch :: hoehe / y cm / 10.0 * yn dif, r breit:: breite / x cm / 10.0 * xn dif, yn max :: yy max + r hoch + 3.0 * y 1 mm; yn min := yn min - r hoch - 2.0 * y 1 mm; IF mode THEN xn min := xn min - real(anzahl y stellen) * r breit FI. x erweiterung: IF mode THEN real(anzahl y stellen) * breite / 10.0 ELSE 0.0 FI. zeichne x achse: TEXT VAR zahl :: text (xx min, anzahl x stellen, nachkomma); ersetze zahl; move (rahmen, max(xn min, xx min - real(length(zahl)) * r breit / 2.0), yn min); draw (rahmen, zahl, 0.0, breite, hoehe); zahl := text (xx max, anzahl x stellen, nachkomma); ersetze zahl; move (rahmen, xx max - real(length(zahl)) * r breit, yn min); draw (rahmen, zahl, 0.0, breite, hoehe). zeichne y achse: zahl := text (yy min, anzahl y stellen, nachkomma); ersetze zahl; move (rahmen, max (xn min, xx min - real(length(zahl)) * r breit - (xx max - xx min) / 30.0),yy min - r hoch / 2.0); draw (rahmen, zahl, 0.0, breite, hoehe); zahl := text (yy max,anzahl y stellen,nachkomma); ersetze zahl; move (rahmen, max (xn min, xx min - real(length(zahl)) * r breit - (xx max - xx min) / 30.0),yy max - r hoch / 2.0); draw (rahmen, zahl, 0.0, breite, hoehe). zeichne ueberschrift: move (rahmen, (xx max + xx min - real(length(ueberschrift)) * r breit) / 2.0, yy max + y 1 mm); draw (rahmen, ueberschrift, 0.0, breite, hoehe). ersetze zahl: change all (zahl, ".", ",") END PROC beschriftung; INT PROC stellen (REAL CONST r): IF r = 0.0 THEN nachkomma + 2 ELSE nachkomma + 3 + max (0, int ( round(log10 (abs(r)),nachkomma))) FI END PROC stellen END PACKET funktionen; PACKET fkt manager DEFINES fkt manager: LET continue code = 100, ack = 0, nack = 1; DATASPACE VAR dummy space; INT VAR order; TASK VAR order task; PROC fkt manager: set autonom; disable stop; break (quiet); REP forget (dummy space); wait (dummy space, order, order task); IF order >= continue code AND order task = supervisor THEN call (supervisor, order, dummy space, order); IF order = ack THEN fkt online FI; set autonom; command dialogue (FALSE); forget (ALL myself) ELSE send (order task, nack, dummy space) FI PER. fkt online: command dialogue (TRUE); fktplot; IF online THEN eumel must advertise; break (quiet) FI END PROC fktmanager END PACKET fktmanager