home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_progs / libs / plotlib.lha / Plot_1.lzh / Source / D3L2.c next >
Encoding:
C/C++ Source or Header  |  1990-02-21  |  46.8 KB  |  1,238 lines

  1. /****************************************************************
  2. *                                                                                                                                *
  3. *     Filename : D3L2.c                                                                                        *
  4. *                                                                                                                                *
  5. *****************************************************************
  6. *                                                                                                                                *
  7. *        Comment : Dieses File unterstützt alle Level 2 Funktionen        *
  8. *                            welche für die 3 dimensionale Darstellung                    *
  9. *                            benötigt werden.                                                                    *
  10. *                                                                                                                                *
  11. *                                Funktionen                                                        *
  12. *                            ==========                                                        *
  13. *                                                                                                                                *
  14. *            ClearCidden()                löscht Hiddentabelle                                    *
  15. *            InitHidden()                alloziert Hiddentabelle                                *
  16. *            FreeHidden()                gibt Speicher von Hiddentabelle frei    *
  17. *            InitRotation()            initialisiert Rotationsfaktoren                *
  18. *            Trans3d()                        Transformiert 3D-Werte                                *
  19. *            CalcScale3d()                berechnet die Skalierung                            *
  20. *            DrawGLine3d()                zeichnet eine Gitterlinie                            *
  21. *            DrawGrid3d()                zeichnet die Koordinatenachsen                *
  22. *            HiddenLine()                berechnet Sichtbarkeit einer Linie        *
  23. *            SortFct0()                    Sortierfunktion 1                                            *
  24. *            SortFct2()                    Sortierfunktion 2                                            *
  25. *            Draw3dCurve()                zeichnet die Kurve                                        *
  26. *            DoClipp3D()                    3D Clipping                                                        *
  27. *            CheckClipp3D()            Clipping Hilfsfunktion                                *
  28. *            Draw3d()                        Hauptfunktion für 3D-Darstellung            *
  29. *            D3Lines()                        Unterfunktion für Draw3D()                        *
  30. *                                                                                                                                *
  31. *                Rev : V1.0                                                                                            *
  32. *                                                                                                                                *
  33. *        History : V1.0 erstellen dieses Files                            26/01/90    *
  34. *                                                                                                                                *
  35. *                Doc : Plotlibrary User's Guide                                                    *
  36. *                                                                                                                                *
  37. *             Bugs : keine bekannten                                                                        *
  38. *                                                                                                                                *
  39. *            Autor : Oesch Silvano                                                                            *
  40. *                                                                                                                                *
  41. *            Datum : 26/01/90                                                                                    *
  42. *                                                                                                                                *
  43. ****************************************************************/
  44.  
  45. /****************************************************************
  46. *                                                                                                                                *
  47. *    allgemeine Includedateien                                                                            *
  48. *                                                                                                                                *
  49. ****************************************************************/
  50.  
  51. #include <math.h>
  52.  
  53. /****************************************************************
  54. *                                                                                                                                *
  55. *    Plotlibrary Includedateien                                                                        *
  56. *                                                                                                                                *
  57. ****************************************************************/
  58.  
  59. #include "Plot.h"
  60. #include "PlotL2.h"
  61. #include "SuppL2.h"
  62. #include "GfxL3.h"
  63. #include "DispL2.h"
  64. #include "D3L2.h"
  65.  
  66. /****************************************************************
  67. *                                                                                                                                *
  68. *    externe Variablen                                                                                            *
  69. *                                                                                                                                *
  70. ****************************************************************/
  71.  
  72. extern struct Plot *plot;
  73. extern int plerr;
  74.  
  75. extern DATA    (*xexpfct)(),                        /* 10^ oder e^ bzw. ln oder    */
  76.                         (*xlogfct)(),                        /* log Funktion für X-Achse    */
  77.                         (*yexpfct)(),                        /* 10^ oder e^ bzw. ln oder    */
  78.                         (*ylogfct)(),                        /* log Funktion für Y-Achse    */
  79.                         (*zexpfct)(),                        /* 10^ oder e^ bzw. ln oder    */
  80.                         (*zlogfct)();                        /* log Funktion für Z-Achse    */
  81.  
  82. /****************************************************************
  83. *                                                                                                                                *
  84. *    Globale statische Variablen                                                                        *
  85. *                                                                                                                                *
  86. ****************************************************************/
  87.  
  88. static DATA    xr1,xr2,xr3,                        /* Rotationsfaktoren                */
  89.                         yr1,yr2,yr3,                        /* für alle drei Achsen            */
  90.                         zr1,zr2,zr3;
  91.  
  92. static DATA    xoffset,                                /* Bildverschiebung auf der    */
  93.                         yoffset,                                /* Projektionsebene                    */
  94.                         fxscale,                                /* Einheitsskalierung für        */
  95.                         fyscale,                                /* alle Achsen                            */
  96.                         fzscale,
  97.                         xscale,                                    /* Skalierung in der Pro-        */
  98.                         yscale;                                    /* jektionsebene                        */
  99.  
  100. static    GPT *tv,                                        /* oberer Horizont                    */
  101.                         *bv;                                        /* unterer Horizont                    */
  102.  
  103. /****************************************************************
  104. *                                                                                                                                *
  105. *    Function : draw3d()                                                                                        *
  106. *                                                                                                                                *
  107. *****************************************************************
  108. *                                                                                                                                *
  109. *         Input : void                                                                                                *
  110. *                                                                                                                                *
  111. *        Output : int                        allg. Rückgabewert                                    *
  112. *                            != FALSE        alle klar                                                        *
  113. *                            == FALSE            Fehler                                                            *
  114. *                                                                                                                                *
  115. *****************************************************************
  116. *                                                                                                                                *
  117. *     Comment : Draw3D() ist die Hauptfunktion der 3D-Darstellung.    *
  118. *                         Sie ruft die einzelnen Unterfunktionen auf, welche    *
  119. *                         das System initialisieren und danach werden die        *
  120. *                         Zeichnungsfunktionen aufgerufen, welche die                *
  121. *                         Graphik zeichnen.                                                                    *
  122. *                                                                                                                                *
  123. ****************************************************************/
  124.  
  125. int draw3d()
  126. {
  127.     int returnset = TRUE;                            /* allg. Rückgabewert                */
  128.  
  129.     plot->phix = 30;                                    /* feste Rotationswinkel        */
  130.     plot->phiy = 40;                                    /* für alle Achsen                    */
  131.     plot->phiz = 0;
  132.  
  133.     getxsize2d();                                            /* verfügbare Zeichengrösse    */
  134.     getysize2d();                                            /* verfügbare Zeichengrösse    */
  135.  
  136.     if (plot->d3opt & HIDDEN)                    /* Initialisiere Hiddenline    */
  137.         setreturn(inithidden());                /* wenn benötigt                        */
  138.     if (returnset != FALSE)                        /* weiter wenn kein Fehler    */
  139.     {
  140.         initfunction();                                    /* log Funktionen init.            */
  141.         initrotation();                                    /* rot. Funktion init.            */
  142.         calcstep(&plot->xmin,plot->xmes);
  143.         calcstep(&plot->ymin,plot->ymes);
  144.         calcstep(&plot->zmin,plot->zmes);
  145.         calcscale3d();                                    /* Skalierung berechnen            */
  146.         ClearGraphics();                                /* Graphik löschen                    */
  147.         drawgrid3d();                                        /* Gitter zeichnen                    */
  148.         draw3dcurves();                                    /* 3D Kurve zeichnen                */
  149.     }
  150.     if (plot->d3opt & HIDDEN)                    /* Hiddenline    freigeben            */
  151.         freehidden();                                        /* wenn vorhanden                        */
  152.     return(returnset);                                /* und zurück                                */
  153. }
  154.  
  155. /****************************************************************
  156. *                                                                                                                                *
  157. *    Function : Draw3dCurves()                                                                            *
  158. *                                                                                                                                *
  159. *****************************************************************
  160. *                                                                                                                                *
  161. *         Input : void                                                                                                *
  162. *                                                                                                                                *
  163. *        Output : void                                                                                                *
  164. *                                                                                                                                *
  165. *****************************************************************
  166. *                                                                                                                                *
  167. *     Comment : Draw3DCurves() zeichnet und beschriftet eine drei-    *
  168. *                         dimensionale Kurve. Die eingestellten Dar-                    *
  169. *                         stellungsoptionen HiddenLine und Crosshatching            *
  170. *                         werden dabei berücksichtigt. Alle Daten im                    *
  171. *                         Speicher werden zuerst nach ihrer Z-Komponente            *
  172. *                         sortiert und danach werden gleiche Z-Werte anhand    *
  173. *                         der X-Werte sortiert. Dadurch wird die ganze                *
  174. *                         in Schnitte unterteilt in Richtung der Z-Achse.        *
  175. *                         Die Linien können danach vmo kleineren X-Wert zum    *
  176. *                         grösseren X-Wert gezeichnet werden.                                *
  177. *                         Beim Crosshatching werden einfach die Sortier-            *
  178. *                         komponenten vertauscht. Es kann beim Aufzeichen        *
  179. *                         mit Crosshatching zu Darstellungsfehleren kommen,    *
  180. *                         da der Hiddenline Algorithmus die Daten in einer        *
  181. *                         bestimmten Reihenfolge benötigt. Siehe                            *
  182. *                         HiddenLine().                                                                            *
  183. *                                                                                                                                *
  184. ****************************************************************/
  185.  
  186. static void draw3dcurves()
  187. {
  188.  
  189.     struct Curve *curve=plot->first;    /* Kurvenzeiger                            */
  190.  
  191.     calccolor(curve->color);                    /* Farbe setzten                        */
  192.     d3lines(sfct2,sfct0);                            /* 1 Linienzug                            */
  193.     if (plot->d3opt & CROSH)                    /* mit Crosshatching                */
  194.     {                                                                    /* Ja                                                */
  195.         clearhidden();                                    /* Hidden init.                            */
  196.         d3lines(sfct0,sfct2);                        /* 2 Linienzug                            */
  197.     }
  198.     SetFgColor(TEXTCOL);                            /* für Text                                    */
  199.     if (curve->titel)                                    /* Wenn Namen                                */
  200.         printtextabs(curve->titel,            /* und schreibe Namen                */
  201.                                 (plot->xpic1+plot->xpic2)/2,
  202.                                 plot->ysize,T_CX|T_B);
  203.  
  204. }
  205.  
  206. /****************************************************************
  207. *                                                                                                                                *
  208. *    Function : trans3d()                                                                                    *
  209. *                                                                                                                                *
  210. *****************************************************************
  211. *                                                                                                                                *
  212. *         Input : xo,yo,zo,xn,yn                                                                            *
  213. *                            DATA *xo            transformierender X-Wert                        *
  214. *                                     *yo            transformierender Y-Wert                        *
  215. *                                     *zo            transformierender Z-Wert                        *
  216. *                            int     *xn            transformierter X-Wert                            *
  217. *                                     *yn            transformierter Y-Wert                            *
  218. *                                                                                                                                *
  219. *        Output : returnset            Rüchgabewert                                                *
  220. *                            int returnset                                                                            *
  221. *                                == TRUE            gültige Transformation                            *
  222. *                                 & XTRANS        ungültige X Transformation                    *
  223. *                                 & YTRANS        ungültige Y Transformation                    *
  224. *                                 & ZTRANS        ungültige Z Transformation                    *
  225. *                                                                                                                                *
  226. *****************************************************************
  227. *                                                                                                                                *
  228. *     Comment : Diese Funktion transformiert einen Koordinaten-        *
  229. *                         punkt in die Bildschirmkoordinaten.    Die math.            *
  230. *                         Beschreibung dieser Funktion ist in der Diplom-        *
  231. *                         arbeit zu finden.                                                                    *
  232. *                                                                                                                                *
  233. ****************************************************************/
  234.  
  235. int trans3d(xo,yo,zo,xn,yn)
  236. DATA *xo,
  237.          *yo,
  238.          *zo;
  239. int     *xn,
  240.          *yn;
  241. {
  242.     int returnset = TRUE;                            /* allg Rückgabewert                */
  243.     DATA    x,y,z,                                            /* Speicher für die                    */
  244.                 x1,y1,z1,                                        /* Koordinaten                            */
  245.                 divs;                                                /* Projektionsdivisor                */
  246.  
  247. /****************************************************************
  248. *                                                                                                                                *
  249. *    Werte Transformation                                                                                    *
  250. *                                                                                                                                *
  251. ****************************************************************/
  252.  
  253.     if (plot->xmes != LIN)                        /* log Transformation                */
  254.         if (*xo > 0.0)                                    /* bereichscheck                        */
  255.             x = xlogfct(*xo);                            /* transformieren                        */
  256.         else                                                        /* sonst                                        */
  257.             returnset |=XTRANS;                        /* Fehler                                        */
  258.     else                                                            /* also lineare Trans.            */
  259.         x = *xo;                                                /* Wert zuweisen                        */
  260.  
  261.     if (plot->ymes != LIN)                        /* log Transformation                */
  262.         if (*yo > 0.0)                                    /* bereichscheck                        */
  263.             y = ylogfct(*yo);                            /* transformieren                        */
  264.         else                                                        /* sonst                                        */
  265.             returnset |=YTRANS;                        /* Fehler                                        */
  266.     else                                                            /* also lineare Trans.            */
  267.         y = *yo;                                                /* Wert zuweisen                        */
  268.  
  269.     if (plot->zmes != LIN)                        /* log Transformation                */
  270.         if (*zo > 0.0)                                    /* bereichscheck                        */
  271.             z = zlogfct(*zo);                            /* transformieren                        */
  272.         else                                                        /* sonst                                        */
  273.             returnset |=ZTRANS;                        /* Fehler                                        */
  274.     else                                                            /* also lineare Trans.            */
  275.         z = *zo;                                                /* Wert zuweisen                        */
  276.  
  277.     if (returnset != TRUE)                        /* Fehler bei Werttransf.        */
  278.         return(returnset);                            /* mit Fehler zurück                */
  279.  
  280.     x = x*fxscale;                                        /* Einheitsskalierung                */
  281.     y = y*fyscale;                                        /* alle Achsen haben danach    */
  282.     z = z*fzscale;                                        /* einen Range von 10000        */
  283.  
  284. /****************************************************************
  285. *                                                                                                                                *
  286. *    Rotation um x-, y- und z-Achse in dieser Reihenfolge                    *
  287. *                                                                                                                                *
  288. ****************************************************************/
  289.  
  290.     x1 = x*xr1 + y*xr2 + z*xr3;                /* Rotationswerte wurden        */
  291.     y1 = x*yr1 + y*yr2 + z*yr3;                /* in InitRotation() schon    */
  292.     z1 = x*zr1 + y*zr2 + z*zr3;                /* berechnet                                */
  293.  
  294. /****************************************************************
  295. *                                                                                                                                *
  296. *    Projektion auf die Bildschirmebene                                                        *
  297. *                                                                                                                                *
  298. ****************************************************************/
  299.  
  300.     divs = z1-plot->zcenter;
  301.     x = (z1*plot->xcenter-x1*plot->zcenter)/divs;
  302.     y = (z1*plot->ycenter-y1*plot->zcenter)/divs;
  303.  
  304. /****************************************************************
  305. *                                                                                                                                *
  306. *    Spiegelung, Skalierung und Rückverschiebung                                        *
  307. *                                                                                                                                *
  308. ****************************************************************/
  309.  
  310.     *xn = (int)(x*xscale)+xoffset;        /* X-Achse                                    */
  311.     *yn = (int)(-y*yscale)+yoffset;        /* Y-Achse                                    */
  312.  
  313.     return(returnset);                                /* und zurück                                */
  314. }
  315.  
  316. /****************************************************************
  317. *                                                                                                                                *
  318. *    Function : drawgline3d()                                                                            *
  319. *                                                                                                                                *
  320. *****************************************************************
  321. *                                                                                                                                *
  322. *         Input : void                                                                                                *
  323. *                                                                                                                                *
  324. *        Output : void                                                                                                *
  325. *                                                                                                                                *
  326. *****************************************************************
  327. *                                                                                                                                *
  328. *     Comment : DrawGLine3D() zeichnet eine Gerade mit den ein-        *
  329. *                         gestellten Transformationswerten. Es werden keine    *
  330. *                         Kontrollen auf Sichtbarkeit und transformier-            *
  331. *                         geführt.                                                                                        *
  332. *                                                                                                                                *
  333. ****************************************************************/
  334.  
  335. void drawgline3d(xs,ys,zs,xe,ye,ze)
  336. DATA *xs,*ys,*zs,*xe,*ye,*ze;
  337. {
  338.     int xsn,ysn,xen,yen;                            /* trans. Werte                            */
  339.  
  340.     trans3d(xs,ys,zs,&xsn,&ysn);            /* Werte transformieren            */
  341.     trans3d(xe,ye,ze,&xen,¥);
  342.  
  343.     DrawLine(xsn,ysn,xen,yen);                /* Linie Zeichnen                        */
  344. }
  345.  
  346. /****************************************************************
  347. *                                                                                                                                *
  348. *    Function : D3Lines()                                                                                    *
  349. *                                                                                                                                *
  350. *****************************************************************
  351. *                                                                                                                                *
  352. *         Input : sort1,sort2,opt                                                                        *
  353. *                            int *sort1()            Hauptsortierfunktion                        *
  354. *                            int *sort2()            Untersortierfunktion                        *
  355. *                            int opt                        Crosshatchoption                                *
  356. *                                                                                                                                *
  357. *        Output : void                                                                                                *
  358. *                                                                                                                                *
  359. *****************************************************************
  360. *                                                                                                                                *
  361. *     Comment : Unterfunktion von Draw3dCurves. Kommentar siehe        *
  362. *                         dort.                                                                                            *
  363. *                                                                                                                                *
  364. ****************************************************************/
  365.  
  366. static void d3lines(sort1,sort2)
  367. int (*sort1)(DATA *,DATA *),
  368.         (*sort2)(DATA *,DATA *);
  369. {
  370.     int counter,                                            /* Unterelementzähler                */
  371.             ct,                                                        /* Elememntzähler                        */
  372.             datasize,                                            /* Grösse eines Elementes        */
  373.             xi1,yi1,                                            /* Startpunkt Bildschirm        */
  374.             xi2,yi2,                                            /* Endpunkt Bildschirm            */
  375.             i,                                                        /* Schleifenzähler                    */
  376.             set,                                                    /* Setindikator                            */
  377.             clipp;                                                /* clipping Status                    */
  378.     struct Curve *curve;                            /* Kurvenzeiger                            */
  379.     register DATA *val,                                /* letztes Datenelement            */
  380.                                 *first;                            /* erstes Element                        */
  381.     DATA    x1,y1,z1,                                        /* Startpunkt real                    */
  382.                 x2,y2,z2;                                        /* Endpunkt real                        */
  383.  
  384.     curve = plot->first;                            /* Kurvenzeiger init.                */
  385.     datasize = valsize()*sizeof(DATA);
  386.     val = curve->val;                                    /* Datenzeiger init.                */
  387.     qsort((void *)curve->val,curve->count,datasize,sort1);
  388.                                                                         /* sortiere ganzes Feld            */
  389.     ct = 0;                                                        /* counter löschen                    */
  390.     while(ct < curve->count)                    /* solange Daten vorhanden    */
  391.     {
  392.         first = val;                                        /* Startelement                            */
  393.         counter = 0;                                        /* kein Element                            */
  394.         do                                                            /* suche alle Elemente die    */
  395.         {                                                                /* gleich sind wie das            */
  396.             val +=3;                                            /* Startelement und zähle        */
  397.             counter++;                                        /* sie                                            */
  398.         }
  399.         while(!sort1(first,val));                /* Feldvergleich                        */
  400.  
  401.         if (counter >=2)                                /* min. Start- und Endpunkt    */
  402.         {
  403.             qsort((void *)first,counter,datasize,sort2);
  404.                                                                         /* sortieren                                */
  405.             set = FALSE;                                    /* 1 Element nicht gesetzt    */
  406.             clipp = FALSE;                                /* clipping Status                    */
  407.             for (i=0;i<counter;i++)                /* für alle Punkte                    */
  408.             {
  409.                 x2 = first[0];                            /* Endpunkt zuweisen                */
  410.                 y2 = first[1];
  411.                 z2 = first[2];
  412.                 if (set)                                        /* Startpunkt gesetzt                */
  413.                 {                                                        /* Ja                                                */
  414.                     if (plot->clipp == CLIPP)    /* clippen falls notwendig    */
  415.                         clipp = doclipp3d(&x1,&y1,&z1,&x2,&y2,&z2);
  416.                     if (!clipp)                                /* nur wenn guter Status        */
  417.                     {                                                    /* transformieren                        */
  418.                         if ((trans3d(&x1,&y1,&z1,&xi1,&yi1) == TRUE) and
  419.                                 (trans3d(&x2,&y2,&z2,&xi2,&yi2) == TRUE))
  420.                         {                                                /* nur wenn trans. ok                */
  421.  
  422. /****************************************************************
  423. *                                                                                                                                *
  424. *    Wenn HiddenLine erwünscht ist, muss bei CrossHatching der            *
  425. *    Startpunkt mit dem Endpunkt vertauscht werden.                                *
  426. *                                                                                                                                *
  427. ****************************************************************/
  428.  
  429.                             if (plot->d3opt & HIDDEN)
  430.                             {
  431.                                 if (sort1 == sfct2)
  432.                                     hiddenline(xi1,yi1,xi2,yi2);
  433.                                 else
  434.                                     hiddenline(xi2,yi2,xi1,yi1);
  435.                             }
  436.                             else
  437.                                 DrawLine(xi1,yi1,xi2,yi2);
  438.                         }
  439.                     }
  440.                 }
  441.                 x1 = first[0];                            /* Startpunkt von letztem        */
  442.                 y1 = first[1];                            /* Punkt nehmen                            */
  443.                 z1 = first[2];
  444.                 set = TRUE;                                    /* Startpunkt gesetzt                */
  445.                 first +=3;                                    /* Nächtes Datenelement            */
  446.             }
  447.         }
  448.         ct += counter;                                    /* gezeichnete Punkte add.    */
  449.     }
  450. }
  451.  
  452. /****************************************************************
  453. *                                                                                                                                *
  454. *    Function : drawgrid3d()                                                                                *
  455. *                                                                                                                                *
  456. *****************************************************************
  457. *                                                                                                                                *
  458. *         Input : void                                                                                                *
  459. *                                                                                                                                *
  460. *        Output : void                                                                                                *
  461. *                                                                                                                                *
  462. *****************************************************************
  463. *                                                                                                                                *
  464. *     Comment : DrawGrid() zeichnet das Gitter auf den Bildschirm    *
  465. *                         für die 2 dimensionale Darstellung.                                *
  466. *                                                                                                                                *
  467. ****************************************************************/
  468.  
  469. static void drawgrid3d()
  470. {
  471.     int i,                                                        /* Schleifenzähler                    */
  472.             slen,                                                    /* Textlänge                                */
  473.             len,                                                    /* Beschriftungslänge Y            */
  474.             htsize,                                                /* Zeilenhöhe                                */
  475.             x1,y1;                                                /* Bildschirmkoordinaten        */
  476.  
  477.     char sbuf[] = " ";                                /* Textpuffer                                */
  478.  
  479.  
  480.     drawxaxis();                                            /* Alle drei Achsen auf            */
  481.     len = drawyaxis();                                /* den Bildschirm zeichnen    */
  482.     drawzaxis();
  483.  
  484. /****************************************************************
  485. *                                                                                                                                *
  486. *    Sichtbare Achsenlinien zeichnen                                                                *
  487. *                                                                                                                                *
  488. ****************************************************************/
  489.  
  490.     drawgline3d(&plot->xgridmin,&plot->ygridmax,&plot->zgridmax,
  491.                             &plot->xgridmin,&plot->ygridmin,&plot->zgridmax);
  492.  
  493.     drawgline3d(&plot->xgridmin,&plot->ygridmin,&plot->zgridmin,
  494.                             &plot->xgridmax,&plot->ygridmin,&plot->zgridmin);
  495.  
  496.     drawgline3d(&plot->xgridmin,&plot->ygridmin,&plot->zgridmax,
  497.                             &plot->xgridmin,&plot->ygridmin,&plot->zgridmin);
  498.  
  499.     if (plot->titel)                                    /* Titel der Graphik                 */
  500.         printtextabs(plot->titel,                /* schreiben wenn vorhanden    */
  501.                                  (plot->xpic1+plot->xpic2)/2,
  502.                                     plot->ypic1-plot->yle,T_CX|T_B);
  503.  
  504.     trans3d(&plot->xgridmin,&plot->ygridmin,&plot->zgridmin,
  505.                     &x1,&y1);
  506.  
  507.     if (plot->xname)                                    /* X-Achsenname                            */
  508.         printtextabs(plot->xname,                /* schreiben wenn vorhanden    */
  509.                                 (plot->xpic2+x1)/2,
  510.                                 y1,T_CX|T_T);
  511.  
  512.     if (plot->xunit)                                    /* X-Achseneinheit                    */
  513.         printtextabs(plot->xunit,                /* schreiben wenn vorhanden    */
  514.                                  plot->xpic2,
  515.                                  y1,T_L|T_T);
  516.  
  517.     if (plot->zname)                                    /* Z-Achsenname                            */
  518.         printtextabs(plot->zname,                /* schreiben wenn vorhanden    */
  519.                                 (plot->xpic1+x1)/2,
  520.                                 y1,T_CX|T_T);
  521.  
  522.     if (plot->zunit)                                    /* Z-Achseneinheit                    */
  523.         printtextabs(plot->zunit,                /* schreiben wenn vorhanden    */
  524.                                  plot->xpic1,
  525.                                  y1,T_R|T_T);
  526.  
  527.     if (plot->yname)                                    /* Y-Achsenname                            */
  528.     {                                                                    /* schreiben wenn vorhanden    */
  529.         slen = strlen(plot->yname);            /* Länge des Namens                    */
  530.         len ++;                                                    /* Abstand zur Y-Achse            */
  531.         htsize = 5*plot->ytext/4;
  532.         y1 = (plot->ypic2+plot->ypic1-(slen-1)*htsize)/2;
  533.         x1 = plot->xpic1-len*plot->xtext;
  534.         for (i=0;i<slen;i++)                        /* jedes Zeichen ausgeben        */
  535.         {
  536.             sbuf[0] = plot->yname[i];
  537.             printtextabs(    sbuf,
  538.                                         x1,
  539.                                         y1+i*htsize,
  540.                                         T_L|T_CY);
  541.         }
  542.     }
  543.  
  544.     trans3d(&plot->xgridmin,&plot->ygridmax,&plot->zgridmax,
  545.                     &x1,&y1);
  546.  
  547.     if (plot->yunit)                                    /* Y-Achseneinheit                    */
  548.         printtextabs(plot->yunit,                /* schreiben wenn vorhanden    */
  549.                                  x1,
  550.                                  y1-plot->yle,
  551.                                  T_L|T_B);
  552. }
  553.  
  554. /****************************************************************
  555. *                                                                                                                                *
  556. *    Function : HiddenLine()                                                                                *
  557. *                                                                                                                                *
  558. *****************************************************************
  559. *                                                                                                                                *
  560. *         Input : x,y,x1,y1                                                                                    *
  561. *                            int x                            Startpunkt der Linie                        *
  562. *                            int y                                                                                            *
  563. *                            int x1                        Endpunkt der Linie                            *
  564. *                            int y1                                                                                        *
  565. *                                                                                                                                *
  566. *        Output : void                                                                                                *
  567. *                                                                                                                                *
  568. *****************************************************************
  569. *                                                                                                                                *
  570. *     Comment : Diese Funktion kontrolliert eine Linie auf ihre        *
  571. *                         auf ihre Sichtbarkeit. Die Funktionsweise dieses        *
  572. *                         ist schnell erklärt.                                                                *
  573. *                         Es werden zwei Horizonte definiert mit der Länge        *
  574. *                         der Bildschirmauflösung. Diese beiden Horizonte        *
  575. *                         werden am Anfang mit ihren gegenüberliegenden            *
  576. *                         Werten inittialisiert. Die einzelnen Punkte einer    *
  577. *                         Linie werden nun mit diesen beiden Horizonten            *
  578. *                         vergliechen.                                                                                *
  579. *                         Wenn sie über bzw. unter dem Horizont liegen, so        *
  580. *                         werden sie gezeichnet und die Horizonte werden auf    *
  581. *                         dieses Nivau angehoben. Wenn die Punkte zwischen        *
  582. *                         den Horizonten liegt, dann wird keine Linie                *
  583. *                         gezeichnet.                                                                                *
  584. *                         Dieser sehr schnell und kleine Algorithmus hat            *
  585. *                         jedoch auch seine Nachteile. Die Linien müssen            *
  586. *                         auf dem Bildschirm von vorne nach hinten                        *
  587. *                         gezeichnet werden.                                                                    *
  588. *                         Da dies beim Crosshatching nicht immer erfüllt            *
  589. *                         wird, kann man dort kleinere Fehler erkennen.            *
  590. *                                                                                                                                *
  591. ****************************************************************/
  592.  
  593. static void hiddenline(x,y,x1,y1)
  594. int x,y,x1,y1;
  595. {
  596.  
  597.     int dx,                                                        /* horiz. Länge in Punkten    */
  598.             i,                                                        /* Schleifenzähler                    */
  599.             mx,my,                                                /* Startpunkt der Linie            */
  600.             top,bot,                                            /* Boolean für Horizont            */
  601.             hid,                                                    /* Hiddenboolean                        */
  602.             yai,                                                    /* aktuelle Y-Wert                    */
  603.             yvi;                                                    /* vorhergehender Y-Wert        */
  604.     DATA    yaf,                                                /* aktueller Floathorizont    */
  605.                 m;                                                    /* Steigung                                    */
  606.  
  607.     dx = x1-x;                                                /* berechne länge                        */
  608.     if (dx==0)                                                /* wenn keine Differenz            */
  609.     {
  610.         dx = 1;                                                    /* generieren einer                    */
  611.         x = x1-1;                                                /* künst. Differenz                    */
  612.     }
  613.     m = (DATA)(y1-y)/abs(dx);                    /* Steigung der Linie                */
  614.     yaf = (DATA)y;                                        /* Startpunkt speichern            */
  615.     yai = y;                                                    /* Y-Wert setzten                        */
  616.     yvi = y;
  617.  
  618.     hid=TRUE;                                                    /* Linie nicht sichtbar            */
  619.     mx = x;                                                        /* Startpunkt der Linie            */
  620.     my = y;                                                        /* setzten                                    */
  621.     for (i=x;i<=x1;i++)                                /* für ganze Länge                    */
  622.     {
  623.         top = (yai <= tv[i]);                        /* Punkt über Top setzte 1    */
  624.         bot = (yai >= bv[i]);                        /* Punkt unter Bottom 1            */
  625.  
  626.         if (top) tv[i] = yai;                        /* neuer Horizont setzten        */
  627.         if (bot) bv[i] = yai;                        /* wenn nötig                                */
  628.         if ((!hid)and(!((top)or(bot))))    /* Zeichne Linie wenn 1            */
  629.         {                                                                /* Status sich verändert        */
  630.             hid=TRUE;                                            /* Linie versteckt                    */
  631.             DrawLine(mx,my,i-1,yvi);
  632.         }
  633.         if ((hid)and((top)or(bot)))            /* alles Sichtbar dann            */
  634.         {                                                                /* setzte hidden und lege        */
  635.             hid=FALSE;                                        /* den Startpinkt der Linie    */
  636.             mx = i;                                                /* fest                                            */
  637.             my = yai;
  638.         }
  639.         yaf = yaf+m;                                        /* nächster Punkt berechnen    */
  640.         yvi = yai;                                            /* und vorhergehender                */
  641.         yai = round(yaf);                                /* setzten                                    */
  642.     }
  643.     if (!hid)                                                    /* zeichne Linie, wenn            */
  644.         DrawLine(mx,my,x1,y1);                    /* Daten vorhanden                    */
  645. }
  646.  
  647.  
  648. /****************************************************************
  649. *                                                                                                                                *
  650. *    Function : sfct0()                                                                                        *
  651. *                                                                                                                                *
  652. *****************************************************************
  653. *                                                                                                                                *
  654. *         Input : x,x1                                                                                                *
  655. *                            DATA *x                        erstes Element                                    *
  656. *                            DATA *1x                    zweites Element                                    *
  657. *                                                                                                                                *
  658. *        Output : int                                                                                                *
  659. *                            >  0                           x >     x1                                                    *
  660. *                            == 0                            x == x1                                                    *
  661. *                            <  0                            x <     x1                                                    *
  662. *                                                                                                                                *
  663. *****************************************************************
  664. *                                                                                                                                *
  665. *     Comment : Diese Funktion wird von dem Sortieralgorithmus            *
  666. *                         benötigt. Die Datentabelle wird nach dem ersten        *
  667. *                         Element ( x-Wert ) sortiert.                                                *
  668. *                                                                                                                                *
  669. ****************************************************************/
  670.  
  671. static int sfct0(x,x1)
  672. DATA *x,
  673.          *x1;
  674. {
  675.     if (*x < *x1) return(-1);                    /* Vergleichsoperation mit    */
  676.     else if (*x > *x1) return(1);            /* den verschiedenen Rück-    */
  677.     else return(0);                                        /* gabewerten                                */
  678. }
  679.  
  680. /****************************************************************
  681. *                                                                                                                                *
  682. *    Function : sfct2()                                                                                        *
  683. *                                                                                                                                *
  684. *****************************************************************
  685. *                                                                                                                                *
  686. *         Input : x,x1                                                                                                *
  687. *                            DATA *x                        erstes Element                                    *
  688. *                            DATA *1x                    zweites Element                                    *
  689. *                                                                                                                                *
  690. *        Output : int                                                                                                *
  691. *                            >  0                           x >     x1                                                    *
  692. *                            == 0                            x == x1                                                    *
  693. *                            <  0                            x <     x1                                                    *
  694. *                                                                                                                                *
  695. *****************************************************************
  696. *                                                                                                                                *
  697. *     Comment : Diese Funktion wird von dem Sortieralgorithmus            *
  698. *                         benötigt. Die Datentabelle wird nach dem dritten        *
  699. *                         Element ( z-Wert ) sortiert.                                                *
  700. *                                                                                                                                *
  701. ****************************************************************/
  702.  
  703. static int sfct2(x,x1)
  704. DATA *x,
  705.          *x1;
  706. {
  707.     register DATA *u,*v;                            /* Datenzeiger                            */
  708.  
  709.     u = x+2;                                                    /* zuweisen der Daten-            */
  710.     v = x1+2;                                                    /* elemente                                    */
  711.  
  712.     if (*u < *v) return(-1);                    /* Vergleichsoperation mit    */
  713.     else if (*u > *v) return(1);            /* den verschiedenen Rück-    */
  714.     else return(0);                                        /* gabewerten                                */
  715. }
  716.  
  717. /****************************************************************
  718. *                                                                                                                                *
  719. *    Function : checkclipp3d()                                                                            *
  720. *                                                                                                                                *
  721. *****************************************************************
  722. *                                                                                                                                *
  723. *         Input : x,y,z,c                                                                                        *
  724. *                            DATA *x                        x Koordinate                                        *
  725. *                            DATA *y                        y Koordinate                                        *
  726. *                            DATA *z                        z Koordinate                                        *
  727. *                            char *c                        Status                                                    *
  728. *                                                                                                                                *
  729. *        Output : void                                                                                                *
  730. *                                                                                                                                *
  731. *****************************************************************
  732. *                                                                                                                                *
  733. *     Comment : Diese Funktion kontrolliert die Koordinaten                 *
  734. *                         mittels der Gittergrenzen auf ihre Lage. Der                *
  735. *                         Status wird mit den folgenden defines gesetzt.            *
  736. *                                                                                                                                *
  737. *                            X_MN    ->    Clipping XMin                                                        *
  738. *                            X_MX    ->    Clipping XMax                                                        *
  739. *                            Y_MN    ->    Clipping YMin                                                        *
  740. *                            Y_MX    ->    Clipping YMax                                                        *
  741. *                            Z_MN    ->    Clipping ZMin                                                        *
  742. *                            Z_MX    ->    Clipping ZMax                                                        *
  743. *                                                                                                                                *
  744. *                        Wenn das Clipping eingeschaltet ist, wird                        *
  745. *                        mindestens diese Funktion aufgerufen und durch-            *
  746. *                        geführt.                                                                                        *
  747. *                                                                                                                                *
  748. ****************************************************************/
  749.  
  750. static void checkclipp3d(x,y,z,c)
  751. DATA    *x,
  752.             *y,
  753.             *z;
  754. char    *c;
  755. {
  756.   *c=0;                                                            /* status initialisieren        */
  757.   if (*x<plot->xgridmin)                        /* links von min ?                    */
  758.     *c |= X_MN;                                            /* Ja                                                */
  759.   else if (*x>plot->xgridmax)                /* Nein, rechts von max            */
  760.     *c |= X_MX;                                            /* Ja                                                */
  761.  
  762.   if (*y<plot->ygridmin)                        /* links von min ?                    */
  763.     *c |= Y_MN;                                            /* Ja                                                */
  764.   else if (*y>plot->ygridmax)                /* Nein, rechts von max            */
  765.     *c |= Y_MX;                                            /* Ja                                                */
  766.  
  767.   if (*z<plot->zgridmin)                        /* links von min ?                    */
  768.     *c |= Z_MN;                                            /* Ja                                                */
  769.   else if (*z>plot->zgridmax)                /* Nein, rechts von max            */
  770.     *c |= Z_MX;                                            /* Ja                                                */
  771. }
  772.  
  773. /****************************************************************
  774. *                                                                                                                                *
  775. *    Function : doclipp3d()                                                                                *
  776. *                                                                                                                                *
  777. *****************************************************************
  778. *                                                                                                                                *
  779. *         Input : x1,y1,z1,x2,y2,z2                                                                    *
  780. *                            DATA *x1            x Start                                                            *
  781. *                            DATA *y1            y    Start                                                            *
  782. *                            DATA *z1            z    Start                                                            *
  783. *                            DATA *x2            x Ende                                                            *
  784. *                            DATA *y2            y Ende                                                            *
  785. *                            DATA *z2            z    Ende                                                            *
  786. *                                                                                                                                *
  787. *        Output : char                        Status                                                            *
  788. *                            != 0                    trivial reject                                            *
  789. *                            == 0                    Draw                                                                *
  790. *                                                                                                                                *
  791. *****************************************************************
  792. *                                                                                                                                *
  793. *     Comment : Der Cohen-Sutherland Clipping Algorithmus welcher    *
  794. *                         hier verwendet wird, ist eine logische Weiter-            *
  795. *                         entwicklung aus dem 2D-Bereich. Er liefert einen        *
  796. *                         Status über das Zeichnen der Linie.                                *
  797. *                         Wenn dieser Status == 0 ist, kann die Linie                *
  798. *                         gezeichnet werden.                                                                    *
  799. *                         Eine nähere Beschreibung dieses Algorithums                *
  800. *                         befindet sich in der Diplomarbeit.                                    *
  801. *                                                                                                                                *
  802. ****************************************************************/
  803.  
  804. static char doclipp3d(x1,y1,z1,x2,y2,z2)
  805. DATA    *x1,
  806.             *y1,
  807.             *z1,
  808.             *x2,
  809.             *y2,
  810.             *z2;
  811. {
  812.     DATA     x,y,z,                                            /* geclippte Koordinaten        */
  813.                 fac;                                                /* Verhältnisfaktor                    */
  814.     char    c1,c2,c;                                        /* Status Variablen                    */
  815.  
  816.     checkclipp3d(x1,y1,z1,&c1);                /* Kontrolliere Startpunkt    */
  817.     checkclipp3d(x2,y2,z2,&c2);                /* kontrolliere Endpunkt        */
  818.  
  819. /****************************************************************
  820. *                                                                                                                                *
  821. *    Der folgende Vergleich bestimmt das Clipping.                                    *
  822. *                                                                                                                                *
  823. *    ((c1!=0) || (c2!=0)) Wenn c1 == 0 und c2 == 0 dann trivial        *
  824. *    accept also die Linie liegt vollständig im Fenster.                        *
  825. *                                                                                                                                *
  826. *    ((c1 & c2)!=0) Wenn beide Statusvariablen gleich sind spricht    *
  827. *    man von trivial reject.                                                                                *
  828. *                                                                                                                                *
  829. *    Wenn eine dieser Bedingungen erfüllt ist, dann muss keine            *
  830. *    Berechnung durchgeführt werden. Der Status wird entsprechend    *
  831. *    gesetzt.                                                                                                            *
  832. *                                                                                                                                *
  833. ****************************************************************/
  834.  
  835.     while(((c1!=0) || (c2!=0)) && ((c1 & c2)==0))
  836.   {
  837.         if (c1)                                                    /* Startpunkt clippen                */
  838.             c=c1;                                                    /* dann Status zuweisen            */
  839.         else                                                        /* sonst                                        */
  840.             c=c2;                                                    /* Endpunkt zuweisen                */
  841.  
  842.         if (c & X_MN)                                        /* Punkt kleiner xmin ?            */
  843.         {                                                                /* Ja                                                */
  844.             x=plot->xgridmin;                            /* x gleich xmingrid                */
  845.             fac=(x-*x1)/(*x2-*x1);                /* Faktor berechnen                    */
  846.             y=*y1+(*y2-*y1)*fac;                    /* Schnittpunkt Y Koord.        */
  847.             z=*z1+(*z2-*z1)*fac;                    /* Schnittpunkt Z Koord.        */
  848.         }
  849.         else if (c & X_MX)                            /* Punkt kleiner xmax ?            */
  850.         {                                                                /* Ja                                                */
  851.             x=plot->xgridmax;                            /* x gleich xmaxgrid                */
  852.             fac = (x-*x1)/(*x2-*x1);            /* Faktor berechnen                    */
  853.             y= *y1+(*y2-*y1)*fac;                    /* Schnittpunkt Y Koord.        */
  854.             z= *z1+(*z2-*z1)*fac;                    /* Schnittpunkt Z Koord.        */
  855.         }
  856.  
  857.         if (c & Y_MN)                                        /* Punkt kleiner ymin ?            */
  858.         {                                                                /* Ja                                                */
  859.             y=plot->ygridmin;                            /* y gleich ymingrid                */
  860.             fac = (y-*y1)/(*y2-*y1);            /* Faktor berechnen                    */
  861.             x= *x1+(*x2-*x1)*fac;                    /* Schnittpunkt X Koord.        */
  862.             z= *z1+(*z2-*z1)*fac;                    /* Schnittpunkt Z Koord.        */
  863.         }
  864.         else if (c & Y_MX)                            /* Punkt kleiner ymax ?            */
  865.         {                                                                /* Ja                                                */
  866.             y=plot->ygridmax;                            /* y gleich ymaxgrid                */
  867.             fac = (y-*y1)/(*y2-*y1);            /* Faktor berechnen                    */
  868.             x= *x1+(*x2-*x1)*fac;                    /* Schnittpunkt X Koord.        */
  869.             z= *z1+(*z2-*z1)*fac;                    /* Schnittpunkt Z Koord.        */
  870.         }
  871.  
  872.         if (c & Z_MN)                                        /* Punkt kleiner zmin ?            */
  873.         {                                                                /* Ja                                                */
  874.             z=plot->zgridmin;                            /* z gleich zmingrid                */
  875.             fac = (z-*z1)/(*z2-*z1);            /* Faktor berechnen                    */
  876.             x= *x1+(*x2-*x1)*fac;                    /* Schnittpunkt X Koord.        */
  877.             y= *y1+(*y2-*y1)*fac;                    /* Schnittpunkt Y Koord.        */
  878.         }
  879.         else if (c & Z_MX)                            /* Punkt kleiner zmax ?            */
  880.         {                                                                /* Ja                                                */
  881.             z=plot->zgridmax;                            /* z gleich zmaxgrid                */
  882.             fac = (z-*z1)/(*z2-*z1);            /* Faktor berechnen                    */
  883.             x= *x1+(*x2-*x1)*fac;                    /* Schnittpunkt X Koord.        */
  884.             y= *y1+(*y2-*y1)*fac;                    /* Schnittpunkt Y Koord.        */
  885.         }
  886.  
  887.         if (c==c1)                                            /* Startpunkt bearbeitet ?    */
  888.         {                                                                /* Ja                                                */
  889.             *x1=x;                                                /* geclippte Werte zu-            */
  890.             *y1=y;                                                /* weisen                                        */
  891.             *z1=z;
  892.             checkclipp3d(x1,y1,z1,&c1);        /* und kontrollieren                */
  893.         }
  894.         else                                                        /* also Endpunkt                        */
  895.         {
  896.             *x2=x;                                                /* geclippte Werte zu-            */
  897.             *y2=y;                                                /* weisen                                        */
  898.             *z2=z;
  899.             checkclipp3d(x2,y2,z2,&c2);        /* und kontrollieren                */
  900.         }
  901.     }
  902.     return(c1);                                                /* zurück mit Status                */
  903. }
  904.  
  905. /****************************************************************
  906. *                                                                                                                                *
  907. *    Function : calcscale()                                                                                *
  908. *                                                                                                                                *
  909. *****************************************************************
  910. *                                                                                                                                *
  911. *         Input : void                                                                                                *
  912. *                                                                                                                                *
  913. *        Output : void                                                                                                *
  914. *                                                                                                                                *
  915. *****************************************************************
  916. *                                                                                                                                *
  917. *     Comment : CalcScale berechnet die automatische Skalierung        *
  918. *                         für alle 3D Darstellungen auf dem Bildschirm.            *
  919. *                         Diese Funktion berechnet die Werte für die                    *
  920. *                         Transformationsmatrix. Es wird der max. verfügbare    *
  921. *                         Pixelbereich dividiert durch die Grösse des                *
  922. *                         Gitters. Dadurch erhalten wir für jeden Pixel            *
  923. *                         einen bestimmten virtuellen Wert.                                    *
  924. *                                                                                                                                *
  925. ****************************************************************/
  926.  
  927. static void calcscale3d()
  928. {
  929.     int i;                                                        /* allg Schleifenvariable        */
  930.  
  931.     int pt[8][3] =                                        /* Kanten der Koordinaten-    */
  932.     {                                                                    /* grenzen. Indexierung in    */
  933.         0,2,5,                                                    /* vt[] (ValueTable).                */
  934.         1,2,5,
  935.         1,3,5,
  936.         0,3,5,
  937.         0,2,4,
  938.         1,2,4,
  939.         1,3,4,
  940.         0,3,4
  941.     };
  942.  
  943.     DATA    u,v,                                                /* X- und Y-Projektion            */
  944.                 ul,ur,                                            /* X-Projektions Werte            */
  945.                 vl,vr,                                            /* Y-Projektions Werte            */
  946.                 divs,                                                /* Divisor                                    */
  947.                 x,y,z,                                            /* temp. Koordinatenpunkt        */
  948.                 vt[6];                                            /* Eckpunkttabelle                    */
  949.  
  950. /****************************************************************
  951. *                                                                                                                                *
  952. *    Werte Konvertierung für alle Grenzwerte                                                *
  953. *                                                                                                                                *
  954. ****************************************************************/
  955.  
  956.     if (plot->xmes != LIN)                        /* log. Transformation            */
  957.     {
  958.         vt[0] = xlogfct(plot->xgridmin);
  959.         vt[1] = xlogfct(plot->xgridmax);
  960.     }
  961.     else                                                            /* lineare Transformation        */
  962.     {
  963.         vt[0] = plot->xgridmin;
  964.         vt[1] = plot->xgridmax;
  965.     }
  966.  
  967.     if (plot->ymes != LIN)                        /* log.    Transformation            */
  968.     {
  969.         vt[2] = ylogfct(plot->ygridmin);
  970.         vt[3] = ylogfct(plot->ygridmax);
  971.     }
  972.     else                                                            /* lineare Transformation        */
  973.     {
  974.         vt[2] = plot->ygridmin;
  975.         vt[3] = plot->ygridmax;
  976.     }
  977.  
  978.     if (plot->zmes != LIN)                        /* log. Transformation            */
  979.     {
  980.         vt[4] = zlogfct(plot->zgridmin);
  981.         vt[5] = zlogfct(plot->zgridmax);
  982.     }
  983.     else                                                            /* lineare Transformation        */
  984.     {
  985.         vt[4] = plot->zgridmin;
  986.         vt[5] = plot->zgridmax;
  987.     }
  988.  
  989. /****************************************************************
  990. *                                                                                                                                *
  991. *    Berechnen der Einheitsskalierung. Bei einer multiplikation        *
  992. *    von f?scale mit den Grenzen der Achsen überstreichen alle            *
  993. *    Achsen den gleichen Bereich. Sie werden dadurch im 3D-Bereich    *
  994. *    gleich lang dargestellt.                                                                            *
  995. *                                                                                                                                *
  996. ****************************************************************/
  997.  
  998.     fxscale = 10000/(vt[1]-vt[0]);        /* X-Achse                                    */
  999.     fyscale = 10000/(vt[3]-vt[2]);        /* Y-Achse                                    */
  1000.     fzscale = 10000/(vt[5]-vt[4]);        /* Z-Achse                                    */
  1001.  
  1002. /****************************************************************
  1003. *                                                                                                                                *
  1004. *    Transformation auf die Einheitsskalierung                                            *
  1005. *                                                                                                                                *
  1006. ****************************************************************/
  1007.  
  1008.     vt[0] = vt[0]*fxscale;                        /* X-Achse minimum                    */
  1009.     vt[1] = vt[1]*fxscale;                        /* X-Achse maximum                    */
  1010.     vt[2] = vt[2]*fyscale;                        /* Y-Achse minimum                    */
  1011.     vt[3] = vt[3]*fyscale;                        /* Y-Achse maximum                    */
  1012.     vt[4] = vt[4]*fzscale;                        /* Z-Achse minimum                    */
  1013.     vt[5] = vt[5]*fzscale;                        /* Z-Achse maximum                    */
  1014.  
  1015. /****************************************************************
  1016. *                                                                                                                                *
  1017. *    Initialisieren der projezierten Koordinaten                                        *
  1018. *                                                                                                                                *
  1019. ****************************************************************/
  1020.  
  1021.     ul = 1e30;                                                /* X-Achse 2D                                */
  1022.     ur = -ul;                                                    /* X-Achse 2D                                */
  1023.     vl = 1e30;                                                /* Y-Achse 2D                                */
  1024.     vr = -vl;                                                    /* Y-Achse 2D                                */
  1025.  
  1026. /****************************************************************
  1027. *                                                                                                                                *
  1028. *    Festlegung des Betrachtungspunktes                                                        *
  1029. *                                                                                                                                *
  1030. ****************************************************************/
  1031.  
  1032.     plot->xcenter = (vt[0]+vt[1])/2;    /* X-Achsenmitte                        */
  1033.     plot->ycenter = (vt[2]+vt[3])/2;    /* Z-Achsenmitte                        */
  1034.     plot->zcenter = 1e30;                            /* Z-Achse weit weit hinten    */
  1035.  
  1036. /****************************************************************
  1037. *                                                                                                                                *
  1038. *    Berechnen der Grenzwerte auf der Bildschirmebene                            *
  1039. *                                                                                                                                *
  1040. *    Alle Eckpunkte des Koordinatenwürfels werden transformiert        *
  1041. *    und die max. Projektionswerte werden festgehalten. Diese            *
  1042. *    Werte müssen danach so skaliert werden, dass sie auf dem            *
  1043. *    Bildschirmbereich liegen.                                                                            *
  1044. *                                                                                                                                *
  1045. ****************************************************************/
  1046.  
  1047.     for (i=0;i<8;i++)
  1048.     {
  1049.  
  1050. /****************************************************************
  1051. *                                                                                                                                *
  1052. *    Rotation um x-, y- und z-Achse in dieser Reihenfolge                    *
  1053. *                                                                                                                                *
  1054. ****************************************************************/
  1055.  
  1056.         x = vt[pt[i][0]]*xr1 + vt[pt[i][1]]*xr2 + vt[pt[i][2]]*xr3;
  1057.         y = vt[pt[i][0]]*yr1 + vt[pt[i][1]]*yr2 + vt[pt[i][2]]*yr3;
  1058.         z = vt[pt[i][0]]*zr1 + vt[pt[i][1]]*zr2 + vt[pt[i][2]]*zr3;
  1059.  
  1060. /****************************************************************
  1061. *                                                                                                                                *
  1062. *    Projektion auf die Bildschirmebene                                                        *
  1063. *                                                                                                                                *
  1064. ****************************************************************/
  1065.  
  1066.         divs = z-plot->zcenter;
  1067.         u = (z*plot->xcenter-x*plot->zcenter)/divs;
  1068.         v = (z*plot->ycenter-y*plot->zcenter)/divs;
  1069.  
  1070.         if (u<ul) ul = u;                                /* max. Werte nach Pro-            */
  1071.         if (u>ur) ur = u;                                /* jektion zuweisen für            */
  1072.         if (v<vl) vl = v;                                /* beide Achsen                            */
  1073.         if (v>vr) vr = v;
  1074.     }
  1075.  
  1076. /****************************************************************
  1077. *                                                                                                                                *
  1078. *    Berechnung der Skalierung mit den max. Werten                                    *
  1079. *                                                                                                                                *
  1080. ****************************************************************/
  1081.  
  1082.     xscale = (plot->xpic2-plot->xpic1)/(ur-ul);
  1083.     yscale = (plot->ypic2-plot->ypic1)/(vr-vl);
  1084.  
  1085. /****************************************************************
  1086. *                                                                                                                                *
  1087. *    Berechnung der Verschiebung mit den max. Werten                                *
  1088. *                                                                                                                                *
  1089. ****************************************************************/
  1090.  
  1091.     xoffset = (plot->xpic1*ur-plot->xpic2*ul)/(ur-ul);
  1092.     yoffset = (plot->ypic2*vr-plot->ypic1*vl)/(vr-vl);
  1093.  
  1094. }
  1095.  
  1096. /****************************************************************
  1097. *                                                                                                                                *
  1098. *    Function : ClearHidden()                                                                            *
  1099. *                                                                                                                                *
  1100. *****************************************************************
  1101. *                                                                                                                                *
  1102. *         Input : void                                                                                                *
  1103. *                                                                                                                                *
  1104. *        Output : void                                                                                                *
  1105. *                                                                                                                                *
  1106. *****************************************************************
  1107. *                                                                                                                                *
  1108. *     Comment : Diese Funktion initialisiert die beiden Horizonte    *
  1109. *                         auf die min. bzw. max. Werte. Danach kann der            *
  1110. *                         Hiddenlinealgorithmus neu gestartet werden.                *
  1111. *                                                                                                                                *
  1112. ****************************************************************/
  1113.  
  1114. static void clearhidden()
  1115. {
  1116.     register i;
  1117.     register GPT *tv1,*bv1,                        /* Arrayzeiger                            */
  1118.                              min,max;                            /* Init. -werte                            */
  1119.  
  1120.     min = (GPT)plot->ypic2;                        /* Zuweisen der Init.-            */
  1121.     max = (GPT)plot->ypic1;                        /* werte                                        */
  1122.  
  1123.     tv1 = tv;                                                    /* Adressen zuweisen der        */
  1124.     bv1 = bv;                                                    /* beiden Horizonte                    */
  1125.     for (i=0;i<=plot->xpic2;i++)            /* alle Felder init.                */
  1126.     {
  1127.         *tv1++ = min;                                        /* top mit bottom init.            */
  1128.         *bv1++ = max;                                        /* bot mit top init.                */
  1129.     }
  1130. }
  1131.  
  1132. /****************************************************************
  1133. *                                                                                                                                *
  1134. *    Function : InitHidden()                                                                                *
  1135. *                                                                                                                                *
  1136. *****************************************************************
  1137. *                                                                                                                                *
  1138. *         Input : void                                                                                                *
  1139. *                                                                                                                                *
  1140. *        Output : int                        allg. Rückgabewert                                    *
  1141. *                            != FALSE        alle klar                                                        *
  1142. *                            == FALSE            Fehler                                                            *
  1143. *                                                                                                                                *
  1144. *****************************************************************
  1145. *                                                                                                                                *
  1146. *     Comment : Diese Funktion alloziert den notwendigen Speicher    *
  1147. *                         für den Hiddenline Algorithmus.                                        *
  1148. *                                                                                                                                *
  1149. ****************************************************************/
  1150.  
  1151. static int inithidden()
  1152. {
  1153.     tv = malloc((plot->xpic2+2)*sizeof(GPT));
  1154.     bv = malloc((plot->xpic2+2)*sizeof(GPT));
  1155.     if ((tv)and(bv))                                    /* Wenn Speicher bekommen        */
  1156.     {
  1157.         clearhidden();                                    /* diesen initialisieren        */
  1158.         return(TRUE);                                        /* alles klar                                */
  1159.     }
  1160.     else                                                            /* sonst mit Fehler zurück    */
  1161.     {
  1162.         seterror(HIDDENMEM);
  1163.         return(FALSE);
  1164.     }
  1165. }
  1166.  
  1167. /****************************************************************
  1168. *                                                                                                                                *
  1169. *    Function : FreeHidden()                                                                                *
  1170. *                                                                                                                                *
  1171. *****************************************************************
  1172. *                                                                                                                                *
  1173. *         Input : void                                                                                                *
  1174. *                                                                                                                                *
  1175. *        Output : void                                                                                                *
  1176. *                                                                                                                                *
  1177. *****************************************************************
  1178. *                                                                                                                                *
  1179. *     Comment : Diese Funktion gibt den allozierten Speicher für        *
  1180. *                         den Hiddenlinealgorithmus an das System zurück.        *
  1181. *                                                                                                                                *
  1182. ****************************************************************/
  1183.  
  1184. static void freehidden()
  1185. {
  1186.     if (tv) free(tv);                                    /* Tophorizont                            */
  1187.     if (bv) free(bv);                                    /* Bottomhorizont                        */
  1188. }
  1189.  
  1190. /****************************************************************
  1191. *                                                                                                                                *
  1192. *    Function : initrotation()                                                                            *
  1193. *                                                                                                                                *
  1194. *****************************************************************
  1195. *                                                                                                                                *
  1196. *         Input : void                                                                                                *
  1197. *                                                                                                                                *
  1198. *        Output : void                                                                                                *
  1199. *                                                                                                                                *
  1200. *****************************************************************
  1201. *                                                                                                                                *
  1202. *     Comment : Initialisiert die global statischen Rotations-            *
  1203. *                         variablen xr1,xr2 .. zr3.                                                    *
  1204. *                         Die Rotation erfolgt zuerst mit der X-Achse,                *
  1205. *                         danach folgt die Y-Achse und amm Schluss wird noch    *
  1206. *                         um die Z-Achse rotiert.                                                        *
  1207. *                                                                                                                                *
  1208. *                         Die Herleitung dieser Funktionen ist in der                *
  1209. *                         Diplomarbeit zu finden.                                                        *
  1210. *                                                                                                                                *
  1211. ****************************************************************/
  1212.  
  1213. static void initrotation()
  1214. {
  1215.  
  1216.     static DATA rad = 0.01745329;            /* Umrechnungsfaktor                */
  1217.  
  1218.     DATA px,py,pz;                                        /* Rotationswinkel in Rad.    */
  1219.  
  1220.     px = plot->phix*rad;                            /* Umrechnen der Rotations-    */
  1221.     py = plot->phiy*rad;                            /* winkel von Grad nach            */
  1222.     pz = plot->phiz*rad;                            /* Radiant                                    */
  1223.  
  1224.     xr1 =  cos(py)*cos(pz);                        /* Berechnen der Rotations-    */
  1225.     xr2 =  cos(py)*sin(pz);                        /* faktoren für die ver-        */
  1226.     xr3 = -sin(py);                                        /* schiedenen Achsen                */
  1227.  
  1228.     yr1 =  sin(px)*cos(py)*cos(pz)-cos(px)*sin(pz);
  1229.     yr2 =  sin(px)*sin(py)*sin(pz)+cos(px)*cos(pz);
  1230.     yr3 =  sin(px)*cos(py);
  1231.  
  1232.     zr1 =  cos(px)*sin(py)*cos(pz)+sin(px)*sin(pz);
  1233.     zr2 =  cos(px)*sin(py)*sin(pz)-sin(px)*cos(pz);
  1234.     zr3 =  cos(px)*cos(py);
  1235.  
  1236. }
  1237.  
  1238.