home *** CD-ROM | disk | FTP | other *** search
/ gondwana.ecr.mu.oz.au/pub/ / Graphics.tar / Graphics / VOGLE.ZIP / VOGLE / SRC / ARCS.C next >
Encoding:
C/C++ Source or Header  |  2000-02-11  |  4.4 KB  |  239 lines

  1. #include "vogle.h"
  2.  
  3. #ifdef    TC
  4.  
  5. extern    double    cos();
  6. extern    double    sin();
  7.  
  8. #else 
  9.  
  10. #include <math.h>
  11.  
  12. #endif
  13.  
  14. static int    nsegs = 32;
  15.  
  16. /*
  17.  * arcprecision
  18.  *
  19.  *    sets the number of segments in an arc or circle.
  20.  *    - obsolete function.
  21.  */
  22. void
  23. arcprecision(noseg)
  24.     int    noseg;
  25. {
  26.     nsegs = noseg;
  27. }
  28.  
  29. /*
  30.  * circleprecision
  31.  *
  32.  *    sets the number of segments in an arc or circle.
  33.  */
  34. void
  35. circleprecision(noseg)
  36.     int    noseg;
  37. {
  38.     nsegs = noseg;
  39. }
  40.  
  41. /*
  42.  * arc
  43.  *
  44.  * draw an arc at a given location.  Precision of arc (# line segments)
  45.  * is calculated from the value given to circleprecision.
  46.  *
  47.  */
  48. void
  49. arc(x, y, radius, startang, endang)
  50.     float    x, y, radius;
  51.     float    startang, endang;
  52. {
  53.     Token    *t;
  54.     float    cx, cy, dx, dy;
  55.     float    deltang, cosine, sine, angle;
  56.     int    sync, i, numsegs;
  57.  
  58.     if (!vdevice.initialised)
  59.         verror("arc: vogle not initialised");
  60.  
  61.     if ((sync = vdevice.sync))
  62.         vdevice.sync = 0;
  63.  
  64.     angle = startang * D2R;
  65.     numsegs = (endang - startang) / 360.0 * nsegs + 0.5;
  66.     deltang = (endang - startang) * D2R / numsegs;
  67.     cosine = cos((double)deltang);
  68.     sine = sin((double)deltang);
  69.  
  70.     if (vdevice.inobject) {
  71.         t = newtokens(8);
  72.         t[0].i = ARC;
  73.         t[1].f = x;
  74.         t[2].f = y;
  75.         t[3].f = radius * cos((double)angle);
  76.         t[4].f = radius * sin((double)angle);
  77.         t[5].f = cosine;
  78.         t[6].f = sine;
  79.         t[7].i = numsegs;
  80.         return;
  81.     }
  82.  
  83.     /* calculates initial point on arc */
  84.  
  85.     cx = x + radius * cos((double)angle);
  86.     cy = y + radius * sin((double)angle);
  87.     move2(cx, cy);
  88.  
  89.     for (i = 0; i < numsegs; i++)  {
  90.         dx = cx - x; 
  91.         dy = cy - y;
  92.         cx = x + dx * cosine - dy * sine;
  93.         cy = y + dx * sine + dy * cosine;
  94.         draw2(cx, cy);
  95.     }
  96.  
  97.     if (sync) {
  98.         vdevice.sync = 1;
  99.         (*vdevice.dev.Vsync)();
  100.     }
  101. }
  102.  
  103. /*
  104.  * sector
  105.  *
  106.  *    draw a sector in a given location. The number of line segments in the
  107.  * arc of the segment is the same as in arc.
  108.  */
  109. void
  110. sector(x, y, radius, startang, endang)
  111.     float    x, y, radius;
  112.     float    startang, endang;
  113. {
  114.     Token    *t;
  115.     float    cx, cy, dx, dy;
  116.     float    deltang, cosine, sine, angle;
  117.     int    sync, i, numsegs, inpoly;
  118.  
  119.     if (!vdevice.initialised)
  120.         verror("segment: vogle not initialised");
  121.  
  122.     angle = startang * D2R;
  123.     numsegs = (endang - startang) / 360.0 * nsegs + 0.5;
  124.     deltang = (endang - startang) * D2R / numsegs;
  125.     cosine = cos((double)deltang);
  126.     sine = sin((double)deltang);
  127.  
  128.     if (vdevice.inobject) {
  129.         t = newtokens(8);
  130.         t[0].i = SECTOR;
  131.         t[1].f = x;
  132.         t[2].f = y;
  133.         t[3].f = radius * cos((double)angle);
  134.         t[4].f = radius * sin((double)angle);
  135.         t[5].f = cosine;
  136.         t[6].f = sine;
  137.         t[7].i = numsegs;
  138.         return;
  139.     }
  140.  
  141.     if ((sync = vdevice.sync))
  142.         vdevice.sync = 0;
  143.  
  144.     inpoly = vdevice.inpolygon;
  145.  
  146.     if ((vdevice.attr->a.fill || vdevice.attr->a.hatch) && !inpoly)
  147.         makepoly();        /* want it filled */
  148.  
  149.     move2(x, y);
  150.             /* calculates initial point on arc */
  151.  
  152.     cx = x + radius * cos((double)angle);
  153.     cy = y + radius * sin((double)angle);
  154.  
  155.     draw2(cx, cy);
  156.  
  157.     for (i = 0; i < numsegs; i++)  {
  158.         dx = cx - x; 
  159.         dy = cy - y;
  160.         cx = x + dx * cosine - dy * sine;
  161.         cy = y + dx * sine + dy * cosine;
  162.         draw2(cx, cy);
  163.     }
  164.  
  165.     if ((vdevice.attr->a.fill || vdevice.attr->a.hatch) && !inpoly)
  166.         closepoly();
  167.     else {
  168.         if (sync)
  169.             vdevice.sync = 1;
  170.  
  171.         draw2(x, y);
  172.     }
  173. }
  174.  
  175. /*
  176.  * circle
  177.  *
  178.  * Draw a circle of given radius at given world coordinates. The number of
  179.  * segments in the circle is the same as that of an arc.
  180.  *
  181.  */
  182. void
  183. circle(x, y, radius)
  184.     float    x, y, radius;
  185. {
  186.     Token    *t;
  187.     float    cx, cy, dx, dy;
  188.     float    angle, cosine, sine;
  189.     int    sync, i, inpoly;
  190.  
  191.     if (!vdevice.initialised)
  192.         verror("circle: vogle not initialised");
  193.  
  194.     angle = 2.0 * PI / nsegs;
  195.     cosine = cos((double)angle);
  196.     sine = sin((double)angle);
  197.  
  198.     if (vdevice.inobject) {
  199.         t = newtokens(7);
  200.         t[0].i = CIRCLE;
  201.         t[1].f = x;
  202.         t[2].f = y;
  203.         t[3].f = radius;
  204.         t[4].f = cosine;
  205.         t[5].f = sine;
  206.         t[6].i = nsegs;
  207.         return;
  208.     }
  209.  
  210.     if ((sync = vdevice.sync))
  211.         vdevice.sync = 0;
  212.  
  213.     cx = x + radius;
  214.     cy = y;
  215.  
  216.     inpoly = vdevice.inpolygon;
  217.  
  218.     if ((vdevice.attr->a.fill || vdevice.attr->a.hatch) && !inpoly)
  219.         makepoly();        /* want it filled */
  220.  
  221.     move2(cx, cy);
  222.     for (i = 0; i < nsegs - 1; i++) {
  223.         dx = cx - x; 
  224.         dy = cy - y;
  225.         cx = x + dx * cosine - dy * sine;
  226.         cy = y + dx * sine + dy * cosine;
  227.         draw2(cx, cy);
  228.     }
  229.  
  230.     if ((vdevice.attr->a.fill || vdevice.attr->a.hatch) && !inpoly)
  231.         closepoly();
  232.     else {
  233.         if (sync)
  234.             vdevice.sync = 1;
  235.  
  236.         draw2(x + radius, y);
  237.     }
  238. }
  239.