home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 344b.lha / plplot_v2.6 / src / plnxtv.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-01-27  |  15.7 KB  |  561 lines

  1. /* Draws the next view of a 3-d plot. The physical coordinates of */
  2. /* the points for the next view are placed in the n points of arrays  */
  3. /* u and v. The silhouette found so far is stored in the heap as a */
  4. /* set of m peak points. */
  5.  
  6. #include "plplot.h"
  7. #include "declare.h"
  8. #include <stdio.h>
  9. #ifdef PLSTDC
  10. #include <stdlib.h>
  11. #else
  12. extern char *malloc();
  13. extern char *realloc();
  14. extern void free();
  15. #endif
  16.  
  17. PLINT pl3mode=0;                 /* 0 3d solid; 1 mesh plot */
  18. PLINT pl3upv=1;                  /* 1 update view; 0 no update */
  19. PLINT *oldhiview;
  20. PLINT *oldloview;
  21.  
  22. /* This routine now dynamically allocates the memory it needs for hidden */
  23. /* line removal.  Memory is allocated in blocks of 2*BINC*sizeof(PLINT) */
  24. /* bytes.  Large values of BINC give better performance but also */
  25. /* allocate more memory than is needed. If your 3D plots are very */
  26. /* "spiky" or you are working with very large matrices then you will */
  27. /* probably want to increase BINC. */
  28.  
  29. #define  BINC      50
  30.  
  31. static PLINT *newhiview;
  32. static PLINT *newloview;
  33. static PLINT mhi, xxhi, newhisize;
  34. static PLINT mlo, xxlo, newlosize;
  35.  
  36. void plnxtv(u, v, n, init)
  37. PLINT *u, *v, n, init;
  38. {
  39.    void plnxtvhi(), plnxtvlo();
  40.  
  41.    plnxtvhi(u,v,n,init);
  42.  
  43.    if(pl3mode)
  44.       plnxtvlo(u,v,n,init);
  45. }
  46.  
  47. static void plnxtvhi(u,v,n,init)
  48. PLINT *u, *v, n, init;
  49. {
  50.       PLINT i, j, first;
  51.       PLINT sx1, sx2, sy1, sy2;
  52.       PLINT su1, su2, sv1, sv2;
  53.       PLINT cx, cy, px, py;
  54.       PLINT seg, ptold, lstold, pthi, pnewhi, newhi, change, ochange;
  55.       void savehipoint(), swaphiview();
  56.  
  57.       first = 1;
  58.       pnewhi = 0;
  59.  
  60.       /* For the initial set of points, just display them and store them as */
  61.       /* the peak points. */
  62.  
  63.       if (init == 1) {
  64.          /* heap not yet allocated so ... */
  65.          if(!( oldhiview = (PLINT *)malloc(2*n*sizeof(PLINT))))
  66.             plexit("Out of memory.");
  67.          movphy(u[0],v[0]);
  68.          oldhiview[0] = u[0];
  69.          oldhiview[1] = v[0];
  70.          for (i=1; i<n; i++){
  71.            draphy(u[i],v[i]);
  72.            oldhiview[2*i] = u[i];
  73.            oldhiview[2*i+1] = v[i];
  74.          }
  75.          mhi = n;
  76.          return;
  77.       }
  78.  
  79.       /* Otherwise, we need to consider hidden-line removal problem. We scan */
  80.       /* over the points in both the old (i.e. oldhiview[]) and */
  81.       /* new (i.e. u[] and v[]) arrays in order of increasing x coordinate. */
  82.       /* At each stage, we find the line segment in the other array (if one */
  83.       /* exists) that straddles the x coordinate of the point. We */
  84.       /* have to determine if the point lies above or below the line segment, */
  85.       /* and to check if the below/above status has changed since the last */
  86.       /* point. */
  87.  
  88.       /* If pl3upv = 0 we do not update the view, this is useful for drawing */
  89.       /* lines on the graph after we are done plotting points.  Hidden line */
  90.       /* removal is still done, but the view is not updated. */
  91.       xxhi = 0;
  92.       i = 0;
  93.       j = 0;
  94.       if(pl3upv != 0) {
  95.          newhisize = 2*(mhi+BINC);
  96.          if(!( newhiview = (PLINT *)malloc(newhisize*sizeof(PLINT)))) {
  97.             free((VOID *)oldhiview);
  98.             plexit("Out of memory.");
  99.          }
  100.       }
  101.  
  102.       /* (oldhiview[2*i], oldhiview[2*i]) is the i'th point in the old array */
  103.       /* (u[j], v[j])           is the j'th point in the new array */
  104.  
  105.       while (i < mhi || j < n) {
  106.  
  107.         /* The coordinates of the point under consideration are (px,py). */
  108.         /* The line segment joins (sx1,sy1) to (sx2,sy2). */
  109.  
  110.         /* "ptold" is true if the point lies in the old array. We set it */
  111.         /*  by comparing the x coordinates of the i'th old point */
  112.         /*  and the j'th new point, being careful if we have fallen past */
  113.         /*  the edges. Having found the point, load up the point and */
  114.         /*  segment coordinates appropriately. */
  115.  
  116.         ptold = ((oldhiview[2*i] < u[j] && i<mhi) || j>= n);
  117.         if (ptold) {
  118.           px = oldhiview[2*i];
  119.           py = oldhiview[2*i+1];
  120.           seg = j>0 && j<n;
  121.           if (seg) {
  122.             sx1 = u[j-1];
  123.             sy1 = v[j-1];
  124.             sx2 = u[j];
  125.             sy2 = v[j];
  126.           }
  127.         }
  128.         else {
  129.           px = u[j];
  130.           py = v[j];
  131.           seg = i>0 && i<mhi;
  132.           if (seg) {
  133.             sx1 = oldhiview[2*(i-1)];
  134.             sy1 = oldhiview[2*(i-1)+1];
  135.             sx2 = oldhiview[2*i];
  136.             sy2 = oldhiview[2*i+1];
  137.           }
  138.         }
  139.  
  140.         /* Now determine if the point is higher than the segment, using the */
  141.         /* logical function "above". We also need to know if it is */
  142.         /* the old view or the new view that is higher. "newhi" is set true */
  143.         /* if the new view is higher than the old */
  144.  
  145.         if(seg)
  146.             pthi = plabv(px,py,sx1,sy1,sx2,sy2);
  147.         else
  148.             pthi = 1;
  149.  
  150.         newhi = (ptold && !pthi) || (!ptold && pthi);
  151.         change = (newhi && !pnewhi) || (!newhi && pnewhi);
  152.  
  153.         /* There is a new intersection point to put in the peak array if the */
  154.         /* state of "newhi" changes */
  155.  
  156.         if (first) {
  157.           movphy(px,py);
  158.           first = 0;
  159.           lstold = ptold;
  160.           savehipoint(px,py);
  161.           pthi = 0;
  162.           ochange = 0;
  163.         }
  164.         else if (change) {
  165.           /* Take care of special cases at end of arrays.  If pl3upv */
  166.           /* is 0 the endpoints are not connected to the old view. */
  167.           if (pl3upv==0 && ((!ptold && j==0)||(ptold && i==0))) {
  168.             movphy(px,py);
  169.             lstold = ptold;
  170.             pthi = 0;
  171.             ochange = 0;
  172.           }
  173.           else if (pl3upv==0 && ((!ptold && i>=mhi)||(ptold && j>=n))) {
  174.             movphy(px,py);
  175.             lstold = ptold;
  176.             pthi = 0;
  177.             ochange = 0;
  178.           }
  179.           /* If pl3upv is not 0 then we do want to connect the current line */
  180.           /* with the previous view at the endpoints.  */
  181.           /* Also find intersection point with old view. */
  182.           else  {
  183.             if (i == 0) {
  184.               sx1 = oldhiview[0];
  185.               sy1 = -1;
  186.               sx2 = oldhiview[0];
  187.               sy2 = oldhiview[1];
  188.             }
  189.             else if (i >= mhi) {
  190.               sx1 = oldhiview[2*(mhi-1)];
  191.               sy1 = oldhiview[2*(mhi-1)+1];
  192.               sx2 = oldhiview[2*(mhi-1)];
  193.               sy2 = -1;
  194.             }
  195.             else {
  196.               sx1 = oldhiview[2*(i-1)];
  197.               sy1 = oldhiview[2*(i-1)+1];
  198.               sx2 = oldhiview[2*i];
  199.               sy2 = oldhiview[2*i+1];
  200.             }
  201.  
  202.             if (j == 0) {
  203.               su1 = u[0];
  204.               sv1 = -1;
  205.               su2 = u[0];
  206.               sv2 = v[0];
  207.             }
  208.             else if (j >= n) {
  209.               su1 = u[n-1];
  210.               sv1 = v[n-1];
  211.               su2 = u[n];
  212.               sv2 = -1;
  213.             }
  214.             else  {
  215.               su1 = u[j-1];
  216.               sv1 = v[j-1];
  217.               su2 = u[j];
  218.               sv2 = v[j];
  219.             }
  220.  
  221.             /* Determine the intersection */
  222.             pl3cut(sx1,sy1,sx2,sy2,su1,sv1,su2,sv2,&cx,&cy);
  223.             if (cx == px && cy == py)  {
  224.               if (lstold && !ochange)
  225.                 movphy(px,py);
  226.               else
  227.                 draphy(px,py);
  228.  
  229.               savehipoint(px,py);
  230.               lstold = 1;
  231.               pthi = 0;
  232.             }
  233.             else {
  234.               if (lstold && !ochange)
  235.                  movphy(cx,cy);
  236.               else
  237.                  draphy(cx,cy);
  238.  
  239.               lstold = 1;
  240.               savehipoint(cx,cy);
  241.             }
  242.             ochange =1;
  243.           }
  244.         }
  245.  
  246.         /* If point is high then draw plot to point and update view. */
  247.         if (pthi) {
  248.           if (lstold && ptold)
  249.             movphy(px,py);
  250.           else
  251.             draphy(px,py);
  252.  
  253.           savehipoint(px,py);
  254.           lstold = ptold;
  255.           ochange = 0;
  256.         }
  257.  
  258.         pnewhi = newhi;
  259.  
  260.         if (ptold)
  261.           i = i+1;
  262.         else
  263.           j = j+1;
  264.       }
  265.  
  266.       /* Set oldhiview */
  267.       swaphiview();
  268. }
  269.  
  270. static void savehipoint(px, py)
  271. PLINT px, py;
  272. {
  273.    PLINT *temp;
  274.  
  275.    if(pl3upv == 0)
  276.       return;
  277.    if( xxhi >= newhisize )  {
  278.       /* allocate additional space */
  279.       newhisize += 2*BINC;
  280.       if(!(temp = (PLINT *)realloc((VOID *)newhiview,newhisize*sizeof(PLINT)))) {
  281.          free((VOID *)oldhiview);
  282.          free((VOID *)newhiview);
  283.          plexit("Out of memory.");
  284.       }
  285.       newhiview = temp;
  286.    }
  287.  
  288.    newhiview[xxhi] = px;
  289.    xxhi++;
  290.    newhiview[xxhi] = py;
  291.    xxhi++;
  292. }
  293.  
  294. static void swaphiview()
  295. {
  296.    if(pl3upv != 0) {
  297.      mhi = xxhi/2;
  298.      free((VOID *)oldhiview);
  299.      oldhiview = newhiview;
  300.    }
  301. }
  302.  
  303. static void plnxtvlo(u,v,n,init)
  304. PLINT *u, *v, n, init;
  305. {
  306.       PLINT i, j, first;
  307.       PLINT sx1, sx2, sy1, sy2;
  308.       PLINT su1, su2, sv1, sv2;
  309.       PLINT cx, cy, px, py;
  310.       PLINT seg, ptold, lstold, ptlo, pnewlo, newlo, change, ochange;
  311.       void savelopoint(), swaploview();
  312.  
  313.       first = 1;
  314.       pnewlo = 0;
  315.  
  316.       /* For the initial set of points, just display them and store them as */
  317.       /* the peak points. */
  318.  
  319.       if (init == 1) {
  320.          /* heap not yet allocated so ... */
  321.          if(!( oldloview = (PLINT *)malloc(2*n*sizeof(PLINT))))
  322.             plexit("Out of memory.");
  323.          movphy(u[0],v[0]);
  324.          oldloview[0] = u[0];
  325.          oldloview[1] = v[0];
  326.          for (i=1; i<n; i++){
  327.            draphy(u[i],v[i]);
  328.            oldloview[2*i] = u[i];
  329.            oldloview[2*i+1] = v[i];
  330.          }
  331.          mlo = n;
  332.          return;
  333.       }
  334.  
  335.       /* Otherwise, we need to consider hidden-line removal problem. We scan */
  336.       /* over the points in both the old (i.e. oldloview[]) and */
  337.       /* new (i.e. u[] and v[]) arrays in order of increasing x coordinate. */
  338.       /* At each stage, we find the line segment in the other array (if one */
  339.       /* exists) that straddles the x coordinate of the point. We */
  340.       /* have to determine if the point lies above or below the line segment, */
  341.       /* and to check if the below/above status has changed since the last */
  342.       /* point. */
  343.  
  344.       /* If pl3upv = 0 we do not update the view, this is useful for drawing */
  345.       /* lines on the graph after we are done plotting points.  Hidden line */
  346.       /* removal is still done, but the view is not updated. */
  347.       xxlo = 0;
  348.       i = 0;
  349.       j = 0;
  350.       if(pl3upv != 0) {
  351.          newlosize = 2*(mlo+BINC);
  352.          if(!( newloview = (PLINT *)malloc(newlosize*sizeof(PLINT)))) {
  353.             free((VOID *)oldloview);
  354.             plexit("Out of memory.");
  355.          }
  356.       }
  357.  
  358.       /* (oldloview[2*i], oldloview[2*i]) is the i'th point in the old array */
  359.       /* (u[j], v[j])           is the j'th point in the new array */
  360.  
  361.       while (i < mlo || j < n) {
  362.  
  363.         /* The coordinates of the point under consideration are (px,py). */
  364.         /* The line segment joins (sx1,sy1) to (sx2,sy2). */
  365.  
  366.         /* "ptold" is true if the point lies in the old array. We set it */
  367.         /*  by comparing the x coordinates of the i'th old point */
  368.         /*  and the j'th new point, being careful if we have fallen past */
  369.         /*  the edges. Having found the point, load up the point and */
  370.         /*  segment coordinates appropriately. */
  371.  
  372.         ptold = ((oldloview[2*i] < u[j] && i<mlo) || j>= n);
  373.         if (ptold) {
  374.           px = oldloview[2*i];
  375.           py = oldloview[2*i+1];
  376.           seg = j>0 && j<n;
  377.           if (seg) {
  378.             sx1 = u[j-1];
  379.             sy1 = v[j-1];
  380.             sx2 = u[j];
  381.             sy2 = v[j];
  382.           }
  383.         }
  384.         else {
  385.           px = u[j];
  386.           py = v[j];
  387.           seg = i>0 && i<mlo;
  388.           if (seg) {
  389.             sx1 = oldloview[2*(i-1)];
  390.             sy1 = oldloview[2*(i-1)+1];
  391.             sx2 = oldloview[2*i];
  392.             sy2 = oldloview[2*i+1];
  393.           }
  394.         }
  395.  
  396.         /* Now determine if the point is lower than the segment, using the */
  397.         /* logical function "above". We also need to know if it is */
  398.         /* the old view or the new view that is lower. "newlo" is set true */
  399.         /* if the new view is lower than the old */
  400.  
  401.         if(seg)
  402.             ptlo = !plabv(px,py,sx1,sy1,sx2,sy2);
  403.         else
  404.             ptlo = 1;
  405.  
  406.         newlo = (ptold && !ptlo) || (!ptold && ptlo);
  407.         change = (newlo && !pnewlo) || (!newlo && pnewlo);
  408.  
  409.         /* There is a new intersection point to put in the peak array if the */
  410.         /* state of "newlo" changes */
  411.  
  412.         if (first) {
  413.           movphy(px,py);
  414.           first = 0;
  415.           lstold = ptold;
  416.           savelopoint(px,py);
  417.           ptlo = 0;
  418.           ochange = 0;
  419.         }
  420.         else if (change) {
  421.           /* Take care of special cases at end of arrays.  If pl3upv */
  422.           /* is 0 the endpoints are not connected to the old view. */
  423.           if (pl3upv==0 && ((!ptold && j==0)||(ptold && i==0))) {
  424.             movphy(px,py);
  425.             lstold = ptold;
  426.             ptlo = 0;
  427.             ochange = 0;
  428.           }
  429.           else if (pl3upv==0 && ((!ptold && i>=mlo)||(ptold && j>=n))) {
  430.             movphy(px,py);
  431.             lstold = ptold;
  432.             ptlo = 0;
  433.             ochange = 0;
  434.           }
  435.           /* If pl3upv is not 0 then we do want to connect the current line */
  436.           /* with the previous view at the endpoints.  */
  437.           /* Also find intersection point with old view. */
  438.           else  {
  439.             if (i == 0) {
  440.               sx1 = oldloview[0];
  441.               sy1 = 100000;
  442.               sx2 = oldloview[0];
  443.               sy2 = oldloview[1];
  444.             }
  445.             else if (i >= mlo) {
  446.               sx1 = oldloview[2*(mlo-1)];
  447.               sy1 = oldloview[2*(mlo-1)+1];
  448.               sx2 = oldloview[2*(mlo-1)];
  449.               sy2 = 100000;
  450.             }
  451.             else {
  452.               sx1 = oldloview[2*(i-1)];
  453.               sy1 = oldloview[2*(i-1)+1];
  454.               sx2 = oldloview[2*i];
  455.               sy2 = oldloview[2*i+1];
  456.             }
  457.  
  458.             if (j == 0) {
  459.               su1 = u[0];
  460.               sv1 = 100000;
  461.               su2 = u[0];
  462.               sv2 = v[0];
  463.             }
  464.             else if (j >= n) {
  465.               su1 = u[n-1];
  466.               sv1 = v[n-1];
  467.               su2 = u[n];
  468.               sv2 = 100000;
  469.             }
  470.             else  {
  471.               su1 = u[j-1];
  472.               sv1 = v[j-1];
  473.               su2 = u[j];
  474.               sv2 = v[j];
  475.             }
  476.  
  477.             /* Determine the intersection */
  478.             pl3cut(sx1,sy1,sx2,sy2,su1,sv1,su2,sv2,&cx,&cy);
  479.             if (cx == px && cy == py)  {
  480.               if (lstold && !ochange)
  481.                 movphy(px,py);
  482.               else
  483.                 draphy(px,py);
  484.  
  485.               savelopoint(px,py);
  486.               lstold = 1;
  487.               ptlo = 0;
  488.             }
  489.             else {
  490.               if (lstold && !ochange)
  491.                  movphy(cx,cy);
  492.               else
  493.                  draphy(cx,cy);
  494.  
  495.               lstold = 1;
  496.               savelopoint(cx,cy);
  497.             }
  498.             ochange =1;
  499.           }
  500.         }
  501.  
  502.         /* If point is low then draw plot to point and update view. */
  503.         if (ptlo) {
  504.           if (lstold && ptold)
  505.             movphy(px,py);
  506.           else
  507.             draphy(px,py);
  508.  
  509.           savelopoint(px,py);
  510.           lstold = ptold;
  511.           ochange = 0;
  512.         }
  513.  
  514.         pnewlo = newlo;
  515.  
  516.         if (ptold)
  517.           i = i+1;
  518.         else
  519.           j = j+1;
  520.       }
  521.  
  522.       /* Set oldloview */
  523.       swaploview();
  524. }
  525.  
  526. static void savelopoint(px, py)
  527. PLINT px, py;
  528. {
  529.    PLINT *temp;
  530.  
  531.    if(pl3upv == 0)
  532.       return;
  533.    if( xxlo >= newlosize )  {
  534.       /* allocate additional space */
  535.       newlosize += 2*BINC;
  536.       if(!(temp = (PLINT *)realloc((VOID *)newloview,newlosize*sizeof(PLINT)))) {
  537.          free((VOID *)oldloview);
  538.          free((VOID *)newloview);
  539.          plexit("Out of memory.");
  540.       }
  541.       newloview = temp;
  542.    }
  543.  
  544.    newloview[xxlo] = px;
  545.    xxlo++;
  546.    newloview[xxlo] = py;
  547.    xxlo++;
  548. }
  549.  
  550. static void swaploview()
  551. {
  552.    if(pl3upv != 0) {
  553.      mlo = xxlo/2;
  554.      free((VOID *)oldloview);
  555.      oldloview = newloview;
  556.    }
  557. }
  558.  
  559.  
  560.  
  561.