home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dream 52
/
Amiga_Dream_52.iso
/
Amiga
/
Applications
/
Mathematiques
/
Kurve.lha
/
Kurve
/
kurve.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-12-06
|
48KB
|
1,744 lines
/* kurvemake */
/* this is the name of the makefile */
/*******************************************************************/
/* */
/* Kurve */
/* */
/* Kurvendiskusion */
/* */
/* ⌐ 89-92 by Henning Rink */
/* */
/* Version 2.001 12.09.1992 */
/* */
/* */
/* copyright notes -> see ReadMe */
/*******************************************************************/
/*******************************************************************/
/* */
/* REVISION HISTORY */
/* */
/* Kurve V1.0 10.09.1989 */
/* */
/* Kurve V1.5 20.02.1990 */
/* changed Parser 2.55 to 3.0 */
/* Parser now creates code for pseudo-stack-machine */
/* */
/* Kurve V1.6 21.10.1990 */
/* Updated whole programm for Aztec C 5.0a */
/* new Funktion-Requester */
/* added zooming of coordinates */
/* */
/* Kurve V1.7 01.12.1990 */
/* new Parser 4.00 now generates 68000 machine code for IEEE64 libs*/
/* some minor changes in frequest.c */
/* */
/* small changes in NeueF() V1.701 07.01.1991 */
/* changed DoReq() 07.01.1991 */
/* changed colours for WB 2.0 (got Kick36.141?) V1.702 19.01.1991 */
/* some minor changes at pseudo bugs V1.703 10.03.1991 */
/* added UnZoom() 10.03.1991 */
/* changed line-clipping code V1.704 19.03.1991 */
/* */
/* Kurve V1.71 27.04.1991 */
/* added screenprefs() and changed all? coordinates to */
/* relative screen height and width 27.04.1991 */
/* */
/* V1.711 changed Drucken() because I got a formfeed between */
/* close(fd[prt:]) (printing of the Text ) */
/* and the OpenDevice(printer...) (prints RastPort) */
/* this occur only with HP-Desk/Laserjet 27.05.1991 */
/* added ShowErr() 28.05.1991 */
/* */
/* V1.712 some code improvements, menu style change 15.06.1991 */
/* no more dividing with constant floats->> multiply it! */
/* */
/* V1.713 small changes in all modules 25.07.1991 */
/* */
/* V1.714 changed Cross() and ZoomBox() 10.08.1991 */
/* */
/* V1.715 more 2.0 styling, translation german english */
/* corrected g-format error -->>checkstring() 18. and 24.08.1991 */
/* */
/* V1.716 WB like cycling of ZoomBox 24.09.1991 */
/* */
/* V1.800 added changescreensize requester, 17.11.1991 */
/* changecolor request and some menu improvements */
/* Deleted Funktion(), Ableitung1() and Ableitung2() */
/* --> all drawing is done via DrawFunc() */
/* Inserted getcolors(); enabled Keystroke Activation 18.11.1991 */
/* of all Gadgets used in Requesters */
/* inserted new mousepointer 19.11.1991 */
/* added extLoadConfig and extSaveConfig to handle different */
/* configuration files 19. and 20.11.1991 */
/* */
/* V1.801 found bug in tag structure; changed Draw->All 17.12.1991 */
/* */
/* V1.802 ShowErr now does AutoRequest, added numerical (Simpson) */
/* integration of the function from xmin to xmax 21.12.1991 */
/* */
/* added #ifdef AztecVERSION500 to printpara() and checkstring() */
/* in funkrequest.c, so checkstring is only compiled if you set */
/* this define to AztecVERSION500 -> see checkstring() */
/* changed some cast operators and includes.kur cause I'm using */
/* now the Kick2.04 and AztecC52 includes 24.12.1991 */
/* some minor enhancements 25.12.1991 */
/* placed file and screenrequest in fileandscreen.c 28.12.1991 */
/* V1.803 last Aztec 5.0d/e Version 28.12.1991 */
/* */
/* V1.900 new functionlist requester and new intervall requester */
/* to deal with various number of functions 29.12.1991-06.02.1992 */
/* recursive drawfunc2() 08.02.1992 */
/* */
/* V1.901 */
/* disabled load-save in Functionlist and found bug in disabling */
/* Colors Menu if no palette requester is available 28.02.1992 */
/* */
/* V1.902 bug in doreqreq found !! 17.04.1992 */
/* now save and load settings always with the active function */
/* bug in load - save functions found; load buffer was to small */
/* */
/* Changes for Version 2.000 */
/* doing CreateMenus() disabled KickstartVersions<37 28.07.1992 */
/* changescreenmode-request with kick 2.0 look 01. to 03.08.1992 */
/* MouseCenterWin, new OK,Cancel Gadgets 03. to 04.08.1992 */
/* handlepattern, handleedit 04. to 05.08.1992 */
/* changeintervall, asl filerequester 06.08.1992 */
/* showerr now does EasyRequest() 12.08.1992 */
/* min_open 13.08.1992 */
/* turboparser4.00 for 68881/82 16.08.1992 */
/* */
/* V2.001 small change in fileandscreen->gadgethandling 12.09.1992 */
/* improved handling of asl.requester some code cleanup 27.09.1992 */
/*******************************************************************/
/* externals in globdata.c */
extern struct NewWindow FirstNewWindow;
extern struct NewWindow SecondNewWindow;
extern struct NewWindow ThirdNewWindow;
extern struct NewWindow FourthNewWindow;
extern struct NewScreen FirstNewScreen; /* this is an ExtNewScreen !! */
extern struct TextAttr NormalAttr;
extern struct IntuiText MemText;
extern struct IntuiText DateText;
extern struct IntuiText NameText;
extern unsigned char funktion[]; /* init with LoadConfig() 25.07.1991 */
extern unsigned char UndoBuffer[];
extern unsigned char minx[];
extern unsigned char maxx[];
extern unsigned char miny[];
extern unsigned char maxy[];
extern char *Days[],*Months[],*ErrorMessages[];
extern const char *coltoolname;
extern UWORD mousedata[];
extern USHORT defscr;
extern struct EasyStruct es1;
extern APTR ScreenVI;
extern struct Menu *menu;
extern struct NewMenu menulist[];
extern struct NewGadget NewOKGadget;
extern struct NewGadget NewCancelGadget;
extern struct Gadget *nullgadget;
/* externals from funkrequest.c and parser.c */
extern double x;
extern short fehler;
extern short *point;
extern void FuncReq(void);
extern void ZoomBox(USHORT);
extern void UnZoom(void);
extern void printpara(unsigned char *,double);
extern void checkrights(char *);
extern void changecolor(void);
extern void changescreenmode(void);
extern void extLoadConfig(void);
extern void extSaveConfig(void);
extern void LoadConfig(char *);
extern void setcolors(void);
extern void delallfuncs(void);
extern void changeintervall(void);
extern void helpdruck(UBYTE **, long *);
extern void ReDrawFuncs(void);
extern void MouseCenterWin(struct NewWindow *,short,short);
extern void handlesave(void);
extern void setscreenprefs(void);
/* internal functions */
void Open_LIBS(void);
void Close_LIBS(void);
void Open_WINS(void);
void Close_WINS(void);
void About(void);
void Drucken(void);
void Ende(void);
void NeueP(void);
void DrawFunc(double (*)(double),long);
void Clear(void);
void Nullstellen(void);
void Maxima(void);
void Wendepunkte(void);
void Cross(void);
void Maus(void);
void newton1(short);
void newton2(short, double);
void newton3(short, double);
short openex(void);
void closeex(short);
void exaus(short,double,double,short);
double f(double);
double fa(double);
double fa2(double);
double fa3(double);
WORD Menuauswertung(USHORT);
short ShowErr(short,BOOL);
void NumIntegrate(double (*)(double));
void Cleardrawn(void);
void DrawFunc2(double (*)(double),double,long);
void Kickerror(void);
void min_open(void);
/* more vars */
double (*numb)(void);
double (*numb1)(void);
double (*numb2)(void);
struct FuncNode *FirstFunc;
struct FuncNode *activeFunc;
extern struct ExecBase *SysBase;
struct ReqLib *ReqBase;
struct IntuitionBase *IntuitionBase;
struct Library *AslBase;
struct Library *GadToolsBase;
struct Screen *FirstScreen;
struct Window *FirstWindow,*SecondWindow,*ThirdWindow,*FourthWindow;
struct IntuiMessage *message;
struct GfxBase *GfxBase;
struct RastPort *rp,*rp2,*rp4;
struct Process *process;
APTR oldwin;
double xmin,xmax,ymin,ymax,xstep,xe,ye;
long xnull,ynull; /* Nullpunkte */
short STEP=4;
long ys,xs,yn,xn,xmouse,ymouse; /* Startendkoordinaten fⁿr Zoombox */
long scrheight,scrwidth,winheightmax,scrmode;
short flag=0;
UWORD *mousemem;
extern struct IntuiText CopyrightText;
extern char configfile[];
extern char configpath[];
extern char configdir[];
short array[1500];
union printerIO /* look for Addison Wesley Libraries&Devices */
{
struct IOStdReq ios;
struct IODRPReq iodrp;
struct IOPrtCmdReq iopc;
};
void _cli_parse(){}
void _wb_parse(){}
void main(void)
{
register ULONG MessageClass;
USHORT Code,paint=0;
WORD goon;
if(SysBase->LibNode.lib_Version<37) /* 28.07.1992 */
Kickerror();
xmin=sin(3.0)+sin(3.0); /* ╓ffnen der Mathlibs 10.03.1991 */
/* bei einem Fehler bricht das Programm */
/* automatisch ab !!! */
Open_LIBS();
strcpy(&configpath[0],&configdir[0]);
strcat(&configpath[0],&configfile[0]);
LoadConfig(NULL);
checkrights((char *)CopyrightText.IText);
/* all screen configuration done !! */
/* so lets open my screen and windows */
Open_WINS();
FOREVER
{
Wait(1L<<FirstWindow->UserPort->mp_SigBit);
while(message=(struct IntuiMessage *)GetMsg(FirstWindow->UserPort))
{
MessageClass=message->Class;
Code=message->Code;
xmouse=message->MouseX;
ymouse=message->MouseY;
ReportMouse((long)FALSE,FirstWindow);
if(MessageClass&MENUVERIFY)
{
if(paint)
{
if(flag)
ZoomBox(2);
paint=0;
if(Code==MENUHOT)
message->Code=MENUCANCEL;
}
}
ReplyMsg((struct Message *)message);
switch(MessageClass)
{
case MOUSEBUTTONS :
switch(Code)
{
case SELECTUP :
paint=0;
if(flag)
ZoomBox(paint);
break;
case SELECTDOWN : /* disabling menu messages 25.07.1991 */
if(!paint)
{
paint=1;
xs=xmouse;
ys=ymouse;
}
break;
}
break;
case INTUITICKS: /* added 24.09.1991 */
if(paint)
ZoomBox(paint);
break;
case MOUSEMOVE :
if(paint)
ZoomBox(paint);
Maus();
break;
case MENUPICK :
if(Code!=MENUNULL)
{
goon=Menuauswertung(Code); /* got an endless loop of */
while(goon) /* NextSelect so I must */
{ /* have a return value from Menuauswertung */
/* since doing CreateMenus() 28.07.1992 */
Code=ItemAddress(menu,(long)Code)->NextSelect;
if(Code!=MENUNULL)
goon=Menuauswertung(Code);
else
break;
}
}
break;
}
ReportMouse((long)TRUE,FirstWindow);
}
}
}
/******************************************/
/* */
/* Auswertung der Menunummer */
/* */
/******************************************/
WORD Menuauswertung(USHORT Menunummern)
{
register USHORT Menu,MenuItem,SubItem;
WORD retval=TRUE;
Menu=MENUNUM(Menunummern);
MenuItem=ITEMNUM(Menunummern);
SubItem=SUBNUM(Menunummern);
SetDrMd(rp,(long)JAM1);
switch(Menu)
{
case 0:
switch(MenuItem)
{
case 0:
Cleardrawn();
Clear();
break;
case 1:
About();
break;
case 2:
if(ShowErr(16,TRUE))
Drucken();
break;
case 3:
if(ShowErr(0,TRUE))
Ende();
break;
}
break;
case 1:
switch(MenuItem)
{
case 0:
FuncReq();
break;
case 1:
changeintervall();
break;
case 2:
UnZoom();
break;
case 3:
switch(SubItem) /* Schrittweite einstellen */
{
case 0:
STEP=1;
xstep=(xmax-xmin)/scrwidth;
break;
case 1:
STEP=2;
xstep=(xmax-xmin)/scrwidth*2.0;
break;
case 2:
STEP=4;
xstep=(xmax-xmin)/scrwidth*4.0;
break;
case 3:
STEP=8;
xstep=(xmax-xmin)/scrwidth*8.0;
break;
}
break;
case 4:
changescreenmode();
retval=FALSE;
break;
case 5:
changecolor();
break;
case 6:
extLoadConfig();
retval=FALSE;
break;
case 7:
extSaveConfig();
break;
}
break;
case 2:
switch(MenuItem)
{
case 0:
activeFunc->isdrawn|=0x01;
DrawFunc(f,1L);
break;
case 1:
activeFunc->isdrawn|=0x02;
DrawFunc(fa,4L);
break;
case 2:
activeFunc->isdrawn|=0x04;
DrawFunc(fa2,5L);
break;
case 3:
activeFunc->isdrawn|=0x07;
DrawFunc(f,1L);
DrawFunc(fa,4L);
DrawFunc(fa2,5L);
break;
case 4:
Clear();
ReDrawFuncs();
break;
}
break;
case 3:
switch(MenuItem)
{
case 0:
Nullstellen();
break;
case 1:
Maxima();
break;
case 2:
Wendepunkte();
break;
case 3:
NumIntegrate(f);
break;
}
break;
}
SetDrMd(rp,(long)JAM1|COMPLEMENT);
return(retval);
}
void Open_LIBS(void)
{
extern struct Gadget FuncSaveGadget,FuncLoadGadget;
if(!(AslBase=(struct Library *) /* asl and gadtools on 28.07.1992 */
OpenLibrary((UBYTE *)"asl.library",37L)))
{
Close_LIBS();
exit(0);
}
if(!(GadToolsBase=(struct Library *)
OpenLibrary((UBYTE *)"gadtools.library",37L)))
{
Close_LIBS();
exit(0);
}
ReqBase=(struct ReqLib *)OpenLibrary((UBYTE *)"req.library",0L);
if(!(mousemem=AllocMem(72L,MEMF_CHIP)))
{
Close_LIBS();
exit(0);
}
CopyMem((char *)&mousedata[0],(char *)mousemem,72L);
if(!(GfxBase=(struct GfxBase *)
OpenLibrary((UBYTE *)"graphics.library",37L)))
{
Close_LIBS();
exit(0);
}
if (!(IntuitionBase = (struct IntuitionBase *)
OpenLibrary((UBYTE *)"intuition.library", 37L)))
{
Close_LIBS();
exit(0);
}
}
void Close_LIBS(void)
{
if (mousemem) FreeMem(mousemem,72L);
if (AslBase) CloseLibrary((struct Library *)AslBase);
if (GadToolsBase) CloseLibrary((struct Library *)GadToolsBase);
if (ReqBase) CloseLibrary((struct Library *)ReqBase);
if (GfxBase) CloseLibrary((struct Library *)GfxBase);
if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
}
void Open_WINS(void)
{
BPTR fh;
extern struct NewWindow ReqNewWindow,FuncReqNewWindow;
if(!(FirstScreen=OpenScreen(&FirstNewScreen)))
{
if(ScreenVI) /* do not call min_open on programmstart */
{ /* changed 13.08.1992 */
min_open();
return();
}
else
{
ShowErr(15,FALSE);
Ende();
}
}
ScreenVI=GetVisualInfo(FirstScreen,TAG_DONE); /* 28.07.1992 */
NewOKGadget.ng_VisualInfo=NewCancelGadget.ng_VisualInfo=ScreenVI;
FirstNewWindow.Screen=SecondNewWindow.Screen=ThirdNewWindow.Screen=\
FourthNewWindow.Screen=ReqNewWindow.Screen=FuncReqNewWindow.Screen=FirstScreen;
if (!(FirstWindow = OpenWindow(&FirstNewWindow)))
{
ShowErr(15,FALSE);
Ende();
}
process= (struct Process *) FindTask(NULL);
oldwin=process->pr_WindowPtr;
process->pr_WindowPtr=(APTR)FirstWindow;
if(!(menu=CreateMenusA(menulist,NULL))) /* 28.07.1992 */
{
ShowErr(17,FALSE);
Ende();
}
if(!LayoutMenusA(menu,ScreenVI,NULL))
{
ShowErr(17,FALSE);
Ende();
}
if(!(SetMenuStrip(FirstWindow,menu))) /* Menu aktivieren */
{ /* Test since 25.07.1991 */
ShowErr(17,FALSE);
Ende();
}
if(!ReqBase)
{
if(!(fh=Lock((UBYTE *)coltoolname,(long)ACCESS_READ)))
{
OffMenu(FirstWindow,(long)0x00a1);
}
else
UnLock(fh);
}
if (!(SecondWindow = OpenWindow(&SecondNewWindow)))
{
ShowErr(8,FALSE);
Ende();
}
rp=FirstWindow->RPort;
rp2=SecondWindow->RPort;
SetAPen(rp,5L);
SetBPen(rp,0L);
SetAPen(rp2,1L);
SetDrPt(rp,0xffff);
SetDrMd(rp,(long)JAM1);
setcolors();
Cross();
Maus();
SetDrMd(rp,(long)JAM1|COMPLEMENT);
}
void Close_WINS(void)
{
if (FirstWindow) process->pr_WindowPtr=oldwin; /* Don't test oldwin!! */
/* test FirstWindow 10.03.1991 */
if (FirstWindow->MenuStrip) ClearMenuStrip(FirstWindow);
/* did only test FirstWindow before 25.07.1991 */
if (menu) FreeMenus(menu);
if (FirstWindow) CloseWindow(FirstWindow);
if (SecondWindow) CloseWindow(SecondWindow);
if (FirstScreen)
{
FreeVisualInfo(ScreenVI);
CloseScreen(FirstScreen);
}
FirstScreen=FirstWindow=SecondWindow=menu=0L;
/* BUG !!! if reopen windows with */
} /* Open_WINS after Close_WINS AND */
/* then ran out of mem, I close */
/* FirstWindow, but there is no */
/* FirstWindow! 25.12.1991 */
/******************************************/
/* */
/* Fenster mit Infotext */
/* */
/******************************************/
void About(void)
{
ULONG MessageClass;
struct RastPort *rp3;
long memchip,memother;
time_t z;
UBYTE speicher[40];
struct tm *zeit;
short offset;
ThirdNewWindow.FirstGadget=NULL;
time(&z); /* Zeit als long Variable */
zeit=localtime((const time_t *)&z); /* long Variable in Zeitstructur wandeln */
sprintf((char *)UndoBuffer,"%s %2d. %s %4d %2d:%02d:%02d",Days[zeit->tm_wday],zeit->tm_mday,
Months[zeit->tm_mon],zeit->tm_year+1900,
zeit->tm_hour,zeit->tm_min,zeit->tm_sec);
offset=200-TextLength(rp,(STRPTR)UndoBuffer,strlen((const char *)UndoBuffer))/2;
DateText.IText=UndoBuffer; /* Structuren vervollstΣndigen */
DateText.LeftEdge=offset;
memchip=AvailMem(MEMF_CHIP);
memother=AvailMem(MEMF_FAST);
sprintf((char *)speicher,"%ld chip mem, %ld other mem",memchip,memother);
offset=200-TextLength(rp,(STRPTR)speicher,strlen((const char *)speicher))/2;
MemText.IText=speicher; /* Structuren vervollstΣndigen */
MemText.LeftEdge=offset;
MouseCenterWin(&ThirdNewWindow,0,0);
if ((ThirdWindow = OpenWindow(&ThirdNewWindow))==NULL)
ShowErr(9,FALSE);
else
{
rp3=ThirdWindow->RPort;
PrintIText(rp3,&NameText,0L,0L);
FOREVER
{
if((message=(struct IntuiMessage *)
GetMsg(ThirdWindow->UserPort))==NULL)
{
Wait(1L << ThirdWindow->UserPort->mp_SigBit);
continue;
}
MessageClass=message->Class;
ReplyMsg((struct Message *)message);
switch(MessageClass)
{
case MOUSEBUTTONS :
CloseWindow(ThirdWindow);
return();
}
}
}
}
/******************************************/
/* */
/* Ausgabe des Windows und der */
/* Einstellungen auf den Drucker */
/* */
/******************************************/
void Drucken(void)
{
struct MsgPort *printerPort;
union printerIO *request;
UBYTE *memblock;
long len,col0,col2;
helpdruck(&memblock,&len); /* inserted 29.01.1992 */
if(!len)
return();
SetPointer(FirstWindow,mousemem,16L,16L,0L,0L);
if(printerPort=CreatePort(NULL,0L))
{
if(request=(union printerIO *)CreateExtIO(printerPort,
sizeof(union printerIO)))
{
if(!(OpenDevice((UBYTE *)"printer.device",0L,(struct IORequest *)request,0L)))
{
/* old sprintf() deleted 29.01.1992 */
request->ios.io_Message.mn_ReplyPort=printerPort;
request->ios.io_Command=CMD_WRITE;
request->ios.io_Data=(APTR)memblock;
request->ios.io_Length=len;
if(!(DoIO((struct IORequest *)request)))
{
col0=GetRGB4(FirstScreen->ViewPort.ColorMap,0L);
col2=GetRGB4(FirstScreen->ViewPort.ColorMap,2L);
SetRGB4(&FirstScreen->ViewPort,0L,15L,15L,15L);
SetRGB4(&FirstScreen->ViewPort,2L,0L,0L,0L);
/* Einstellungen fⁿr einen RastPort-Dump */
request->iodrp.io_Command= PRD_DUMPRPORT;
request->iodrp.io_RastPort=rp;
request->iodrp.io_ColorMap=FirstScreen->ViewPort.ColorMap;
request->iodrp.io_Modes=FirstScreen->ViewPort.Modes;
request->iodrp.io_SrcX=0; /* LeftEdge -- TopEdge !! */
request->iodrp.io_SrcY=0; /* so kann man auch einen Ausschnitt drucken */
request->iodrp.io_SrcWidth=scrwidth;
request->iodrp.io_SrcHeight=scrheight-10;
request->iodrp.io_Special= SPECIAL_FULLROWS | SPECIAL_FULLCOLS | SPECIAL_ASPECT;
if(DoIO((struct IORequest *)request))/* wartet bis Drucker fertig ist */
fehler=10; /* SendIO wⁿrde im Programm fortfahren */
SetRGB4(&FirstScreen->ViewPort,0L,(col0>>8) & 0xf,(col0>>4) & 0xf,col0 & 0xf);
SetRGB4(&FirstScreen->ViewPort,2L,(col2>>8) & 0xf,(col2>>4) & 0xf,col2 & 0xf);
}
CloseDevice((struct IORequest *)request);
}
DeleteExtIO((struct IORequest *)request);
}
DeletePort(printerPort);
}
ClearPointer(FirstWindow); /* 29.01.1992 */
FreeMem(memblock,len);
}
void Ende(void)
{
delallfuncs();
Close_WINS();
Close_LIBS();
exit(0);
}
/**************************************************/
/* */
/* Einstellungen nach Neueingabe ⁿberprⁿfen */
/* */
/**************************************************/
void NeueP(void)
{
register double help,xnd,ynd;
xmin=atof((const char *)minx);
xmax=atof((const char *)maxx);
ymin=atof((const char *)miny);
ymax=atof((const char *)maxy);
if(xmin>xmax) /* X-Werte vertauscht */
{
help=xmin;
xmin=xmax;
xmax=help;
}
if(ymin>ymax) /* Y-Werte vertauscht */
{
help=ymin;
ymin=ymax;
ymax=help;
}
printpara(minx,xmin); /* Werte nochmals reinschreiben ,um */
printpara(miny,ymin); /* falsche Eingaben dem Benutzer beim */
printpara(maxx,xmax); /* nΣchsten Aufruf sichtbar zu machen */
printpara(maxy,ymax);
xstep=(xmax-xmin)/scrwidth*STEP;
xe=scrwidth/(xmax-xmin); /* Schrittweite X 1Pixel */
xnd=xe*-xmin; /* Nullpunkt X */
ye=(scrheight-10)/(ymax-ymin); /* Schrittweite Y 1 Pixel */
ynd=(scrheight-10)-ye*-ymin; /* Nullpunkt Y */
xnull=xnd; /* long Variablen mit Nullpunkt */
ynull=ynd;
}
/*******************************************************************/
/* */
/* DrawFunc() is a revision of the old */
/* Ableitung1() --> so Funktion(), */
/* Ableitung() and Ableitung2() is */
/* done with DrawFunc() */
/* ->code size improvement of 860 bytes */
/* */
/*******************************************************************/
void DrawFunc(double (*calc)(double),long color)
{
register double y,x1;
register long xp,yp;
long oldy;
short flag=0;
UWORD oldpattern;
if(fehler)
return();
oldpattern=rp->LinePtrn;
SetPointer(FirstWindow,mousemem,16L,16L,0L,0L);
SetAPen(rp,color);
SetDrPt(rp,activeFunc->FuncPattern);
x1=xmin;
y=calc(x1);
yp=y*ye;
yp=ynull-yp;
xp=xmin*xe;
if(yp>winheightmax)
{
yp=winheightmax;
flag=1;
}
else
if(yp<0L)
{
yp=0L;
flag=1;
}
oldy=yp;
Move(rp,0L,yp);
for(;x1<xmax;x1 += xstep)
{
y=calc(x1);
yp=-y*ye;
yp+=ynull;
xp=x1*xe;
xp += xnull;
/* more Line-Clipping */
/* changed 19.03.1991 and 27.04.1991 */
/* old Version draws a line to y=251 or y=-1 */
/* this never caused a guru, but i thought */
/* my old A2000 A (built 23-Jun-87) machines */
/* behavior is not like everyone's */
if(yp>winheightmax)
{
if(flag)
Move(rp,xp,winheightmax);
else
{
if(labs(yp-oldy)>(STEP<<2))
DrawFunc2(calc,xstep,yp);
Draw(rp,xp,winheightmax);
flag=1;
}
}
else
{
if(yp<0L)
{
if(flag)
Move(rp,xp,0L);
else
{
if(labs(yp-oldy)>(STEP<<2))
DrawFunc2(calc,xstep,yp);
Draw(rp,xp,0L);
flag=1;
}
}
else
{
if(labs(yp-oldy)>(STEP<<2))
DrawFunc2(calc,xstep,yp);
Draw(rp,xp,yp);
flag=0;
}
}
oldy=yp;
}
ClearPointer(FirstWindow);
SetDrPt(rp,oldpattern);
}
/*******************************************************************/
/* */
/* DrawFunc2() draws one new step if delta y is to big */
/* done 08.02.1992 */
/* */
/*******************************************************************/
void DrawFunc2(double (*calc)(double),double oldstep,long oldy)
{
double xold,step;
register long xp,yp;
step=oldstep*0.5;
xold=x;
yp=-calc(x-step)*ye;
yp+=ynull;
xp=x*xe; /* x is set while doing calc(x-step) */
xp += xnull;
if(yp>winheightmax)
yp=winheightmax;
else if(yp<0L)
yp=0L;
if(labs(yp-oldy)>(STEP<<2))
DrawFunc2(calc,step,yp);
Draw(rp,xp,yp);
x=xold;
}
/*******************************************************************/
/* */
/* Cleardrawn clears the isdrawn Flag in */
/* struct FuncNode done 23.01.1992 */
/* */
/*******************************************************************/
void Cleardrawn(void)
{
struct FuncNode *nodeptr;
nodeptr=FirstFunc;
do
{
nodeptr->isdrawn=0;
}while(nodeptr=nodeptr->Next);
}
void Clear(void) /* Bildschirm l÷schen */
{
SetRast(rp,0L);
Cross();
}
/******************************************/
/* */
/* Nullstellensuche */
/* */
/******************************************/
void Nullstellen(void)
{
short n=0,sign,sign2;
register double dx,z;
if(openex())
return();
Move(rp4,156L,20L); /* Text ausgeben */
Text(rp4,(UBYTE *)"Zero points",11L);
x=xmin;
sign=numb() < 0.0 ? 0 : 1;
dx=(xmax-xmin)/scrwidth*4.0; /* Schrittweite 4 Pixel */
for(;x<=xmax;x += dx)
{
sign2=numb() < 0.0 ? 0 : 1;
if(sign != sign2 )
{
z=x;
x -= dx*.5;
n++; /* ZΣhler der Nullstellen */
newton1(n);
x = z;
sign=sign2;
}
}
closeex(n);
}
/******************************************/
/* */
/* Ausgabewindow ÷ffnen */
/* */
/******************************************/
short openex(void)
{
if (!(FourthWindow = OpenWindow(&FourthNewWindow)))
{
ShowErr(12,FALSE);
return(1);
}
rp4=FourthWindow->RPort;
SetAPen(rp4,6L);
SetBPen(rp4,0L);
return(0);
}
/******************************************/
/* */
/* Ausgabewindow schlie▀en */
/* */
/******************************************/
void closeex(short n)
{
long yoffset;
yoffset=50+n*10;
if(yoffset>(scrheight-15L))
Move(rp4,184L,scrheight-18L); /* Text ausgeben */
else
Move(rp4,184L,yoffset);
SetAPen(rp4,6L);
Text(rp4,(UBYTE *)"End",3L);
Wait(1L<<FourthWindow->UserPort->mp_SigBit);
message=(struct IntuiMessage *)GetMsg(FourthWindow->UserPort);
ReplyMsg((struct Message *)message);
CloseWindow(FourthWindow);
}
/******************************************/
/* */
/* Ausgabe der gefundenen Stellen */
/* */
/******************************************/
void exaus(short n,double a,double b,short s)
{
long offset=30+n*10;
sprintf((char *)UndoBuffer,"y=%12.8f at x= %12.8e",a,b);
if(offset>((scrheight/10)*10-30))
{
offset=(scrheight/10)*10-30;
ScrollRaster(rp4,0L,10L,18L,32L,395L,scrheight-25L);
}
Move(rp4,20L,offset);
SetAPen(rp4,1L);
Text(rp4,(UBYTE *)UndoBuffer,strlen((const char *)UndoBuffer));
if(s)
{
SetAPen(rp4,4L);
Move(rp4,360L,offset);
switch(s)
{
case 1:
Text(rp4,(UBYTE *)"Max",3L);
break;
case 2:
Text(rp4,(UBYTE *)"Min",3L);
break;
case 3:
Text(rp4,(UBYTE *)"T",1L);
break;
case 4:
Text(rp4,(UBYTE *)"S",1L);
break;
}
}
}
/******************************************/
/* */
/* Ermitteln der Nullstelle */
/* */
/******************************************/
void newton1(short n)
{
register double x1,y1,y2;
short q=0;
x1=x;
y1=numb();
do
{
x += 1e-7;
y2=numb();
x1=x1-y1/((y2-y1)*1e7);
x=x1;
y1=numb();
q++;
}while((fabs(y1)>0.00001) && q<60);
exaus(n,y1,x1,0);
}
/******************************************/
/* */
/* Maximasuche */
/* */
/******************************************/
void Maxima(void)
{
short n=0,sign,sign2;
register double dx,z,x1;
if(openex())
return();
SetAPen(rp4,6L);
Move(rp4,140L,20L);
Text(rp4,(UBYTE *)"Maxima & Minima",15L);
x1=xmin;
dx=(xmax-xmin)/scrwidth*8.0;
sign=fa(x1)<0.0 ? 0 : 1;
for(;x1<=xmax;x1 += dx)
{
sign2=fa(x1)<0.0 ? 0 : 1;
if(sign != sign2)
{
z=x1;
x1 -= dx*.5;
n++;
newton2(n,x1);
x1=z;
sign=sign2;
}
}
closeex(n);
}
/******************************************/
/* */
/* Ermittlung des Maximas */
/* */
/******************************************/
void newton2(short n,double x1)
{
register double y1,y;
short q=0,s;
y1=fa(x1);
do
{
x1=x1-fa(x1)/fa2(x1);
y1=fa(x1);
q++;
}while((fabs(y1)>0.001)&&q<60);
x=x1;
if(fa2(x1)<0.0)
s=1;
else
s=2;
y=numb();
exaus(n,y,x1,s);
}
/******************************************/
/* */
/* Wendepunktsuche */
/* */
/******************************************/
void Wendepunkte(void)
{
short n=0,sign,sign2;
register double dx,z,x1;
if(openex())
return();
SetAPen(rp4,6L);
Move(rp4,144L,20L);
Text(rp4,(UBYTE *)"Turning points",14L);
x1=xmin;
dx=(xmax-xmin)/scrwidth*8.0;
sign=fa2(x1)<0.0 ? 0 : 1;
for(;x1<=xmax;x1 += dx)
{
sign2=fa2(x1)<0.0 ? 0 : 1;
if(sign != sign2)
{
z=x1;
x1 -= dx*.5;
n++;
newton3(n,x1);
x1=z;
sign=sign2;
}
}
closeex(n);
}
/******************************************/
/* */
/* Ermittlung des Wendepunktes */
/* */
/******************************************/
void newton3(short n,double x1)
{
register double y1,y;
short q=0,s=3;
y1=fa2(x1);
do
{
x1=x1-fa2(x1)/fa3(x1); /* x2=x1-f(x1)/f'(x1) */
y1=fa2(x1);
q++;
}while((fabs(y1)>0.001)&&q<60);
x=x1;
if(fabs(fa(x1))<0.1)
s=4;
y=numb();
exaus(n,y,x1,s);
}
/******************************************/
/* */
/* Koordinatenkreuz zeichnen */
/* */
/******************************************/
void Cross(void)
{
register double z;
register long s;
double zadd;
SetAPen(rp,2L);
/* Achsen zeichnen */
if(ynull>=0 && ynull<=winheightmax) /* X-Achse */
{
Move(rp,0L,ynull);
Draw(rp,scrwidth-1L,ynull);
zadd=pow(10.0,floor(log10(xmax-xmin)-0.7)); /* 20 minutes of thinking */
z=floor(xmin/zadd)*zadd+zadd; /* 1h work, but great effect */
/* changed 10.08.1991 */
/* -0.7 gives 50 Steps */
/* -> 10^(1.7)=50.??? */
do /* Einheiten zeichnen */
{
s=xe*z+xnull;
Move(rp,s,ynull-3L); /* auf X-Achse */
Draw(rp,s,ynull+3L);
z+=zadd;
}while(z<=xmax);
}
if(xnull>=0 && xnull<=scrwidth) /* Y-Achse */
{
Move(rp,xnull,0L);
Draw(rp,xnull,winheightmax);
zadd=pow(10.0,floor(log10(ymax-ymin)-0.55));/* -0.55 gives me 35 steps */
z=floor(ymin/zadd)*zadd+zadd;
do
{
s=-ye*z+ynull;
Move(rp,xnull-6L,s); /* auf Y-Achse */
Draw(rp,xnull+6L,s);
z+=zadd;
}while(z<=ymax);
}
}
/******************************************/
/* */
/* Function */
/* */
/******************************************/
double f(double r) /* 17.11.1991 */
{
x=r;
return(numb());
}
/******************************************/
/* */
/* 1. Ableitung */
/* */
/******************************************/
double fa(double r)
{
register double x1,x2;
x=r;
if(numb1)
return(numb1());
x1=numb();
x += 1e-6;
x2 = numb();
/* (f(x+dx)-f(x))/dx */
return((x2-x1)*1e6);
}
/******************************************/
/* */
/* 2. Ableitung */
/* */
/******************************************/
double fa2(double r)
{
register double x1,x2;
double x3;
x=r;
if(numb2)
return(numb2());
x1=numb();
x += 1e-5;
x2=numb();
x += 1e-5;
x3=numb();
/* f''(x)=(f(x+2dx)-2f(x+dx)+f(x))/dx^2 */
return((x3-2.0*x2+x1)*1e10);
}
/******************************************/
/* */
/* 3. Ableitung */
/* */
/******************************************/
double fa3(double r)
{
register double x2,x3;
double x1,x4;
x=r;
x1=numb();
x += 1e-3;
x2=numb();
x += 1e-3;
x3= numb();
x += 1e-3;
x4=numb();
/* f'''(x)=(f(x+3dx)-3f(x+2dx)+3f(x+dx)-f(x))/dx^3 */
return((x4-3.0*x3+3.0*x2-x1)*1e9);
}
/************************************************/
/* */
/* abolute Koordinaten ins 2. Fenster schreiben */
/* */
/************************************************/
void Maus(void)
{
double mfy,mfx;
char zahlx[15],zahly[15];
mfy=(ynull-ymouse)/ye; /* x-Wert errechnen */
mfx=(xmouse-xnull)/xe; /* y-Wert errechnen */
sprintf(zahlx,"x= %-11.3e",mfx);
sprintf(zahly,"y= %-11.3e",mfy);
/* Text ausgeben */
Move(rp2,4L,19L);
Text(rp2,(UBYTE *)zahlx,14L);
Move(rp2,4L,30L);
Text(rp2,(UBYTE *)zahly,14L);
}
/*******************************************************************/
/* */
/* added this function cause I have a lott of */
/* messages called in this form */
/* */
/* changed ShowErr on 12.08.1992 */
/* removed AutoRequest() EasyRequest() is much better */
/*******************************************************************/
short ShowErr(short num,BOOL extra)
{
ULONG idcmp=0;
fehler=0; /* clear error number from parser */
if(extra)
es1.es_GadgetFormat=(UBYTE *)"Ok|Cancel";
else
es1.es_GadgetFormat=(UBYTE *)"Ok";
return(EasyRequestArgs(FirstWindow,&es1,&idcmp,&ErrorMessages[num]));
}
/*******************************************************************/
/* */
/* NumIntegrate() Integrates numerical the function f(x) */
/* from xmin to xmax via Simpson Integral */
/* */
/*******************************************************************/
void NumIntegrate(double (*calc)(double))
{
register double f,x1;
double xs;
short n,i;
ULONG MessageClass;
USHORT code,qualifier;
SHORT GadgetID=0;
char str1[60],str2[30],str3[30];
struct Gadget *gad;
extern struct IntuiText IntegralWin5Text,IntegralWin3Text;
SetPointer(FirstWindow,mousemem,16L,16L,0L,0L);
n=(xmax-xmin)/xstep;
if(n&0x01) /* first Version was n%2 25.12.1991 */
n++;
x1=xmin;
xs=(xmax-xmin)/(n>>1); /* double step rate !! */
f=calc(x1);
x1+=xs*0.5; /* the first step to n=1 */
for(i=1;i<n;i+=2)
{
f+=4.0*calc(x1); /* 4 times all not even parts */
x1+=xs;
}
x1=xmin+xs; /* the step to n=2 */
for(i=2;i<n;i+=2)
{
f+=2.0*calc(x1); /* 2 times all even parts */
x1+=xs;
}
f=(f+calc(x1))*(xmax-xmin)/(3.0*n);
sprintf(str1,"Xmin= %s to Xmax= %s",minx,maxx);
printpara((unsigned char *)str2,f);
sprintf(str3,"A= %s",str2);
IntegralWin5Text.IText=(UBYTE *)str3;
IntegralWin3Text.IText=(UBYTE *)str1;
IntegralWin5Text.LeftEdge=200-(IntuiTextLength(&IntegralWin5Text)>>1);
IntegralWin3Text.LeftEdge=200-(IntuiTextLength(&IntegralWin3Text)>>1);
/* first version was lenght/2 25.12.1991 */
NewOKGadget.ng_LeftEdge =155; /* 04.08.1992 */
NewOKGadget.ng_TopEdge =98;
gad=CreateContext((struct Gadget **)&nullgadget);
gad=CreateGadget((ULONG)BUTTON_KIND,gad,&NewOKGadget,
GT_Underscore,(ULONG)'_',TAG_DONE);
ThirdNewWindow.FirstGadget=nullgadget;
ClearPointer(FirstWindow);
MouseCenterWin(&ThirdNewWindow,0,30);
if (!(ThirdWindow = OpenWindow(&ThirdNewWindow)))
ShowErr(9,FALSE);
else
{
rp4=ThirdWindow->RPort;
PrintIText(rp4,&IntegralWin5Text,0L,0L);
GT_RefreshWindow(ThirdWindow,NULL);
FOREVER
{
Wait(1L << ThirdWindow->UserPort->mp_SigBit);
while(message=(struct IntuiMessage *)GT_GetIMsg(ThirdWindow->UserPort))
{
MessageClass=message->Class;
code=message->Code;
qualifier=message->Qualifier;
GT_ReplyIMsg(message);
switch(MessageClass)
{
case IDCMP_REFRESHWINDOW: /*04.08.1992 */
GT_BeginRefresh(ThirdWindow);
PrintIText(rp4,&IntegralWin5Text,0L,0L);
GT_EndRefresh(ThirdWindow,(LONG)TRUE);
break;
case VANILLAKEY:
switch(code)
{
case 'v':
if(!(qualifier&IEQUALIFIER_LCOMMAND))
break;
case 'O':
case 'o':
GadgetID=7;
break;
}
break;
case GADGETUP: /* I've only one Gadget */
GadgetID=7;
break;
default:
break;
}
}
if( GadgetID == 7)
break;
}
CloseWindow(ThirdWindow);
}
if(nullgadget) FreeGadgets(nullgadget);
}
UBYTE WRONGKICKVERSION[]=
{
0,120,25,"Sorry, Kickstart Version greater 37.175 is needed!",0xff,
0,184,55,"Press any mousebutton to continue!",0x00
};
void Kickerror(void) /* 28.07.1992 */
{
if (IntuitionBase = (struct IntuitionBase *)
OpenLibrary((UBYTE *)"intuition.library", 0L))
{
DisplayAlert(0L,WRONGKICKVERSION,70L);
CloseLibrary((struct Library *)IntuitionBase);
}
exit(0);
}
/*******************************************************************/
/* */
/* min_open() will try to open a 640*200 Screen */
/* if OpenScreen() from Open_WINS() fail */
/* 13.08.1992 */
/*******************************************************************/
void min_open(void)
{
static BOOL recursive=0; /* or check 640*200 */
if(AvailMem(MEMF_CHIP|MEMF_LARGEST)<55000L||recursive)
{
if(ShowErr(18,TRUE))
{
extSaveConfig(); /* sorry not able to open any screen */
handlesave();
}
Ende();
}
recursive=TRUE;
scrmode=HIRES_KEY;
scrheight=200;
scrwidth=640;
defscr=0;
setscreenprefs();
NeueP();
Open_WINS();
ShowErr(19,FALSE);
recursive=FALSE;
}