home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************
- * *
- * Filename : DispL2.c *
- * *
- *****************************************************************
- * *
- * Comment : Dieses File unterstützt alle Level 2 welche für *
- * die 2 dimensionale Darstellung benötigt werden. *
- * *
- * Funktionen *
- * ========== *
- * *
- * DispL2() Level 2 der Display Funktion *
- * DispScreen() Bildschirmausgabe *
- * Draw2D() 2D und NIV Funktion *
- * DrawGrid() Zeichnet das komplette Gitter *
- * Draw2DCurves() Zeichnet alle 2D Kurven *
- * DrawGLine() Eine normale Gitterlinie *
- * DrawSLine() Eine Gitterzwischenlinie *
- * Trans2D() Translationsfunktion *
- * CheckClipp() Hilfsfunktion für Clipping *
- * DoClipp() Clippfunktion *
- * InitGraphics() initialisiert die Plotstruktur *
- * GetXSize2D() berechnet verfügbare X Bildgrösse *
- * GetYSize2D() berechnet verfügbare Y Bildgrösse *
- * CalcStep() berechnet die Steps der Graphik. *
- * CalcScale() Berechnet die Skalierung *
- * InitFunction() Initialisiert die Translationsfkt. *
- * *
- * Rev : V1.0 *
- * *
- * History : V1.0 erstellen dieses Files 06/12/89 *
- * *
- * Doc : Plotlibrary User's Guide *
- * *
- * Bugs : keine bekannten *
- * *
- * Autor : Oesch Silvano *
- * *
- * Datum : 06/12/89 *
- * *
- ****************************************************************/
-
- /****************************************************************
- * *
- * allgemeine Includedateien *
- * *
- ****************************************************************/
-
- #include <math.h>
-
- /****************************************************************
- * *
- * Plotlibrary Includedateien *
- * *
- ****************************************************************/
-
- #include "Plot.h"
- #include "PlotL2.h"
- #include "SuppL2.h"
- #include "NivL2.h"
- #include "D3L2.h"
- #include "DispL2.h"
-
- /****************************************************************
- * *
- * Globale statische Variablen *
- * *
- ****************************************************************/
-
- extern DATA (*xexpfct)(), /* 10^ oder e^ bzw. ln oder */
- (*xlogfct)(), /* log Funktion für X-Achse */
- (*yexpfct)(), /* 10^ oder e^ bzw. ln oder */
- (*ylogfct)(), /* log Funktion für Y-Achse */
- (*zexpfct)(), /* 10^ oder e^ bzw. ln oder */
- (*zlogfct)(); /* log Funktion für Z-Achse */
-
- DATA xscale, /* Skalierung aller Achsen */
- yscale,
- zscale;
-
- DATA xoffset, /* Verschiebung aller */
- yoffset, /* Achsen */
- zoffset;
-
- /****************************************************************
- * *
- * externe Variablen *
- * *
- ****************************************************************/
-
- extern struct Plot *plot;
- extern int plerr;
-
- /****************************************************************
- * *
- * Function : displ2() *
- * *
- *****************************************************************
- * *
- * Input : typ,para *
- * int typ Ausgabemodus *
- * int para Graphikparameter *
- * *
- * Output : int returnset allg Rückgabewert *
- * != FALSE alles klar *
- * == FALSE Fehler *
- * *
- *****************************************************************
- * *
- * Comment : Diese Funktion ist Level 2 der Displayroutine. Die *
- * Aufgabe ist die entsprechenden Ausgabefunktionen *
- * mit den notwendigen Parametern aufzurufen. *
- * *
- ****************************************************************/
-
- int displ2(typ,para)
- int typ;
- int para;
- {
-
- int returnset, /* allg Rückgabewert */
- disppara;
-
- plot->col = STARTCOL+1; /* Farbenzähler setzen */
- if (plot->style != NOSTYLE)
- plot->style = NULL; /* Stylezähler setzen */
-
- switch(typ) /* welche Ausgabe */
- {
- case SCREENOUT: /* Bildschirm */
- if (( para < GRAPHNOTSET) or /* kontrolliere Parameter */
- ( para > GRAPHSET))
- { /* nicht in den Grenzen */
- seterror(INVDISPARA); /* Fehler */
- setreturn(FALSE);
- }
- else /* ok */
- {
- initscfunction();
- setreturn(dispscreen(para));
- }
- break;
-
- case SCREENCLOSE: /* Graphik verlassen */
- if (plot->disp == NULL) /* Graphik offen ? */
- { /* Nein Fehler */
- seterror(GRAPHNOTOP);
- setreturn(FALSE);
- }
- else /* Ja */
- {
- initscfunction();
- CloseGraphics(); /* Graphik schliessen */
- setreturn(TRUE);
- }
- break;
-
- case PRINTOUT: /* Matrixdrucker */
- seterror(NOTIMP); /* Leider nicht vorhanden */
- setreturn(FALSE);
- break;
-
- case PLOTOUT: /* Plotter */
- if (plot->pldisp & PLDATASET) /* Plotterdaten vorhanden */
- { /* ja */
- initplfunction(); /* Plotterausgabe */
- disppara = plot->disp; /* speichern von disp */
- plot->disp = NULL; /* und auf 0 setzten */
- setreturn(dispscreen(GRAPHNOTSET));
- if (returnset == TRUE)
- CloseGraphics(); /* schliessen */
- plot->disp = disppara; /* disp zurücksetzen */
- }
- else
- { /* keine Daten */
- seterror(NOPLDATA); /* Fehler */
- setreturn(FALSE);
- }
- break;
- }
- return(returnset); /* und zurück mit Rückgabe */
- }
-
- /****************************************************************
- * *
- * Function : dispscreen() *
- * *
- *****************************************************************
- * *
- * Input : para *
- * *
- * Output : int returnset allg Rückgabewert *
- * != FALSE alles klar *
- * == FALSE Fehler *
- * *
- *****************************************************************
- * *
- * Comment : DispScreen() initialisiert die Graphik und setzt *
- * die benötigten Werte für die Darstellung. Danach *
- * werden die verschiedenen Routinen für 2D, NIV oder *
- * 3D aufgerufen. Wenn die Ausgabe beendigt ist, *
- * werden die alten Werte der Graphikdarstellung *
- * wieder gesetzt. *
- * *
- ****************************************************************/
-
- static int dispscreen(para)
- int para;
- {
-
- int returnset = TRUE; /* allg Rückgabewert */
-
- if (plot->disp == NULL) /* Graphik schon geöffnet ? */
- { /* Nein */
- if (para == GRAPHNOTSET) /* Graphiktyp init. */
- plot->disp |= GRAPHNOTSET;
- else
- plot->disp |= GRAPHSET;
- setreturn(OpenGraphics()); /* Graphik öffnen */
- }
- else if (!(plot->disp & para)) /* alte Graphik gleich wie */
- { /* gewünschte. Nein */
- seterror(GRAPHNOTEQ); /* Fehler */
- return(FALSE);
- }
- if (returnset == FALSE) /* Wenn Fehler, dann alles */
- CloseGraphics(); /* schliessen */
- else
- { /* und sonst weiter im Code */
- getgraphics(); /* alte Werte speichern */
- initgraphics(); /* neue Werte setzten */
-
- /****************************************************************
- * *
- * Zu diesem Zeitpunkt sind alle Graphikwerte initialisiert, die *
- * von allen drei Routinen benötigt werden. Mit dem unteren *
- * switch() werden die verschiedenen Stammfunktionen für die *
- * drei Darstellungsarten aufgerufen. *
- * *
- ****************************************************************/
-
- switch(plot->typ)
- {
- case D2: /* 2D Darstellung */
- case NIV: /* Niveau Darstellung */
- setreturn(draw2d());
- break;
- case D3: /* 3D Darstellung */
- setreturn(draw3d());
- break;
- }
- resetgraphics(); /* alte Werte setzten */
- }
- return(returnset);
- }
-
- /****************************************************************
- * *
- * Function : draw2d() *
- * *
- *****************************************************************
- * *
- * Input : void *
- * *
- * Output : int returnset allg Rückgabewert *
- * != FALSE alles klar *
- * == FALSE Fehler *
- * *
- *****************************************************************
- * *
- * Comment : Das ist die Hauptfunktion der 2D Darstellung. Sie *
- * ruft die spez. 2D Funktionen auf. Die Niveaukurven *
- * werden auch hier behandelt. Einzig das zeichnen *
- * der Kurven und die Kurvenbeschriftung ist anders *
- * als jene der 2D Darstellung. *
- * *
- ****************************************************************/
-
- static int draw2d()
- {
- int returnset; /* all. Rückgabewert */
-
- getxsize2d(); /* verfügbare Zeichengrösse */
- getysize2d(); /* verfügbare Zeichengrösse */
- initfunction(); /* log Funktionen init. */
- calcstep(&plot->xmin,plot->xmes); /* X-Step berechnen */
- calcstep(&plot->ymin,plot->ymes); /* Y-Step berechnen */
- calcscale(); /* Skalierung berechen */
- drawgrid(); /* Gitter zeichnen */
- if (plot->typ == D2) /* Wenn 2D */
- setreturn(draw2dcurves()); /* 2D Kurven zeichnen */
- else /* sonst */
- setreturn(drawnivcurves()); /* Niveau Kurven zeichenen */
- return(returnset);
- }
-
- /****************************************************************
- * *
- * Function : drawgrid() *
- * *
- *****************************************************************
- * *
- * Input : void *
- * *
- * Output : void *
- * *
- *****************************************************************
- * *
- * Comment : DrawGrid() zeichnet das Gitter auf den Bildschirm *
- * für die 2 dimensionale Darstellung. *
- * *
- ****************************************************************/
-
- void drawgrid()
- {
- int i,j,k,slen,len,htsize;
-
- char sbuf[] = " ";
-
- ClearGraphics(); /* Bildschirm löschen */
-
- /****************************************************************
- * *
- * Konvertiere die Gittergrenzen neu, es kann einen Fehler von *
- * +- 1 Pixel geben. *
- * *
- ****************************************************************/
-
- trans2d(&plot->xgridmin,&plot->ygridmax,
- &plot->xpic1,&plot->ypic1);
- trans2d(&plot->xgridmax,&plot->ygridmin,
- &plot->xpic2,&plot->ypic2);
-
- drawxaxis();
- len = drawyaxis();
-
- /****************************************************************
- * *
- * Und jetzt noch der Rahmen um das Gitter. *
- * *
- ****************************************************************/
-
- SetLineStyle(SOL_LINE);
- DrawRectangle(plot->xpic1,plot->ypic1,plot->xpic2,plot->ypic2);
-
- /****************************************************************
- * *
- * Und nun die Beschriftung welche gegeben wurde. Gleichzeitig *
- * wird die globale Variable plot->cpt für den Start der *
- * Kurvenbeschriftung initialisiert. *
- * *
- ****************************************************************/
-
- plot->cpt = plot->ypic2+plot->xle;
- /* Start Namen oder Einheit */
-
- if (plot->titel) /* Titel der Graphik */
- printtextabs(plot->titel,
- (plot->xpic1+plot->xpic2)/2,
- plot->ypic1-plot->yle,T_CX|T_B);
-
- if (plot->xname) /* X-Achsenname */
- printtextabs(plot->xname,
- (plot->xpic2+plot->xpic1)/2,
- plot->cpt,T_CX|T_T);
-
- if (plot->xunit) /* X-Achseneinheit */
- printtextabs(plot->xunit,
- plot->xpic2,
- plot->cpt,T_L|T_T);
-
- if ((plot->xname) or /* Wenn Name oder Einheit */
- (plot->xunit))
- plot->cpt += plot->ylt; /* 1 Zeile tiefer */
-
- if (plot->yname) /* Y-Achsenname */
- {
- slen = strlen(plot->yname); /* Länge des Namens */
- len ++; /* Abstand zur Y-Achse */
- htsize = 5*plot->ytext/4;
- j = (plot->ypic2+plot->ypic1-(slen-1)*htsize)/2;
- k = plot->xpic1-len*plot->xtext;
- for (i=0;i<slen;i++) /* jedes Zeichen ausgeben */
- {
- sbuf[0] = plot->yname[i];
- printtextabs( sbuf,
- k,
- j+i*htsize,
- T_L|T_CY);
- }
- }
-
- if (plot->yunit) /* Y-Achseneinheit */
- printtextabs(plot->yunit,
- plot->xpic1,
- plot->ypic1-plot->yle,
- T_L|T_B);
-
- if (plot->typ == NIV) /* Nur für Niveau */
- {
- if (plot->zname) /* Z-Achsenname */
- printtextabs(plot->zname,
- (plot->xpic2+plot->xpic1)/2,
- plot->ysize-plot->yht,T_CX|T_B);
-
- if (plot->zunit) /* Z-Achseneinheit */
- printtextabs(plot->zunit,
- plot->xpic2,
- plot->ysize-plot->yht,T_L|T_B);
-
- }
- }
-
- /****************************************************************
- * *
- * Function : draw2dcurves() *
- * *
- *****************************************************************
- * *
- * Input : void *
- * *
- * Output : int returnset allg Rückgabewert *
- * != FALSE alles klar *
- * == FALSE Fehler *
- * *
- *****************************************************************
- * *
- * Comment : Draw2DCurves() zeichnet und beschriftet alle *
- * geladenen 2D Kurven. Die Farbwahl welche für jede *
- * Kurve gegeben werden konnte, übersteuert den *
- * automatischen Farbenzähler. *
- * Wenn die Daten geclippt werden müssen, so wird *
- * dies ebenfalls gemacht. Boola ist in Indikator- *
- * array für die Zuweisung des Startpunktes. *
- * *
- ****************************************************************/
-
- static int draw2dcurves()
- {
- register GPT *iarray,*iarray2; /* Integerarray */
-
- GPT *iarray1; /* Speicher */
-
- int xs,ys, /* Startkoordinaten */
- xe,ye, /* Endkoordinaten */
- xe1,ye1, /* Endkoordinaten */
- count, /* Schleifenzähler */
- ptc, /* Punktezähler */
- tris2, /* Translation Rückgabe */
- center, /* X-Achsen Zentrum */
- returnset = TRUE, /* allg Rückgabewert */
- boola, /* Booleanarray */
- bool = FALSE; /* Ind. für Kurvenbeschr. */
-
- struct Curve *curve; /* Kurvenzeiger */
-
- DATA *array, /* Datenzeiger */
- *x2,*y2;
-
- center = (plot->xpic2-plot->xpic1)/2;
- /* Berechne Mittelpunkt */
- curve = plot->first; /* erste Kurve holen */
- while (curve != NULL) /* solange Daten vorhanden */
- {
- calccolor(curve->color); /* welche Farbe ist dran ? */
- array = curve->val; /* init. Datenpointer */
- iarray = malloc((curve->count+2)*valsize()*sizeof(GPT));
- if (iarray == NULL) /* speicher bekommen */
- { /* Nein */
- seterror(GRAPHMEM); /* Fehler setzten und */
- setreturn(FALSE); /* zurück nächste */
- break; /* Kurve zeichnen */
- }
- iarray1 = iarray; /* Startwerte zuweisen */
- iarray2 = iarray;
- boola = FALSE; /* zuweisen des ersten */
- for (count = 0;count<curve->count;count++)
- { /* alle Daten nehmen */
- x2 = array++; /* Endpunkt zuweisen */
- y2 = array++; /* und transformieren */
- tris2 = trans2d(x2,y2,&xe,&ye);
- if (tris2 == TRUE) /* Fehler beim trans. */
- { /* Nein alles klar */
- if (boola & PTCSET) /* Startpunkt schon gesetzt */
- if (plot->clipp == CLIPP) /* müssen wir clippen */
- { /* Ja */
-
- /****************************************************************
- * *
- * Die Clipping Routine liefert nur dann einen Status von NULL, *
- * wenn die Linie gezeichnet werden muss. Ansonsten ist dieser *
- * ungleich NULL. *
- * *
- ****************************************************************/
-
- xe1 = xe; /* Für clippen */
- ye1 = ye;
- if (!(doclipp(&xs,&ys,&xe1,&ye1)))
- {
- if ((iarray2[0] == xs) and (iarray2[1] == ys))
- {
- if (!(boola & PTCINS))
- { /* Startwert setzten */
- *iarray++ = xs; /* Koordinate einsetzten */
- *iarray++ = ys;
- boola |= PTCINS; /* Flag setzten */
- }
- *iarray++ = xe1; /* Endpunkt setzten */
- *iarray++ = ye1;
- iarray2 += 2; /* Zeiger erhöhen */
- }
- else
- {
- if (boola & PTCINS) /* Nur wenn Daten */
- { /* Kurve zeichnen */
- ptc = (iarray - iarray1)/valsize();
- DrawPolyLine(ptc,iarray1);
- }
- iarray = iarray1; /* alle Pointer zurück- */
- *iarray++ = xs; /* setzten und die erste */
- *iarray++ = ys; /* Linie einsetzten */
- *iarray++ = xe1;
- *iarray++ = ye1;
- iarray2 = iarray1+2;
- xe = xe1; /* Für clipp */
- ye = ye1; /* Flag setzten */
- boola = PTCINS|PTCSET;
- }
- }
- }
- else /* kein Clipping, Punkte */
- { /* setzten */
- if (!(boola & PTCINS)) /* Start schon gesetzt ? */
- { /* Nein */
- *iarray++ = xs; /* Startkoordinaten setzten */
- *iarray++ = ys;
- boola |= PTCINS; /* Flag setzten */
- }
- *iarray++ = xe; /* nächster Punkt setzen */
- *iarray++ = ye;
- }
- xs = xe; /* Endpunkt wird zum Start- */
- ys = ye; /* punkt. Zeige das gemacht */
- boola |= PTCSET; /* mit PTCSET */
- }
- else /* Ja Fehler */
- {
- if (boola & PTCINS) /* Startwert gesetzt ? */
- { /* Ja, dann zeichne Kurve */
- ptc = (iarray - iarray1)/valsize();
- DrawPolyLine(ptc,iarray1);
- }
- iarray = iarray1; /* Startarray zuweisen */
- boola = FALSE; /* und neue Kurve beginnen */
- }
- } /* alle Daten berechnet */
-
- if (boola & PTCINS) /* noch Kurven vorhanden */
- { /* Ja */
- ptc = (iarray - iarray1)/valsize();
- DrawPolyLine(ptc,iarray1); /* zeichnen */
- }
- free(iarray1); /* Speicher zurückgeben */
-
- if (curve->titel) /* Hat die Kurve einen */
- { /* Namen ? */
- /* Zeichne Linie vor Name */
- DrawLine( plot->xpic1+bool*center,
- plot->cpt+plot->ytext,
- plot->xpic1+CURLSIZE+bool*center,
- plot->cpt+plot->ytext);
- SetFgColor(TEXTCOL); /* für Text */
- printtextabs( curve->titel, /* und schreibe Namen */
- plot->xpic1+CURLSIZE+bool*center,
- plot->cpt,
- T_R|T_T);
- bool ^= 1; /* nächste andere Stelle */
- if (!(bool)) /* Wenn Bool NULL, dann */
- plot->cpt += plot->ylt; /* haben wir 2 Kurven */
- } /* beschriftet */
- curve = curve->next; /* neuer Kurvenzeiger */
- }
- return(returnset);
- }
-
- /****************************************************************
- * *
- * Function : drawgline() *
- * *
- *****************************************************************
- * *
- * Input : void *
- * *
- * Output : void *
- * *
- *****************************************************************
- * *
- * Comment : DrawGridline zeichnet eine Gerade anhand des *
- * eingestellten Gitterwertes. Wenn dieser *
- * GRID ist, so wird eine lange punktierte *
- * Linie gezeichnet. Wenn er NOGRID ist, *
- * dann werden zwei kurze volle Geraden gezeichnet. *
- * *
- ****************************************************************/
-
- void drawgline(xs,ys,xe,ye)
- DATA *xs,*ys,*xe,*ye;
- {
- int xsn,ysn,xen,yen, /* trans. Werte */
- step; /* Länge der kurzen Geraden */
-
- trans2d(xs,ys,&xsn,&ysn); /* Werte transformieren */
- trans2d(xe,ye,&xen,¥);
-
- if (plot->grid == GRID) /* Gitter zeichnen ? */
- { /* Ja */
- SetLineStyle(DOT_LINE); /* Punktierte Linie */
- DrawLine(xsn,ysn,xen,yen); /* und zeichnen */
- }
- else /* keine Gitter */
- {
- SetLineStyle(SOL_LINE); /* volle Linie */
- if (xsn == xen) /* X-Achse ? */
- { /* Ja */
- step = (yen-ysn)/GRIDLSIZE; /* Länge der Linien */
- /* und zeichnen */
- DrawLine(xsn,ysn,xen,ysn+step);
- DrawLine(xsn,yen-step,xen,yen);
- }
- else /* also Y-Achse */
- {
- step = (xen-xsn)/GRIDLSIZE; /* Länge der Linien */
- /* und zeichnen */
- DrawLine(xsn,ysn,xsn+step,yen);
- DrawLine(xen-step,ysn,xen,yen);
- }
- }
- }
-
- /****************************************************************
- * *
- * Function : drawsline() *
- * *
- *****************************************************************
- * *
- * Input : void *
- * *
- * Output : void *
- * *
- *****************************************************************
- * *
- * Comment : Diese Funktion zeichnet die Linien zwischen zwei *
- * Steps. Es wurde bewusst auf die Integration dieser *
- * Funktion in die von DrawGridLine() verzichtet, da *
- * sonst zuviele Parameter übergeben werden müssten *
- * und die Funktion zu langsam wird. *
- * *
- ****************************************************************/
-
- void drawsline(xs,ys,xe,ye)
- DATA *xs,*ys,*xe,*ye;
- {
- int xsn,ysn,xen,yen,step;
-
- trans2d(xs,ys,&xsn,&ysn); /* Werte transformieren */
- trans2d(xe,ye,&xen,¥);
-
- SetLineStyle(SOL_LINE); /* volle Linie */
- if (xsn == xen) /* X-Achse ? */
- {
- step = (yen-ysn)/STEPLSIZE; /* Länge der Linien */
- DrawLine(xsn,ysn,xen,ysn+step); /* und zeichnen */
- DrawLine(xsn,yen-step,xen,yen);
- }
- else /* also Y-Achse */
- {
- step = (xen-xsn)/STEPLSIZE; /* Länge der Linien */
- DrawLine(xsn,ysn,xsn+step,yen); /* und zeichen */
- DrawLine(xen-step,ysn,xen,yen);
- }
- }
-
- /****************************************************************
- * *
- * Function : trans2d() *
- * *
- *****************************************************************
- * *
- * Input : xo,yo,xn,yn *
- * DATA *xo transformierender X-Wert *
- * *yo transformierender Y-Wert *
- * int *xn transformierter X-Wert *
- * *yn transformierter Y-Wert *
- * *
- * Output : returnset Rüchgabewert *
- * int returnset *
- * == TRUE gültige Transformation *
- * & XTRANS ungültige X Transformation *
- * & YTRANS ungültige Y Transformation *
- * *
- *****************************************************************
- * *
- * Comment : Diese Funktion transformiert ein Koordinatenpaar *
- * auf die Bildschirmkoordinaten. Die math. *
- * Beschreibung dieser Funktion ist in der Diplom- *
- * arbeit zu finden. *
- * *
- ****************************************************************/
-
- int trans2d(xo,yo,xn,yn)
- DATA *xo,
- *yo;
- int *xn,
- *yn;
- {
- int returnset = TRUE; /* allg Rückgabewert */
-
- if (plot->xmes == LIN) /* lineare Transformation */
- *xn = (int)(xscale*((*xo)-xoffset))+plot->xpic1;
- else /* log. Transformation */
- if (*xo > 0.0) /* bereichscheck */
- *xn = (int)(xscale*(xlogfct(*xo)-xoffset))+plot->xpic1;
- else
- returnset |=XTRANS;
-
- if (plot->ymes == LIN) /* lineare Transformation */
- *yn = (int)(yscale*(*yo-yoffset))+plot->ypic2;
- else /* log. Transformation */
- if (*yo > 0.0) /* bereichscheck */
- *yn = (int)(yscale*(ylogfct(*yo)-yoffset))+plot->ypic2;
- else
- returnset |= YTRANS;
-
- return(returnset); /* und zurück */
- }
-
- /****************************************************************
- * *
- * Function : checkclipp() *
- * *
- *****************************************************************
- * *
- * Input : x,y,c *
- * int x x Koordinate *
- * int y y Koordinate *
- * char *c Status *
- * *
- * Output : void *
- * *
- *****************************************************************
- * *
- * Comment : Diese Funktion kontrolliert die Koordinaten *
- * mittels der Bildgrenzen auf ihre Lage. Der *
- * Status wird mit den folgenden defines gesetzt. *
- * *
- * C_L -> Lage links von Bildgrenze *
- * C_R -> Lage rechts von Bildgrenze *
- * C_T -> Lage über von Bildgrenze *
- * C_B -> Lage unter von Bildgrenze *
- * *
- * Wenn das Clipping eingeschaltet ist, wird *
- * mindestens diese Funktion aufgerufen und durch- *
- * geführt. *
- * *
- ****************************************************************/
-
- static void checkclipp(x,y,c)
- int x;
- int y;
- char *c;
- {
- *c=0; /* status initialisieren */
- if (x<plot->xpic1) /* links von min ? */
- *c |= C_L; /* Ja */
- else if (x>plot->xpic2) /* Nein, rechts von max */
- *c |= C_R; /* Ja */
-
- if (y<plot->ypic1) /* unterhalb von min ? */
- *c |= C_T; /* Ja */
- else if (y>plot->ypic2) /* Nein, oberhalb von max */
- *c |= C_B; /* Ja */
- }
-
- /****************************************************************
- * *
- * Function : doclipp() *
- * *
- *****************************************************************
- * *
- * Input : x1,y1,x2,y2 *
- * int *x1 x Start *
- * int *y1 y Start *
- * int *x2 x Ende *
- * int *y2 y Ende *
- * *
- * Output : char Status *
- * != 0 trivial reject *
- * == 0 Draw *
- * *
- *****************************************************************
- * *
- * Comment : Der Cohen-Sutherland Clipping Algorithmus welcher *
- * hier verwendet wird, liefert einen Status über *
- * das Zeichnen der Linie. Wenn dieser Status == 0 *
- * ist, kann die Linie gezeichnet werden. *
- * Eine nähere Beschreibung dieses Algorithums *
- * befindet sich in der Diplomarbeit. *
- * *
- ****************************************************************/
-
- char doclipp(x1,y1,x2,y2)
- int *x1;
- int *y1;
- int *x2;
- int *y2;
- {
- int x,y, /* geclippte Koordinaten */
- h; /* Höhe */
- char c1,c2,c; /* Status Variablen */
-
- checkclipp(*x1,*y1,&c1); /* Kontrolliere Startpunkt */
- checkclipp(*x2,*y2,&c2); /* kontrolliere Endpunkt */
-
- /****************************************************************
- * *
- * Der folgende Vergleich bestimmt das Clipping. *
- * *
- * ((c1!=0) || (c2!=0)) Wenn c1 == 0 und c2 == 0 dann trivial *
- * accept also die Linie liegt vollständig im Fenster. *
- * *
- * ((c1 & c2)!=0) Wenn beide Statusvariablen gleich sind spricht *
- * man von trivial reject. *
- * *
- * Wenn eine dieser Bedingungen erfüllt ist, dann muss keine *
- * Berechnung durchgeführt werden. Der Status wird entsprechend *
- * gesetzt. *
- * *
- ****************************************************************/
-
- while(((c1!=0) || (c2!=0)) && ((c1 & c2)==0))
- {
- if (c1) /* Startpunkt clippen */
- c=c1; /* dann Status zuweisen */
- else /* sonst */
- c=c2; /* Endpunkt zuweisen */
-
- if (c & C_L) /* Punkt links ? */
- { /* Ja */
- x=plot->xpic1; /* x gleich minpic */
- h=(int)(1.0*(*y2-*y1)*(x-*x1)/(*x2-*x1));
- y= *y1+h; /* berechnete höhe + y1 */
- }
- else if (c & C_R) /* Punkt rechts ? */
- { /* Ja */
- x=plot->xpic2; /* x gleich maxpic */
- h=(int)(1.0*(*y2-*y1)*(x-*x1)/(*x2-*x1));
- y= *y1+h; /* berechnete höhe + y1 */
- }
- else if (c & C_T) /* Punkt oben ? */
- { /* Ja */
- y=plot->ypic1; /* y gleich minpic */
- h=(int)(1.0*(*x2-*x1)*(y- *y1)/(*y2- *y1));
- x= *x1+h; /* berechnete höhe + x1 */
- }
- else if (c & C_B) /* Punkt unten ? */
- { /* Ja */
- y=plot->ypic2; /* y gleich maxpic */
- h=(int)(1.0*(*x2-*x1)*(y- *y1)/(*y2- *y1));
- x= *x1+h; /* berechnete höhe + x1 */
- }
-
- if (c==c1) /* Startpunkt bearbeitet ? */
- { /* Ja */
- *x1=x; /* geclippte Werte zu- */
- *y1=y; /* weisen */
- checkclipp(x,y,&c1); /* und kontrollieren */
- }
- else /* also Endpunkt */
- {
- *x2=x; /* geclippte Werte zu- */
- *y2=y; /* weisen */
- checkclipp(x,y,&c2); /* und kontrollieren */
- }
- }
- return(c1); /* zurück mit Status */
- }
-
- /****************************************************************
- * *
- * Function : initgraphics() *
- * *
- *****************************************************************
- * *
- * Input : void *
- * *
- * Output : void *
- * *
- *****************************************************************
- * *
- * Comment : Diese Funktion initialisiert die Plotstruktur mit *
- * den verfügbaren Graphikwerten. *
- * Die folgenden Werte werden gestzt: *
- * *
- * xsize -> max. horizontale beschreibbare *
- * Bildkoordinate *
- * ysize -> max. vertikale beschreibbare *
- * Bildkoordinate *
- * maxcol -> max. setztbares Farbregister *
- * xtext -> Breite einse Zeichens *
- * ytext -> Höhe eines Zeichens *
- * *
- * xht -> Halbe Zeichenlänge *
- * xlt -> 1 vertikale Zeile *
- * *
- * Diese Werte sind die Grundlage für die späteren *
- * berechnungen. Dies Routine muss vor jedem Bild- *
- * schirmaufbau aufgerufen werden. *
- * *
- ****************************************************************/
-
- static void initgraphics()
- {
- SetTextSize(); /* setzte Text */
-
- plot->xsize = GetMaxX(); /* max horix. Bildgrösse */
- plot->ysize = GetMaxY(); /* max vert. Bildgrösse */
-
- plot->maxcol = GetMaxColor(); /* max Farbenanzahl */
- plot->xtext = GetTextSize(XSIZE); /* Textgrösse holen */
- plot->ytext = GetTextSize(YSIZE);
-
- plot->xht = plot->xtext/2; /* Halber Text */
- plot->xlt = 3*plot->xtext/2; /* Eine Zeile */
-
-
- plot->yht = plot->ytext/2; /* halbe Texthöhe */
- plot->ylt = 3*plot->ytext/2; /* mormale Zeilenhöhe */
-
- if (plot->xmes == LIN)
- plot->xle = plot->ylt; /* exp. Zeilenhöhe */
- else
- plot->xle = 2*plot->ytext; /* exp. Zeilenhöhe */
-
- if (plot->ymes == LIN)
- plot->yle = plot->ylt; /* exp. Zeilenhöhe */
- else
- plot->yle = 2*plot->ytext; /* exp. Zeilenhöhe */
-
- SetFgColor(TEXTCOL); /* setzte Stift */
- SetBackColor(BACKCOL); /* setzte Hintergrund */
- }
-
- /****************************************************************
- * *
- * Function : getxsize2d() *
- * *
- *****************************************************************
- * *
- * Input : void *
- * *
- * Output : void *
- * *
- *****************************************************************
- * *
- * Comment : Berechnet die verfügbare Bildgrösse für die *
- * X Bildkoordinatenachse. *
- * Die einzelnen Abstände zwichen den verschiedenen *
- * Zeichen ist immer 1/2*xtext. *
- * Für die Berechnung werden die Variablen *
- * plot->xht und plot->xlt verwendet, welche in *
- * der Routine InitGrahpics initialisiert werden. *
- * *
- ****************************************************************/
-
- void getxsize2d()
- {
-
- plot->xpic1 = plot->xht; /* Startwert */
- plot->xpic2 = plot->xsize-plot->xht;
- /* Endwert */
- if (plot->yname) /* Nur wenn Name gegeben */
- plot->xpic1 += plot->xlt; /* Bild verkleinern */
-
- /****************************************************************
- * *
- * Für die Beschriftung der X-Achse *
- * *
- ****************************************************************/
-
- plot->xpic1 += VALSIZE*plot->xtext+plot->xht;
- if (plot->typ != D3)
- plot->xpic2 -= VALSIZE/2*plot->xtext;
- else
- plot->xpic2 -= VALSIZE*plot->xtext;
-
- }
-
- /****************************************************************
- * *
- * Function : getysize2d() *
- * *
- *****************************************************************
- * *
- * Input : void *
- * *
- * Output : void *
- * *
- *****************************************************************
- * *
- * Comment : Berechnet die verfügbare Bildgrösse für die *
- * Y Bildkoordinatenachse. *
- * Die einzelnen Abstände zwichen den verschiedenen *
- * Zeichen ist immer 1/2*xtext. *
- * Für die Berechnung werden die Variablen *
- * plot->yht, plot->ylt und plot->yle verwendet, *
- * welche in der Routine InitGrahpics initialisiert *
- * werden. *
- * *
- ****************************************************************/
-
- void getysize2d()
- {
-
- int titelcount = NULL, /* Anzahl Kurvennamen */
- niveau, /* Anzahl verschiedener */
- /* Niveaus */
- lines, /* Zeilengrösse */
- line; /* Anzahl benötigte Zeilen */
-
- struct Curve *curve; /* Kurvenzeiger */
-
- plot->ypic1 = NULL; /* Startwert */
- plot->ypic2 = plot->ysize-plot->yht;
- /* Endwert */
-
- if ((plot->titel) or /* Titel oder Einheit */
- (plot->yunit)) /* gesetzt eine Zeile */
- plot->ypic1 += plot->ylt; /* weniger */
-
- plot->ypic2 -= plot->xle; /* Beschriftung X-Achse */
-
- plot->ypic1 += plot->yle; /* Beschriftung Y-Achse */
-
- if (plot->typ != D3)
- {
- if ((plot->xname) or /* Name oder Einheit */
- (plot->xunit)) /* gesetzt eine Zeile */
- plot->ypic2 -= plot->ylt; /* weniger */
- }
-
- if (plot->typ != NIV) /* Wenn 2D dann alle Namen */
- { /* der Kurven zählen */
- curve = plot->first;
- while (curve != NULL)
- {
- if (curve->titel)
- titelcount ++;
- curve = curve->next;
- } /* 2 Titel auf 1 Zeile */
- plot->ypic2 -= ++titelcount/2*plot->ylt;
- }
- else
- { /* Ja */
- niveau = checkniv(); /* hole verschiedene Werte */
- lines = (plot->xpic2-plot->xpic1)/(plot->xtext*(RECTSIZE));
- line = niveau/lines; /* Anzahl Zeilen */
- if (niveau%lines != NULL) /* Nur wenn Rest eine mehr */
- line++;
- plot->ypic2 -= line*2*plot->ytext;
- /* Für jede Linie 2 Zeilen */
- if ((plot->zname) or /* Name oder Einheit */
- (plot->zunit)) /* gesetzt eine Zeile */
- plot->ypic2 -= plot->ylt; /* weniger */
- }
- }
-
- /****************************************************************
- * *
- * Function : calcstep() *
- * *
- *****************************************************************
- * *
- * Input : min,mes *
- * DATA *min Adr. der Daten *
- * int mes Masstab *
- * *
- * Output : void *
- * *
- *****************************************************************
- * *
- * Comment : Berechnet die Schrittweite der Graphik für alle *
- * Masstäbe. Die verschiedenen Berechnungen werden *
- * nachfolgend erklärt. *
- * *
- * LIN : Die Schrittweite wird berechnet mit der *
- * max. Schritten. Damit es jedoch nicht *
- * willkürliche Schritte sind, wird aus einer *
- * Tabelle der nächste Schritt gesucht. *
- * Mit diesem neuen Schritt werden die Grenz- *
- * werte der Graphik gesetzt. Als kleines *
- * Detail ist der Ursprung. Wenn dieser in den *
- * Grenzen enthalten ist, muss dieser auf *
- * Schritt fallen. *
- * *
- * LOG : Bei der logarithmischen Darstellung werden *
- * nur ganze Dekaden gezeichnet und *
- * beschriftet. Da die Beschriftung wesentlich *
- * kürzer ist als jene der linearen *
- * Darstellung, wird hier ohne max. Schritt *
- * gerechnet. *
- * *
- * LN : Bei dieser Darstellung gelten die gleichen *
- * Voraussetzungen wie bei der LOG. *
- * *
- ****************************************************************/
-
- void calcstep(min,mes)
- DATA *min;
- int mes;
- {
-
- DATA steptable[STEPVAL] = /* definierte Schritte bei */
- { /* der linearen Darstellung */
- 1.0,1.25,1.5,2.0,2.5,3.0,
- 4.0,5.0,6.0,7.5,8.0,10.0
- };
-
- DATA *max, /* maximaler Wert */
- *plotstep, /* Graphikstep */
- *gridmin, /* min. Graphikwert */
- *gridmax, /* max. Graphikwert */
- step, /* prov. step */
- valexp; /* Exponent */
-
- int i; /* Schleifenzähler */
-
- max = min+1; /* Zuweisen der Adressen */
- plotstep = min+2;
- gridmin = min+3;
- gridmax = min+4;
-
- switch(mes) /* Je nach Masstab */
- {
- case LIN: /* Linear */
- step = (*max-*min)/STEPNBR; /* prov. Step berechnen */
- valexp = pow(10.0,getexp(step));
- /* berechen Dekadenwert */
-
- /****************************************************************
- * *
- * Suche den Schrittwert welcher grösser als der prov. *
- * berechnete ist. Mit dieser Methode unterscheiden sind die *
- * Anzahl der Schritte nur um +-1 von STEPNBR. *
- * *
- ****************************************************************/
-
- for (i=0;i<=STEPVAL;i++)
- if (step <= steptable[i]*valexp)
- {
- step = steptable[i]*valexp;
- break;
- }
- *plotstep = step; /* Zuweisen der Werte */
- *gridmin = floor((*min)/step)*step;
- *gridmax = ceil((*max)/step)*step;
- break;
-
- case LOG:
- valexp = getexp(*min); /* mit welcher Dekade min */
- *gridmin = pow(10.0,valexp); /* min Wert zuweisen */
- valexp = getexp(*max); /* in welcher Dekade max */
- *gridmax = pow(10.0,valexp); /* max Wert zuweisen */
- if (*gridmax < *max) /* evt. 1 Dekade höher */
- *gridmax = pow(10.0,valexp+1);
- break;
-
- case LN:
- valexp = getexpe(*min); /* mit welcher Dekade min */
- *gridmin = exp(valexp); /* min Wert zuweisen */
- valexp = getexpe(*max); /* in welcher Dekade max */
- *gridmax = exp(valexp); /* max Wert zuweisen */
- if (*gridmax < *max) /* evt. 1 Dekade höher */
- *gridmax = exp(valexp+1);
- break;
- }
- }
-
- /****************************************************************
- * *
- * Function : initfunction() *
- * *
- *****************************************************************
- * *
- * Input : void *
- * *
- * Output : void *
- * *
- *****************************************************************
- * *
- * Comment : Diese Funktion initialisiert die nicht linearen *
- * Skalierungsfunktionen. Die globalen Funktions- *
- * zeiger können dann jederzeit aufgerufen werden. *
- * *
- * xlogfct -> Skalierungsfunktion für X-Achse *
- * xexpfct -> Umkehrung der Skalierung *
- * ylogfct -> Skalierungsfunktion für Y-Achse *
- * yexpfct -> Umkehrung der Skalierung *
- * zlogfct -> Skalierungsfunktion für Z-Achse *
- * zexpfct -> Umkehrung der Skalierung *
- * *
- * Diese Funktionen erleichtern das Skalieren der *
- * einzelnen Werte sehr stark. *
- * *
- ****************************************************************/
-
- void initfunction()
- {
- if (plot->xmes != LIN) /* lineare X-Achse ? */
- if (plot->xmes == LOG) /* Nein, ev. log ? */
- { /* Ja */
- xlogfct = log10; /* Also log Funktionen */
- xexpfct = exp10; /* zuweisen */
- }
- else /* kann nur ln sein */
- {
- xlogfct = log; /* Dann halt diese Funktion */
- xexpfct = exp; /* zuweisen */
- }
-
- if (plot->ymes != LIN) /* lineare Y-Achse ? */
- if (plot->ymes == LOG) /* Nein, ev. log ? */
- { /* Ja */
- ylogfct = log10; /* Also log Funktionen */
- yexpfct = exp10; /* zuweisen */
- }
- else /* kann nur ln sein */
- {
- ylogfct = log; /* Dann halt diese Funktion */
- yexpfct = exp; /* zuweisen */
- }
-
- if ((plot->typ == D3) and /* Nur wenn 3d und nicht */
- (plot->zmes != LIN)) /* lineare Z-Achse ? */
- if (plot->zmes == LOG) /* Nein, ev. log ? */
- { /* Ja */
- zlogfct = log10; /* Also log Funktionen */
- zexpfct = exp10; /* zuweisen */
- }
- else /* kann nur ln sein */
- {
- zlogfct = log; /* Dann halt diese Funktion */
- zexpfct = exp; /* zuweisen */
- }
- }
-
- /****************************************************************
- * *
- * Function : calcscale() *
- * *
- *****************************************************************
- * *
- * Input : void *
- * *
- * Output : void *
- * *
- *****************************************************************
- * *
- * Comment : CalcScale berechnet die automatische Skalierung *
- * für alle 2D und Niveau Darstellungen auf dem *
- * Bildschirm. Diese Funktion ist nicht mit der *
- * CalcStep Funktion zu verwechseln welche die *
- * virtuelle Grösse des Bildschirmes berechnet. *
- * Diese Funktion berechnet nun die Werte für die *
- * Transformationsmatrix. Es wird der max. verfügbare *
- * Pixelbereich dividiert durch die Grösse des *
- * Gitters. Dadurch erhalten wir für jeden Pixel *
- * einen bestimmten virtuellen Wert. *
- * *
- ****************************************************************/
-
- void calcscale()
- {
- int picrange; /* verfügbarer Bildschirm */
-
- picrange = plot->xpic2-plot->xpic1;
- /* x Range */
- if (plot->xmes == LIN) /* LIN anders berechnen */
- {
- xoffset = plot->xgridmin; /* Start init. für trans2d */
- xscale = picrange/(plot->xgridmax-xoffset);
- /* Skalierung berechnen */
- }
- else /* LOG oder LN */
- { /* dieselbe Berechnung aber */
- /* über LOG() oder LN() */
- xoffset = xlogfct(plot->xgridmin);
- xscale = picrange/(xlogfct(plot->xgridmax)-xoffset);
- }
-
- picrange = plot->ypic2-plot->ypic1;
- /* y Range */
- if (plot->ymes == LIN) /* LIN anders berechnen */
- {
- yoffset = plot->ygridmin; /* Start init. für trans2d */
- yscale = -picrange/(plot->ygridmax-yoffset);
- /* Skalierung berechnen */
- }
- else
- { /* LOG oder LN */
- /* dieselbe Berechnung aber */
- /* über LOG() oder LN() */
- yoffset = ylogfct(plot->ygridmin);
- yscale = -picrange/(ylogfct(plot->ygridmax)-yoffset);
- }
- }
-
-