home *** CD-ROM | disk | FTP | other *** search
- /********************************************************************/
- /**** ****/
- /**** ****/
- /**** Program : C-Plot.c ****/
- /**** ****/
- /**** Version : 03.71 ****/
- /**** ****/
- /**** Erstversion : 14.08.1988 ****/
- /**** ****/
- /**** Letzte Änderung : 09.08.1990 ****/
- /**** ****/
- /**** Compiliert mit : siehe MAKEFILE ****/
- /**** ****/
- /**** Gelinkt mit : siehe MAKEFILE ****/
- /**** ****/
- /********************************************************************/
- /**** ****/
- /**** ****/
- /**** Copyright by Rüdiger Dreier ****/
- /**** ****/
- /**** ****/
- /********************************************************************/
-
- /* Einbinden der Include-Files */
-
- #ifdef DEBUG
- #include <exec/types.h>
- #include <proto/tool.h>
- #include "Plotter.h"
- #endif
- #include <string.h>
- #include <devices/printer.h>
- #include <intuition/intuitionbase.h>
- #include <graphics/regions.h>
- #include <proto/mathieeedoubbas.h>
- #include <proto/mathieeedoubtrans.h>
- #include <proto/layers.h>
- #include <math.h>
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <exec/memory.h>
- #include <exec/tasks.h>
- #include <libraries/dosextens.h>
- #include <dos.h>
-
-
- /* Variablendeklaration */
- BOOL KoordinatenKreuz_gezeichnet; /* Gibt an, ob Koordinatenkreuz neu gezeichnet werden muß */
- int GE=1; /* Für die Genauigkeit der Zeichnung */
- int Groesse;
-
- APTR Konstantenstart; /* Zeiger auf die Konstanten */
- struct Block *StartBlock; /* Zeiger auf ersten Block */
- struct LayersBase *LayersBase;
- struct ViewPort *viep; /* Zeiger auf ViewPort */
- struct IntuitionBase *IntuitionBase; /* Zeiger auf IntuitionBase */
- struct ToolBase *ToolBase;
- struct Library *MathIeeeDoubTransBase;
- struct Window *Window; /* Zeiger auf Fenster */
- struct RastPort *RastPort; /* Zeiger auf RastPort */
- struct Screen *Screen; /* Zeiger auf Screen */
- struct GfxBase *GfxBase; /* Zeiger auf Grafik-Library */
- struct View *View;
- struct BitMap bitmap;
- struct Layer *layer;
- struct Layer_Info *layerinfo;
- struct info msgInfo;
-
- /* Strings */
- UBYTE undo1[20]; /* Für Gadget, Intervall und Konstanten */
- UBYTE undoFormel[MAXCHARS]; /* Für Gadget, Formeleingabe */
- UBYTE xmpstring[20], xmnstring[20]; /* Strings für Intervall */
- UBYTE ympstring[20], ymnstring[20]; /* Strings für Intervall */
- UBYTE KonAString[20],KonBString[20]; /* Strings für Konstanten */
- UBYTE KonCString[20],KonDString[20]; /* Strings für Konstanten */
- UBYTE Formeln[11][MAXCHARS]; /* Strings für Formeln */
- UBYTE Abgeleitet[2][MAXCHARS]; /* Strings für 1. und 2. Ableitung */
- char SubMenuTitle[10][16]; /* Die Strings für die 10 SubItems */
-
- SHORT XOffset,YOffset;
-
- /* Variablen, in denen wichtige Werte gespeichert werden */
- LONG xx=609,yy=PLOT_Y; /* Punkte in x/y-Richtung */
- double xmp,xmn,ymp,ymn; /* Intervallgrenzen */
- double x0,y0; /* Position der Achsen */
- double xm,ym; /* Maßstab für x/y-Achse */
-
- /* Daten für Screen und Window */
-
- struct NewScreen Schirm=
- {
- 0,0,640,YSCREEN,2,2,1,HIRES,CUSTOMSCREEN,NULL,"Plotter",NULL,NULL
- };
-
- struct NewWindow Fenster=
- {
- 0,10,640,YSCREEN-10,FARBE0,FARBE1,MENUPICK|MOUSEBUTTONS|RAWKEY,
- BORDERLESS|ACTIVATE|REPORTMOUSE|SUPER_BITMAP,
- NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
- CUSTOMSCREEN
- };
-
- /* Hauptprogramm */
-
- VOID _main()
- {
- /* Einige Formeln vorschlagen */
- strcpy(Formeln[0],"sin(x)");
- strcpy(Formeln[1],"cos(x)");
- strcpy(Formeln[2],"tan(x)");
- strcpy(Formeln[3],"x^2");
- strcpy(Formeln[4],"x^3");
- strcpy(Formeln[5],"5*x");
- strcpy(Formeln[6],"x");
- strcpy(Formeln[7],"sqr(x)");
- strcpy(Formeln[8],"ln(x)");
- strcpy(Formeln[9],"log(x)");
-
- /* Intervall vorschlagen */
- strcpy(xmpstring,"pi");
- strcpy(xmnstring,"-pi");
- ympstring[0]='1'; /* global, NULL ist schon gesetzt */
- ymnstring[0]='-';
- ymnstring[1]='1';
-
- /* Konstanten vorschlagen */
- strcpy(KonAString,"-pi");
- strcpy(KonBString,"-pi");
- strcpy(KonCString,"-pi");
- strcpy(KonDString,"-pi");
-
- if(oeffne()) /* Öffnen der Libraries, Screen, Fenster */
- {
- LoadRGB4(viep,Farb2,4L); /* Farben setzen */
- UpdateMenuText(); /* SubMenuText erneuern */
- UmwandlungInIntervall(); /* Intervallstrings in double umwandeln */
- UmwandlungInKonstanten(); /* Konstantenstrings in double umwandeln */
- MenuWahl(); /* Verwertet die Intuition-Messages */
- }
- ende(); /* Gibt den belegten Speicher wieder frei */
- }
-
-
- /* Routine, die Punkt setzt. Parameter DOUBLE */
- VOID Pset(DOUBLE x1,DOUBLE y1)
- {
- Move(RastPort,Fix(Add(x1,RUNDEN))+Abstand,Fix(Add(y1,RUNDEN))+Abstand);
- Draw(RastPort,Fix(Add(x1,RUNDEN))+Abstand,Fix(Add(y1,RUNDEN))+Abstand);
- }
-
- /* Routine, die Linie zieht. Parameter DOUBLE */
- VOID DrawTo(DOUBLE x1,DOUBLE y1)
- {
- Draw(RastPort,Fix(Add(x1,RUNDEN))+Abstand,Fix(Add(y1,RUNDEN))+Abstand);
- }
-
- /* Zeichnet Linie von (x1,y1) - (x2,y2) Parameter : DOUBLE */
- VOID Line(DOUBLE x1,DOUBLE y1,DOUBLE x2,DOUBLE y2)
- {
- /* Zum Anfang bewegen und Linie ziehen */
- Move(RastPort,Fix(Add(x1,RUNDEN))+Abstand,Fix(Add(y1,RUNDEN))+Abstand);
- Draw(RastPort,Fix(Add(x2,RUNDEN))+Abstand,Fix(Add(y2,RUNDEN))+Abstand);
- }
-
- /* Routine zum Beschriften des Koordinatenkreuzes */
- VOID zeichne(VOID)
- {
- char buffer[11];
- double i,dx,dy,x,y;
- char Zaehler;
- long xx,yy;
-
- SetDrMd(RastPort,JAM1);
- /* Bestimmt Abstand zwischen 2 Skalenunterteilungen */
- dx=Div(Sub(xmp,xmn),10.0);
- dy=Div(Sub(ymp,ymn),10.0);
-
- /* Zeichnet Unterteilung der Achsen */
- i=Sub(xmn,dx);
- yy=Fix(y0)+Abstand+12;
- for(Zaehler=0;Zaehler<=10;Zaehler++)
- {
- i=Add(i,dx);
- if(Cmp(Abs(i),Div(dx,1000.0))==-1)i=0.0000;
- x=Add(x0,Mul(i,xm));
- Line(x,Sub(y0,3.0),x,Add(y0,3.0));
- UmwFtoS(buffer,&i,2);
- xx=Fix(x)-(strlen(buffer)<<2)+Abstand;
- Print(RastPort,buffer,FARBE1,xx,yy);
- }
-
-
- i=Sub(ymn,dy);
- xx=Fix(x0)+Abstand+8;
- for(Zaehler=0;Zaehler<=10;Zaehler++)
- {
- i=Add(i,dy);
- if(Cmp(Abs(i),Div(dy,1000.0))==-1)i=0.0000;
- y=Sub(y0,Mul(i,ym));
- Line(Sub(x0,5.0),y,Add(x0,5.0),y);
- UmwFtoS(buffer,&i,2);
- yy=Fix(y)+Abstand+3;
- Print(RastPort,buffer,FARBE1,xx,yy);
- }
- }
-
-
- /* Wertet Mausklick aus */
- VOID MenuWahl(VOID)
- {
- struct MenuItem *Item;
- long menu,item;
- char ENDE=1;
- USHORT sub,menunr;
-
- while(ENDE)
- {
- /* Wartet auf Event */
- Wait(1L<<Window->UserPort->mp_SigBit);
- /* Arbeitet ab, bis keine Events mehr */
- while(EventAbfrage(Window,&msgInfo))
- {
- /* Verzweigt entsprechend der Events */
- switch(msgInfo.NachrichtenArt)
- {
- /* Menupunkt gewählt */
- case MENUPICK:
- {
- menunr=msgInfo.code;
-
- /* Wurde wirklich ein Menu gewählt ? */
- while(menunr!=MENUNULL)
- {
- /* Wenn ja, dann Menu-, Item- und SubItemNummer bestimmen */
- menu=MENUNUM(menunr);
- item=ITEMNUM(menunr);
- sub =SUBNUM (menunr);
- /* Entsprechend des Menus verzweigen */
- switch (menu)
- {
- case 0:
- {
- /* Ein Punkt des ersten Menus wurde gewählt */
- switch(item)
- {
- /* Entsprechend des Items verzweigen */
- case 0:
- {
- /* Bestimmung der neuen Zeichengenauigkeit */
- GE=sub;
- break;
- }
- case 1:
- {
- /* Eingabe eines neuen Intervall */
- do
- {
- TextFuerIntervall(); /* Gadget vorbereiten */
- /* */ /* Grenzen abfragen */
- Grenzen(xmnstring,ymnstring,xmpstring,ympstring);
- UmwandlungInIntervall(); /* Werte kopieren */
- }
- while(Cmp(xmn,xmp)==1 || Cmp(ymn,ymp)==1);
- }
- case 2:
- {
- /* Schirm löschen */
- /* Loeschen(); */
- goto Einsprung_P2;
- }
- case 3:
- {
- /* Routine zum Drucken */
- drucken();
- /* Farben wieder zurücksetzen */
- LoadRGB4(viep,Farb2,4L);
- break;
- }
- case 4:
- {
- ULONG OldIDCMP;
- if(KoordinatenKreuz_gezeichnet)
- {
- OldIDCMP=Window->IDCMPFlags;
- ModifyIDCMP(Window,MOUSEMOVE|MOUSEBUTTONS);
-
- /* */ /* Bereich mit Maus auswählen */
- AusSchnitt(&xmn,&ymn,&xmp,&ymp); /* Funktion aufrufen */
- ModifyIDCMP(Window,OldIDCMP);
- Einsprung_P2:
- Loeschen();
- }
- break;
- }
- case 5:
- {
- /* Eingabe der Werte für die Konstanten */
- TextFuerKonstanten(); /* Gadget vorbereiten */
- /* */ /* Werte vom Anwender holen */
- Grenzen(KonAString,KonCString,KonBString,KonDString);
- UmwandlungInKonstanten(); /* Werte kopieren */
- break;
- }
- case 6:
- {
- /* About */
- Einsprung_P3:
- About();
- break;
- }
- case 7:
- {
- /* Beenden des Programms */
- ENDE=1-request(PLOT_END,PLOT_CONT,PLOT_QUEST);
- }
- }
- break;
- }
- case 1:
- {
- /* Das nullte Menu wurde gewählt */
- switch (item)
- {
- /* Entsprechend des Items verzweigen */
- case 7:
- {
- Full_Discussion(sub);
- goto Einsprung_P3;
- }
- case 0:
- {
- /* Funktionsterm ändern */
- do
- {
- Funktionseingabe(Formeln[sub]); /* Holen der neuen Vorschrift */
- }
- while(AnzahlKlammern((char *)Formeln[sub]));
- UpdateMenuText(); /* SubItemText erneuern */
- break;
- }
- case 1:
- case 2:
- case 3:
- {
- /* Entsprechend dem SubItem zeichnen */
- ZeichneFunktion(sub,(int)item-1);
- break;
- }
- /* Item 4 ist ---------- */
- case 5:
- {
- /* 1. Abl. symbolisch */
- /* Entsprechend dem SubItem zeichnen */
- strcpy(Formeln[10],Ableiten(Formeln[sub]));
- goto Einsprung_P1;
- }
- case 6:
- {
- /* 2. Abl. symbolisch */
- strcpy(Formeln[10],Ableiten(Formeln[sub]));
- strcpy(Formeln[10],Ableiten(Formeln[10]));
- Einsprung_P1:
- ZeichneFunktion(10,0);
- }
- }
- break;
- }
- case 2:
- {
- switch(item)
- {
- case 1:
- {
- Groesse=GROSS;
- xx=969; /* Definiert, wie viele Punkte für Grafik */
- yy=257; /* genutzt werden sollen */
- break;
- }
- case 0:
- {
- Groesse=KLEIN;
- xx=609; /* Definiert, wie viele Punkte für Grafik */
- yy=PLOT_Y; /* genutzt werden sollen */
- }
- }
- goto Einsprung_P2;
- }
- }
- Item=ItemAddress(Menu,(LONG)menunr);
- menunr=Item->NextSelect;
- Item->NextSelect=MENUNULL;
- }
- }
- case RAWKEY:
- {
- if(Groesse)
- {
- TastaturAbfrage();
- }
- }
- }
- }
- }
- }
-
-
- /* Öffnet Libraries, Screen, Window */
- int oeffne()
- {
- int Failed=0;
- if((ToolBase=(struct ToolBase *)OpenLibrary("tool.library",0)))
- {
- IntuitionBase=ToolBase->IntuitionBase;
- GfxBase=ToolBase->GfxBase;
- MathIeeeDoubTransBase=ToolBase->MathIeeeDoubTransBase;
- MathIeeeDoubBasBase=ToolBase->MathIeeeDoubBasBase;
- if(Konstantenstart=Init_Konst())
- {
- if((LayersBase = (struct LayersBase *)OpenLibrary("layers.library",0)))
- {
- if((Screen=(struct Screen *)OpenScreen(&Schirm)))
- {
- InitBitMap(&bitmap,2,1000,MAXPIXELY);
-
- if((bitmap.Planes[0]=AllocRaster(1000,MAXPIXELY)))
- {
- Delay(5);
- if((bitmap.Planes[1]=AllocRaster(1000,MAXPIXELY)))
- {
- Fenster.Screen=Screen; /* Fenster soll auf Screen erscheinen */
- Fenster.BitMap=&bitmap;
- if((Window=(struct Window *)OpenWindow(&Fenster)))
- {
- /* Zuweisung von Variablen, Einfärben des Windows */
-
-
- MakeMenu(); /* Menustrukturen erzeugen */
- NewSetMenuStrip(Window,Menu); /* Menus verknüpfen */
-
- viep=&Screen->ViewPort; /* ViewPort-Zeiger füllen */
- RastPort=Window->RPort; /* Variablenzuweisung */
- layer=RastPort->Layer; /* LayerPointer holen */
- layerinfo=layer->LayerInfo; /* LayerInfo holen */
- SetRast(RastPort,FARBE0); /* Schirm löschen */
-
- Fenster2.Screen=Screen; /* Fenster2 auch auf Screen */
- Fenster3.Screen=Screen; /* Fenster3 auch auf Screen */
- Failed=1; /* Nur wenn alles geklappt hat */
- }
- }
- }
- }
- }
- }
- }
- return(Failed);
- }
-
-
- /* Routine, die alles wieder schließt */
- VOID ende(VOID)
- {
- LONG H;
- Delay(20);
- if(Konstantenstart)Free_Konst(Konstantenstart);
-
- /* Wenn offen -> schließen */
- if(Window)
- {
- while(H=EventAbfrage(Window,&msgInfo));
- ReMakeMenu(Window);
- CloseWindow(Window);
- };
- if(bitmap.Planes[0])
- {
- FreeRaster(bitmap.Planes[0],1000,MAXPIXELY);
- bitmap.Planes[0]=0;
- }
- if(bitmap.Planes[1])
- {
- FreeRaster(bitmap.Planes[1],1000,MAXPIXELY);
- bitmap.Planes[1]=0;
- }
- if(Screen)CloseScreen(Screen);
-
- /* Schließt auch automatisch IntuitionBase etc. */
- if(ToolBase)CloseLibrary((struct Library *)ToolBase);
-
- if(LayersBase)CloseLibrary((struct Library *)LayersBase);
- }
-
- /* Für Intervall */
- VOID UmwandlungInIntervall(VOID)
- {
- /* Sollte nicht benutzt werden, darum ruhig undefinierter Wert */
- berechnen(&xmp,xmpstring,&x0,(struct Konstanten *)Konstantenstart,&MatheFehler);
- berechnen(&xmn,xmnstring,&x0,(struct Konstanten *)Konstantenstart,&MatheFehler);
- berechnen(&ymp,ympstring,&x0,(struct Konstanten *)Konstantenstart,&MatheFehler);
- berechnen(&ymn,ymnstring,&x0,(struct Konstanten *)Konstantenstart,&MatheFehler);
- }
-
- /* Für Konstanten */
- VOID UmwandlungInKonstanten(VOID)
- {
- /* Eine Konstante darf nicht aus dem Wert einer anderen Konstanten bestehen */
- /* Also nicht A=1+B, da B zum Zeitpunkt der Bestimmung von A nicht unbe- */
- /* dingt den richtigen Wert haben muß. */
- /* Es ist zwar prinzipiell möglich, aber man sollte keine Rekursionen be- */
- /* nutzen, wie a=d+1 und d=a*10 */
- DOUBLE var;
-
- berechnen(&var,KonAString,&var,(struct Konstanten *)Konstantenstart,&MatheFehler);
- Set_Konst_P(Konstantenstart,1,&var);
- berechnen(&var,KonBString,&var,(struct Konstanten *)Konstantenstart,&MatheFehler);
- Set_Konst_P(Konstantenstart,2,&var);
- berechnen(&var,KonCString,&var,(struct Konstanten *)Konstantenstart,&MatheFehler);
- Set_Konst_P(Konstantenstart,3,&var);
- berechnen(&var,KonDString,&var,(struct Konstanten *)Konstantenstart,&MatheFehler);
- Set_Konst_P(Konstantenstart,4,&var);
- }
-
- /* Erneuert SubMenuTexte */
- VOID UpdateMenuText(VOID)
- {
- /* Füllt die SubMenuTitel mit den aktuellen Funktionsdefinitionen */
- USHORT i;
- ClearMenuStrip(Window); /* Menuverknüpfung aufheben */
- for(i=0;i<=9;i++)
- {
- left(SubMenuTitle[i],Formeln[i],14L); /* Ans Ziel kopieren */
- }
- SetMenuStrip(Window,Menu); /* Wieder verknüpfen */
- }
-
- VOID SetRXOffset(VOID)
- {
- LONG dx,dy;
-
- if(YOffset<0)YOffset=0;
- if(XOffset<0)XOffset=0;
-
- if(YOffset>(MAXPIXELY-YSCREEN))YOffset=MAXPIXELY-YSCREEN;
- if(XOffset>(1000-640))XOffset=1000-640;
-
- dx=XOffset-(layer->Scroll_X);
- dy=YOffset-(layer->Scroll_Y);
- /* Mit der Abfrage geht es schneller. Auch ein ScrollLayer(..,..,0,0) */
- /* braucht relativ viel Zeit. */
- if(dx||dy)ScrollLayer(layerinfo,layer,dx,dy);
- }
-
- VOID TastaturAbfrage(VOID)
- {
- static short add=1;
- switch(msgInfo.code)
- {
- case 69:
- {
- /* ESC = Ursprung */
- XOffset=YOffset=0;
- break;
- }
- case 76:
- {
- /* Cursor up */
- YOffset-=add;
- goto Einsprung;
- }
- case 77:
- {
- /* Cursor down */
- YOffset+=add;
- goto Einsprung;
- }
- case 78:
- {
- /* Cursor right */
- XOffset+=add;
- goto Einsprung;
- }
- case 79:
- {
- /* Cursor left */
- XOffset-=add;
-
- Einsprung:
- add++;
- break;
- }
- case 204:
- case 205:
- case 206:
- case 207:
- {
- /* Damit nicht zu schnell gescrollt wird... */
- add=1;
- }
- }
- SetRXOffset();
- if(add>10)add=10;
- }
-
- VOID Loeschen(VOID)
- {
- SetRast(RastPort,0);
- /* Koordinatenkreuz beim nächsten Mal neu zeichnen */
- KoordinatenKreuz_gezeichnet=FALSE;
- ScrollLayer(layerinfo,layer,(LONG)-(layer->Scroll_X),(LONG)-(layer->Scroll_Y));
- }
-
-
-
-
-