home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / gd201.zip / gd-2.0.1 / gd_arc_f_buggy.c < prev    next >
C/C++ Source or Header  |  2001-04-03  |  16KB  |  742 lines

  1. /* This is potentially great stuff, but fails against the test
  2.    program at the end. This would probably be much more 
  3.    efficent than the implementation currently in gd.c if the 
  4.    errors in the output were corrected. TBB */
  5.  
  6. #if 0
  7.  
  8. #include "gd.h"
  9. #include <math.h>
  10.  
  11. /* Courtesy of F J Franklin. */
  12.  
  13. static gdPoint gdArcClosest (int width, int height, int angle);
  14.  
  15. void
  16. gdImageFilledEllipse (gdImagePtr im, int cx, int cy, int width, int height, int color)
  17. {
  18.   gdImageFilledArc (im, cx, cy, width, height, 0, 360, color, gdChord);
  19. }
  20.  
  21. void
  22. gdImageFilledArc (gdImagePtr im, int cx, int cy, int width, int height, int s, int e, int color, int style)
  23. {
  24.   gdPoint pt[7];
  25.   gdPoint axis_pt[4];
  26.  
  27.   int angle;
  28.  
  29.   int have_s = 0;
  30.   int have_e = 0;
  31.  
  32.   int flip_x = 0;
  33.   int flip_y = 0;
  34.  
  35.   int conquer = 0;
  36.  
  37.   int i;
  38.  
  39.   int a;
  40.   int b;
  41.  
  42.   int x;
  43.   int y;
  44.  
  45.   long s_sin = 0;
  46.   long s_cos = 0;
  47.   long e_sin = 0;
  48.   long e_cos = 0;
  49.  
  50.   long w;            /* a * 2 */
  51.   long h;            /* b * 2 */
  52.  
  53.   long x2;            /* x * 2 */
  54.   long y2;            /* y * 2 */
  55.   long lx2;            /* x * 2 (line) */
  56.   long ly2;            /* y * 2 (line) */
  57.  
  58.   long ws;            /* (a * 2)^2 */
  59.   long hs;            /* (b * 2)^2 */
  60.  
  61.   long whs;            /* (a * 2)^2 * (b * 2)^2 */
  62.  
  63.   long g;            /* decision variable */
  64.   long lg;            /* decision variable (line) */
  65.  
  66.   width = (width & 1) ? (width + 1) : (width);
  67.   height = (height & 1) ? (height + 1) : (height);
  68.  
  69.   a = width / 2;
  70.   b = height / 2;
  71.  
  72.   axis_pt[0].x = a;
  73.   axis_pt[0].y = 0;
  74.   axis_pt[1].x = 0;
  75.   axis_pt[1].y = b;
  76.   axis_pt[2].x = -a;
  77.   axis_pt[2].y = 0;
  78.   axis_pt[3].x = 0;
  79.   axis_pt[3].y = -b;
  80.  
  81.   if (s == e)
  82.     return;
  83.  
  84.   if ((e - s) >= 360)
  85.     {
  86.       s = 0;
  87.       e = 0;
  88.     }
  89.  
  90.   while (s < 0)
  91.     s += 360;
  92.   while (s >= 360)
  93.     s -= 360;
  94.   while (e < 0)
  95.     e += 360;
  96.   while (e >= 360)
  97.     e -= 360;
  98.  
  99.   if (e <= s)
  100.     e += 360;
  101.  
  102.   /* I'm assuming a chord-rule at the moment. Need to add origin to get a
  103.    * pie-rule, but will need to set chord-rule before recursion...
  104.    */
  105.  
  106.   for (i = 0; i < 4; i++)
  107.     {
  108.       if ((s < (i + 1) * 90) && (e > (i + 1) * 90))
  109.     {
  110.       gdImageFilledArc (im, cx, cy, width, height, s, (i + 1) * 90, color, gdChord);
  111.       pt[0] = gdArcClosest (width, height, s);
  112.       pt[0].x += cx;
  113.       pt[0].y += cy;
  114.       pt[1].x = cx + axis_pt[(i + 1) & 3].x;
  115.       pt[1].y = cy + axis_pt[(i + 1) & 3].y;
  116.       if (e <= (i + 2) * 90)
  117.         {
  118.           gdImageFilledArc (im, cx, cy, width, height, (i + 1) * 90, e, color, gdChord);
  119.           pt[2] = gdArcClosest (width, height, e);
  120.           pt[2].x += cx;
  121.           pt[2].y += cy;
  122.           if (style == gdChord)
  123.         {
  124.           gdImageFilledPolygon (im, pt, 3, color);
  125.           gdImagePolygon (im, pt, 3, color);
  126.         }
  127.           else if (style == gdPie)
  128.         {
  129.           pt[3].x = cx;
  130.           pt[3].y = cy;
  131.           gdImageFilledPolygon (im, pt, 4, color);
  132.           gdImagePolygon (im, pt, 4, color);
  133.         }
  134.         }
  135.       else
  136.         {
  137.           gdImageFilledArc (im, cx, cy, width, height, (i + 1) * 90, (i + 2) * 90, color, gdChord);
  138.           pt[2].x = cx + axis_pt[(i + 2) & 3].x;
  139.           pt[2].y = cy + axis_pt[(i + 2) & 3].y;
  140.           if (e <= (i + 3) * 90)
  141.         {
  142.           gdImageFilledArc (im, cx, cy, width, height, (i + 2) * 90, e, color, gdChord);
  143.           pt[3] = gdArcClosest (width, height, e);
  144.           pt[3].x += cx;
  145.           pt[3].y += cy;
  146.           if (style == gdChord)
  147.             {
  148.               gdImageFilledPolygon (im, pt, 4, color);
  149.               gdImagePolygon (im, pt, 4, color);
  150.             }
  151.           else if (style == gdPie)
  152.             {
  153.               pt[4].x = cx;
  154.               pt[4].y = cy;
  155.               gdImageFilledPolygon (im, pt, 5, color);
  156.               gdImagePolygon (im, pt, 5, color);
  157.             }
  158.         }
  159.           else
  160.         {
  161.           gdImageFilledArc (im, cx, cy, width, height, (i + 2) * 90, (i + 3) * 90, color, gdChord);
  162.           pt[3].x = cx + axis_pt[(i + 3) & 3].x;
  163.           pt[3].y = cy + axis_pt[(i + 3) & 3].y;
  164.           if (e <= (i + 4) * 90)
  165.             {
  166.               gdImageFilledArc (im, cx, cy, width, height, (i + 3) * 90, e, color, gdChord);
  167.               pt[4] = gdArcClosest (width, height, e);
  168.               pt[4].x += cx;
  169.               pt[4].y += cy;
  170.               if (style == gdChord)
  171.             {
  172.               gdImageFilledPolygon (im, pt, 5, color);
  173.               gdImagePolygon (im, pt, 5, color);
  174.             }
  175.               else if (style == gdPie)
  176.             {
  177.               pt[5].x = cx;
  178.               pt[5].y = cy;
  179.               gdImageFilledPolygon (im, pt, 6, color);
  180.               gdImagePolygon (im, pt, 6, color);
  181.             }
  182.             }
  183.           else
  184.             {
  185.               gdImageFilledArc (im, cx, cy, width, height, (i + 3) * 90, (i + 4) * 90, color, gdChord);
  186.               pt[4].x = cx + axis_pt[(i + 4) & 3].x;
  187.               pt[4].y = cy + axis_pt[(i + 4) & 3].y;
  188.  
  189.               gdImageFilledArc (im, cx, cy, width, height, (i + 4) * 90, e, color, gdChord);
  190.               pt[5] = gdArcClosest (width, height, e);
  191.               pt[5].x += cx;
  192.               pt[5].y += cy;
  193.               if (style == gdChord)
  194.             {
  195.               gdImageFilledPolygon (im, pt, 6, color);
  196.               gdImagePolygon (im, pt, 6, color);
  197.             }
  198.               else if (style == gdPie)
  199.             {
  200.               pt[6].x = cx;
  201.               pt[6].y = cy;
  202.               gdImageFilledPolygon (im, pt, 7, color);
  203.               gdImagePolygon (im, pt, 7, color);
  204.             }
  205.             }
  206.         }
  207.         }
  208.       return;
  209.     }
  210.     }
  211.  
  212.   /* At this point we have only arcs that lies within a quadrant -
  213.    * map this to first quadrant...
  214.    */
  215.  
  216.   if ((s >= 90) && (e <= 180))
  217.     {
  218.       angle = s;
  219.       s = 180 - e;
  220.       e = 180 - angle;
  221.       flip_x = 1;
  222.     }
  223.   if ((s >= 180) && (e <= 270))
  224.     {
  225.       s = s - 180;
  226.       e = e - 180;
  227.       flip_x = 1;
  228.       flip_y = 1;
  229.     }
  230.   if ((s >= 270) && (e <= 360))
  231.     {
  232.       angle = s;
  233.       s = 360 - e;
  234.       e = 360 - angle;
  235.       flip_y = 1;
  236.     }
  237.  
  238.   if (s == 0)
  239.     {
  240.       s_sin = 0;
  241.       s_cos = (long) ((double) 32768);
  242.     }
  243.   else
  244.     {
  245.       s_sin = (long) ((double) 32768 * sin ((double) s * M_PI / (double) 180));
  246.       s_cos = (long) ((double) 32768 * cos ((double) s * M_PI / (double) 180));
  247.     }
  248.   if (e == 0)
  249.     {
  250.       e_sin = (long) ((double) 32768);
  251.       e_cos = 0;
  252.     }
  253.   else
  254.     {
  255.       e_sin = (long) ((double) 32768 * sin ((double) e * M_PI / (double) 180));
  256.       e_cos = (long) ((double) 32768 * cos ((double) e * M_PI / (double) 180));
  257.     }
  258.  
  259.   w = (long) width;
  260.   h = (long) height;
  261.  
  262.   ws = w * w;
  263.   hs = h * h;
  264.  
  265.   whs = 1;
  266.   while ((ws > 32768) || (hs > 32768))
  267.     {
  268.       ws = (ws + 1) / 2;    /* Unfortunate limitations on integers makes */
  269.       hs = (hs + 1) / 2;    /* drawing large  ellipses problematic...    */
  270.       whs *= 2;
  271.     }
  272.   while ((ws * hs) > (0x04000000L / whs))
  273.     {
  274.       ws = (ws + 1) / 2;
  275.       hs = (hs + 1) / 2;
  276.       whs *= 2;
  277.     }
  278.   whs *= ws * hs;
  279.  
  280.   pt[0].x = w / 2;
  281.   pt[0].y = 0;
  282.  
  283.   pt[2].x = 0;
  284.   pt[2].y = h / 2;
  285.  
  286.   have_s = 0;
  287.   have_e = 0;
  288.  
  289.   if (s == 0)
  290.     have_s = 1;
  291.   if (e == 90)
  292.     have_e = 1;
  293.  
  294.   x2 = w;
  295.   y2 = 0;            /* Starting point is exactly on ellipse */
  296.  
  297.   g = x2 - 1;
  298.   g = g * g * hs + 4 * ws - whs;
  299.  
  300.   while ((x2 * hs) > (y2 * ws))    /* Keep |tangent| > 1 */
  301.     {
  302.       y2 += 2;
  303.       g += ws * 4 * (y2 + 1);
  304.  
  305.       if (g > 0)        /* Need to drop */
  306.     {
  307.       x2 -= 2;
  308.       g -= hs * 4 * x2;
  309.     }
  310.  
  311.       if ((have_s == 0) && ((s_sin * x2) <= (y2 * s_cos)))
  312.     {
  313.       pt[0].x = (int) (x2 / 2);
  314.       pt[0].y = (int) (y2 / 2);
  315.       have_s = 1;
  316.     }
  317.  
  318.       if ((have_e == 0) && ((e_sin * x2) <= (y2 * e_cos)))
  319.     {
  320.       pt[2].x = (int) (x2 / 2);
  321.       pt[2].y = (int) (y2 / 2);
  322.       have_e = 1;
  323.     }
  324.     }
  325.   pt[1].x = (int) (x2 / 2);
  326.   pt[1].y = (int) (y2 / 2);
  327.  
  328.   x2 = 0;
  329.   y2 = h;            /* Starting point is exactly on ellipse */
  330.  
  331.   g = y2 - 1;
  332.   g = g * g * ws + 4 * hs - whs;
  333.  
  334.   while ((x2 * hs) < (y2 * ws))
  335.     {
  336.       x2 += 2;
  337.       g += hs * 4 * (x2 + 1);
  338.  
  339.       if (g > 0)        /* Need to drop */
  340.     {
  341.       y2 -= 2;
  342.       g -= ws * 4 * y2;
  343.     }
  344.  
  345.       if ((have_s == 0) && ((s_sin * x2) >= (y2 * s_cos)))
  346.     {
  347.       pt[0].x = (int) (x2 / 2);
  348.       pt[0].y = (int) (y2 / 2);
  349.       have_s = 1;
  350.     }
  351.  
  352.       if ((have_e == 0) && ((e_sin * x2) >= (y2 * e_cos)))
  353.     {
  354.       pt[2].x = (int) (x2 / 2);
  355.       pt[2].y = (int) (y2 / 2);
  356.       have_e = 1;
  357.     }
  358.     }
  359.  
  360.   if ((have_s == 0) || (have_e == 0))
  361.     return;            /* Bizarre case */
  362.  
  363.   if (style == gdPie)
  364.     {
  365.       pt[3] = pt[0];
  366.       pt[4] = pt[1];
  367.       pt[5] = pt[2];
  368.  
  369.       pt[0].x = cx + (flip_x ? (-pt[0].x) : pt[0].x);
  370.       pt[0].y = cy + (flip_y ? (-pt[0].y) : pt[0].y);
  371.       pt[1].x = cx;
  372.       pt[1].y = cy;
  373.       pt[2].x = cx + (flip_x ? (-pt[2].x) : pt[2].x);
  374.       pt[2].y = cy + (flip_y ? (-pt[2].y) : pt[2].y);
  375.       gdImageFilledPolygon (im, pt, 3, color);
  376.       gdImagePolygon (im, pt, 3, color);
  377.  
  378.       pt[0] = pt[3];
  379.       pt[1] = pt[4];
  380.       pt[2] = pt[5];
  381.     }
  382.  
  383.   if (((s_cos * hs) > (s_sin * ws)) && ((e_cos * hs) < (e_sin * ws)))
  384.     {                /* the points are on different parts of the curve...
  385.                  * this is too tricky to try to handle, so divide and conquer:
  386.                  */
  387.       pt[3] = pt[0];
  388.       pt[4] = pt[1];
  389.       pt[5] = pt[2];
  390.  
  391.       pt[0].x = cx + (flip_x ? (-pt[0].x) : pt[0].x);
  392.       pt[0].y = cy + (flip_y ? (-pt[0].y) : pt[0].y);
  393.       pt[1].x = cx + (flip_x ? (-pt[1].x) : pt[1].x);
  394.       pt[1].y = cy + (flip_y ? (-pt[1].y) : pt[1].y);
  395.       pt[2].x = cx + (flip_x ? (-pt[2].x) : pt[2].x);
  396.       pt[2].y = cy + (flip_y ? (-pt[2].y) : pt[2].y);
  397.       gdImageFilledPolygon (im, pt, 3, color);
  398.       gdImagePolygon (im, pt, 3, color);
  399.  
  400.       pt[0] = pt[3];
  401.       pt[2] = pt[4];
  402.  
  403.       conquer = 1;
  404.     }
  405.  
  406.   if (conquer || (((s_cos * hs) > (s_sin * ws)) && ((e_cos * hs) > (e_sin * ws))))
  407.     {                /* This is the best bit... */
  408.       /* steep line + ellipse */
  409.       /* go up & left from pt[0] to pt[2] */
  410.  
  411.       x2 = w;
  412.       y2 = 0;            /* Starting point is exactly on ellipse */
  413.  
  414.       g = x2 - 1;
  415.       g = g * g * hs + 4 * ws - whs;
  416.  
  417.       while ((x2 * hs) > (y2 * ws))    /* Keep |tangent| > 1 */
  418.     {
  419.       if ((s_sin * x2) <= (y2 * s_cos))
  420.         break;
  421.  
  422.       y2 += 2;
  423.       g += ws * 4 * (y2 + 1);
  424.  
  425.       if (g > 0)        /* Need to drop */
  426.         {
  427.           x2 -= 2;
  428.           g -= hs * 4 * x2;
  429.         }
  430.     }
  431.  
  432.       lx2 = x2;
  433.       ly2 = y2;
  434.  
  435.       lg = lx2 * (pt[0].y - pt[2].y) - ly2 * (pt[0].x - pt[2].x);
  436.       lg = (lx2 - 1) * (pt[0].y - pt[2].y) - (ly2 + 2) * (pt[0].x - pt[2].x) - lg;
  437.  
  438.       while (y2 < (2 * pt[2].y))
  439.     {
  440.       y2 += 2;
  441.       g += ws * 4 * (y2 + 1);
  442.  
  443.       if (g > 0)        /* Need to drop */
  444.         {
  445.           x2 -= 2;
  446.           g -= hs * 4 * x2;
  447.         }
  448.  
  449.       ly2 += 2;
  450.       lg -= 2 * (pt[0].x - pt[2].x);
  451.  
  452.       if (lg < 0)        /* Need to drop */
  453.         {
  454.           lx2 -= 2;
  455.           lg -= 2 * (pt[0].y - pt[2].y);
  456.         }
  457.  
  458.       y = (int) (y2 / 2);
  459.       for (x = (int) (lx2 / 2); x <= (int) (x2 / 2); x++)
  460.         {
  461.           gdImageSetPixel (im, ((flip_x) ? (cx - x) : (cx + x)),
  462.                    ((flip_y) ? (cy - y) : (cy + y)), color);
  463.         }
  464.     }
  465.     }
  466.   if (conquer)
  467.     {
  468.       pt[0] = pt[4];
  469.       pt[2] = pt[5];
  470.     }
  471.   if (conquer || (((s_cos * hs) < (s_sin * ws)) && ((e_cos * hs) < (e_sin * ws))))
  472.     {                /* This is the best bit... */
  473.       /* gradual line + ellipse */
  474.       /* go down & right from pt[2] to pt[0] */
  475.  
  476.       x2 = 0;
  477.       y2 = h;            /* Starting point is exactly on ellipse */
  478.  
  479.       g = y2 - 1;
  480.       g = g * g * ws + 4 * hs - whs;
  481.  
  482.       while ((x2 * hs) < (y2 * ws))
  483.     {
  484.       x2 += 2;
  485.       g += hs * 4 * (x2 + 1);
  486.  
  487.       if (g > 0)        /* Need to drop */
  488.         {
  489.           y2 -= 2;
  490.           g -= ws * 4 * y2;
  491.         }
  492.  
  493.       if ((e_sin * x2) >= (y2 * e_cos))
  494.         break;
  495.     }
  496.  
  497.       lx2 = x2;
  498.       ly2 = y2;
  499.  
  500.       lg = lx2 * (pt[0].y - pt[2].y) - ly2 * (pt[0].x - pt[2].x);
  501.       lg = (lx2 + 2) * (pt[0].y - pt[2].y) - (ly2 - 1) * (pt[0].x - pt[2].x) - lg;
  502.  
  503.       while (x2 < (2 * pt[0].x))
  504.     {
  505.       x2 += 2;
  506.       g += hs * 4 * (x2 + 1);
  507.  
  508.       if (g > 0)        /* Need to drop */
  509.         {
  510.           y2 -= 2;
  511.           g -= ws * 4 * y2;
  512.         }
  513.  
  514.       lx2 += 2;
  515.       lg += 2 * (pt[0].y - pt[2].y);
  516.  
  517.       if (lg < 0)        /* Need to drop */
  518.         {
  519.           ly2 -= 2;
  520.           lg += 2 * (pt[0].x - pt[2].x);
  521.         }
  522.  
  523.       x = (int) (x2 / 2);
  524.       for (y = (int) (ly2 / 2); y <= (int) (y2 / 2); y++)
  525.         {
  526.           gdImageSetPixel (im, ((flip_x) ? (cx - x) : (cx + x)),
  527.                    ((flip_y) ? (cy - y) : (cy + y)), color);
  528.         }
  529.     }
  530.     }
  531. }
  532.  
  533. static gdPoint
  534. gdArcClosest (int width, int height, int angle)
  535. {
  536.   gdPoint pt;
  537.  
  538.   int flip_x = 0;
  539.   int flip_y = 0;
  540.  
  541.   long a_sin = 0;
  542.   long a_cos = 0;
  543.  
  544.   long w;            /* a * 2 */
  545.   long h;            /* b * 2 */
  546.  
  547.   long x2;            /* x * 2 */
  548.   long y2;            /* y * 2 */
  549.  
  550.   long ws;            /* (a * 2)^2 */
  551.   long hs;            /* (b * 2)^2 */
  552.  
  553.   long whs;            /* (a * 2)^2 * (b * 2)^2 */
  554.  
  555.   long g;            /* decision variable */
  556.  
  557.   w = (long) ((width & 1) ? (width + 1) : (width));
  558.   h = (long) ((height & 1) ? (height + 1) : (height));
  559.  
  560.   while (angle < 0)
  561.     angle += 360;
  562.   while (angle >= 360)
  563.     angle -= 360;
  564.  
  565.   if (angle == 0)
  566.     {
  567.       pt.x = w / 2;
  568.       pt.y = 0;
  569.       return (pt);
  570.     }
  571.   if (angle == 90)
  572.     {
  573.       pt.x = 0;
  574.       pt.y = h / 2;
  575.       return (pt);
  576.     }
  577.   if (angle == 180)
  578.     {
  579.       pt.x = -w / 2;
  580.       pt.y = 0;
  581.       return (pt);
  582.     }
  583.   if (angle == 270)
  584.     {
  585.       pt.x = 0;
  586.       pt.y = -h / 2;
  587.       return (pt);
  588.     }
  589.  
  590.   pt.x = 0;
  591.   pt.y = 0;
  592.  
  593.   if ((angle > 90) && (angle < 180))
  594.     {
  595.       angle = 180 - angle;
  596.       flip_x = 1;
  597.     }
  598.   if ((angle > 180) && (angle < 270))
  599.     {
  600.       angle = angle - 180;
  601.       flip_x = 1;
  602.       flip_y = 1;
  603.     }
  604.   if ((angle > 270) && (angle < 360))
  605.     {
  606.       angle = 360 - angle;
  607.       flip_y = 1;
  608.     }
  609.  
  610.   a_sin = (long) ((double) 32768 * sin ((double) angle * M_PI / (double) 180));
  611.   a_cos = (long) ((double) 32768 * cos ((double) angle * M_PI / (double) 180));
  612.  
  613.   ws = w * w;
  614.   hs = h * h;
  615.  
  616.   whs = 1;
  617.   while ((ws > 32768) || (hs > 32768))
  618.     {
  619.       ws = (ws + 1) / 2;    /* Unfortunate limitations on integers makes */
  620.       hs = (hs + 1) / 2;    /* drawing large  ellipses problematic...    */
  621.       whs *= 2;
  622.     }
  623.   while ((ws * hs) > (0x04000000L / whs))
  624.     {
  625.       ws = (ws + 1) / 2;
  626.       hs = (hs + 1) / 2;
  627.       whs *= 2;
  628.     }
  629.   whs *= ws * hs;
  630.  
  631.   if ((a_cos * hs) > (a_sin * ws))
  632.     {
  633.       x2 = w;
  634.       y2 = 0;            /* Starting point is exactly on ellipse */
  635.  
  636.       g = x2 - 1;
  637.       g = g * g * hs + 4 * ws - whs;
  638.  
  639.       while ((x2 * hs) > (y2 * ws))    /* Keep |tangent| > 1 */
  640.     {
  641.       y2 += 2;
  642.       g += ws * 4 * (y2 + 1);
  643.  
  644.       if (g > 0)        /* Need to drop */
  645.         {
  646.           x2 -= 2;
  647.           g -= hs * 4 * x2;
  648.         }
  649.  
  650.       if ((a_sin * x2) <= (y2 * a_cos))
  651.         {
  652.           pt.x = (int) (x2 / 2);
  653.           pt.y = (int) (y2 / 2);
  654.           break;
  655.         }
  656.     }
  657.     }
  658.   else
  659.     {
  660.       x2 = 0;
  661.       y2 = h;            /* Starting point is exactly on ellipse */
  662.  
  663.       g = y2 - 1;
  664.       g = g * g * ws + 4 * hs - whs;
  665.  
  666.       while ((x2 * hs) < (y2 * ws))
  667.     {
  668.       x2 += 2;
  669.       g += hs * 4 * (x2 + 1);
  670.  
  671.       if (g > 0)        /* Need to drop */
  672.         {
  673.           y2 -= 2;
  674.           g -= ws * 4 * y2;
  675.         }
  676.  
  677.       if ((a_sin * x2) >= (y2 * a_cos))
  678.         {
  679.           pt.x = (int) (x2 / 2);
  680.           pt.y = (int) (y2 / 2);
  681.           break;
  682.         }
  683.     }
  684.     }
  685.  
  686.   if (flip_x)
  687.     pt.x = -pt.x;
  688.   if (flip_y)
  689.     pt.y = -pt.y;
  690.  
  691.   return (pt);
  692. }
  693.  
  694. #include "gd.h"
  695. #include <string.h>
  696. #include <math.h>
  697.  
  698. #define WIDTH    500
  699. #define HEIGHT    300
  700.  
  701. int 
  702. main (int argc, char *argv[])
  703. {
  704.   gdImagePtr im = gdImageCreate (WIDTH, HEIGHT);
  705.   int white = gdImageColorResolve (im, 0xFF, 0xFF, 0xFF), black = gdImageColorResolve (im, 0, 0, 0),
  706.     red = gdImageColorResolve (im, 0xFF, 0xA0, 0xA0);
  707.   FILE *out;
  708.  
  709.   /* filled arc - circle */
  710.   gdImageFilledArc (im, WIDTH / 5, HEIGHT / 4, 200, 200, 45, 90, red, gdPie);
  711.   gdImageArc (im, WIDTH / 5, HEIGHT / 4, 200, 200, 45, 90, black);
  712.  
  713.   /* filled arc - ellipse */
  714.   gdImageFilledArc (im, WIDTH / 2, HEIGHT / 4, 200, 150, 45, 90, red, gdPie);
  715.   gdImageArc (im, WIDTH / 2, HEIGHT / 4, 200, 150, 45, 90, black);
  716.  
  717.  
  718.   /* reference lines */
  719.   gdImageLine (im, 0, HEIGHT / 4, WIDTH, HEIGHT / 4, black);
  720.   gdImageLine (im, WIDTH / 5, 0, WIDTH / 5, HEIGHT, black);
  721.   gdImageLine (im, WIDTH / 2, 0, WIDTH / 2, HEIGHT, black);
  722.   gdImageLine (im, WIDTH / 2, HEIGHT / 4, WIDTH / 2 + 300, HEIGHT / 4 + 300, black);
  723.   gdImageLine (im, WIDTH / 5, HEIGHT / 4, WIDTH / 5 + 300, HEIGHT / 4 + 300, black);
  724.  
  725.   /* TBB: Write img to test/arctest.png */
  726.   out = fopen ("test/arctest.png", "wb");
  727.   if (!out)
  728.     {
  729.       fprintf (stderr, "Can't create test/arctest.png\n");
  730.       exit (1);
  731.     }
  732.   gdImagePng (im, out);
  733.   fclose (out);
  734.   fprintf (stderr, "Test image written to test/arctest.png\n");
  735.   /* Destroy it */
  736.   gdImageDestroy (im);
  737.  
  738.   return 0;
  739. }
  740.  
  741. #endif
  742.