home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume8 / xfig2.8 / part03 / curve.c < prev    next >
C/C++ Source or Header  |  1990-07-02  |  3KB  |  139 lines

  1. /* 
  2.  *    FIG : Facility for Interactive Generation of figures
  3.  *
  4.  *    Copyright (c) 1985 by Supoj Sutanthavibul (supoj@sally.UTEXAS.EDU)
  5.  *    January 1985.
  6.  *    1st revision : Aug 1985.
  7.  *
  8.  *    %W%    %G%
  9. */
  10. #include "fig.h"
  11. #include "resources.h"
  12. #include "paintop.h"
  13.  
  14. #define        round(a)    ((int)((a) + .5))
  15.  
  16. /*    This routine plot two dimensional curve defined by a second degree
  17.     polynomial of the form :
  18.                 2    2
  19.         f(x, y) = ax + by + g = 0
  20.  
  21.     (x0,y0) is the starting point as well as ending point of the curve.
  22.     The curve will translate with the offset xoff and yoff.
  23.  
  24.     This algorithm is derived from the eight point algorithm in :
  25.     "An Improved Algorithm for the generation of Nonparametric Curves"
  26.     by Bernard W. Jordan, William J. Lennon and Barry D. Holm, IEEE
  27.     Transaction on Computers Vol C-22, No. 12 December 1973.
  28.  
  29.     Will fill the curve if area_fill is != 0
  30. */
  31.  
  32.  
  33. curve(window, xstart, ystart, xend, yend, direction, 
  34.         a, b, xoff, yoff, val, thick, style, style_val, area_fill)
  35. Window    window;
  36. int    xstart, ystart, xend, yend, a, b, xoff, yoff;
  37. int    direction, val, thick, style, area_fill;
  38. float    style_val;
  39. {
  40.     int    dfx, dfy, dfxx, dfyy;
  41.     int    falpha, fx, fy, fxy, absfx, absfy, absfxy;
  42.     int    margin, test_succeed, x, y, deltax, deltay, inc, dec;
  43.     int    npoints;
  44.     int    max_points;
  45.     XPoint    *points;
  46.     
  47.     if (a == 0 || b == 0) 
  48.         return;
  49.  
  50.     max_points = a + b + 1;        /* 1 for end point */
  51.     if (max_points > 4000)
  52.         max_points = 4000;
  53.     if ((points = (XPoint *) malloc(max_points*sizeof(XPoint))) == 0)
  54.         {
  55.         fprintf(stderr,"curve(): No memory\n");
  56.         return;
  57.         }
  58.  
  59.     x    = xstart;
  60.     y    = ystart;
  61.     dfx  = 2 * a * xstart;
  62.     dfy  = 2 * b * ystart;
  63.     dfxx = 2 * a;
  64.     dfyy = 2 * b;
  65.  
  66.     falpha = 0;
  67.     if (direction) {
  68.         inc = 1;  dec = -1;
  69.         }
  70.     else {
  71.         inc = -1;  dec = 1;
  72.         }
  73.     if (xstart == xend && ystart == yend) {
  74.         test_succeed = margin = 1;
  75.         }
  76.     else {
  77.         test_succeed = 3; margin = 3; 
  78.         }
  79.  
  80.     npoints = 0;
  81.     while (test_succeed) {
  82.         if (npoints >= (max_points-1))
  83.             {
  84.         XPoint    *tmp_p;
  85.  
  86.         max_points += a + b;
  87.         if (max_points > 4000)
  88.             break;        /* stop!  It is not closing */
  89.  
  90.         if ((tmp_p = (XPoint *) realloc(points, max_points*sizeof(XPoint))) == 0)
  91.             {
  92.             fprintf(stderr,"curve(): No memory(realloc)\n");
  93.             break;
  94.             }
  95.         free(points);
  96.         points = tmp_p;
  97.             }
  98.         points[npoints].x = (short) xoff+x;
  99.         points[npoints].y = (short) yoff-y;
  100.         npoints++;
  101.  
  102.         if (dfy < 0) 
  103.         deltax = inc; 
  104.         else 
  105.         deltax = dec;
  106.         if (dfx < 0) 
  107.         deltay = dec; 
  108.         else 
  109.         deltay = inc;
  110.         fx  = falpha + dfx * deltax + a;
  111.         fy  = falpha + dfy * deltay + b;
  112.         fxy = fx + fy - falpha;
  113.         absfx  = abs(fx); absfy  = abs(fy); absfxy = abs(fxy);
  114.  
  115.         if ((absfxy <= absfx) && (absfxy <= absfy))
  116.         falpha = fxy;
  117.         else if (absfy <= absfx) {
  118.         deltax = 0; falpha = fy;
  119.         }
  120.         else {
  121.         deltay = 0; falpha = fx;
  122.         }
  123.         x = x + deltax;  y = y + deltay;
  124.         dfx = dfx + dfxx * deltax;
  125.         dfy = dfy + dfyy * deltay;
  126.         if (abs(x - xend) < margin && abs(y - yend) < margin) 
  127.         test_succeed--;
  128.         }
  129.  
  130.     if (margin == 1)    /* end points should touch */
  131.         {
  132.         points[npoints].x = (short) xoff+xstart;
  133.         points[npoints].y = (short) yoff-ystart;
  134.         }
  135.     pw_lines(window, points, npoints, val? PAINT: ERASE,
  136.             thick, style, style_val, area_fill);
  137.     free(points);
  138.     }
  139.