[AD] A new do_ellipse function for 4.2 and 4.4

[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]


I have made a replacement function for allegro's do_ellipse. The old did not produce accurate
ellipses. This one does so, and does so much more rapidly, as confirmed using a related thread on
a.cc. Note that this uses some floating point calculations internally. They have almost no effect
on the efficiency of the code, but may or may not pose problems for systems without an FPU.

In any event, the new function is attached. It should be a drop in replacement for the current
function in gfx.c. I tested it extensively for lack of overdraw, and invalid parameters, and it
passed all of those.

Also, this is not meant for the 4.9 branch. That one will have a separate, more advanced function.


      ____________________________________________________________________________________
You rock. That's why Blockbuster's offering you one month of Blockbuster Total Access, No Cost.  
http://tc.deals.yahoo.com/tc/blockbuster/text5.com
void do_ellipse(BITMAP* bmp, int x, int y, int rx, int ry, int d, void (*proc)(BITMAP *, int, int, int))
{
   int ix, iy; /* center of the ellipse */
   int X, Y;
   float XChange, YChange;
   float EllipseError;
   float TwoASquare, TwoBSquare;
   float StoppingX, StoppingY;
   
   if (rx < 1)
      rx = 1;
   if (ry < 1)
      ry = 1;

   ix = x;
   iy = y;
   TwoASquare = 2 * rx * rx;
   TwoBSquare = 2 * ry * ry;

   X = rx;
   Y = 0;

   XChange = ry * ry * (1 - 2 * rx);
   YChange = rx * rx;
   EllipseError = 0;

   /* the following two decide when to stop, easier than solving for this explicitly */
   StoppingX = TwoBSquare * rx;
   StoppingY = 0;

   while (StoppingX >= StoppingY) {   /* 1st set of points, y' > -1 */
      proc(bmp, ix + X, iy + Y, d);
      proc(bmp, ix - X, iy + Y, d);
      if (Y != 0)   {
         proc(bmp, ix + X, iy - Y, d);
         proc(bmp, ix - X, iy - Y, d);
      }

      Y++;
      StoppingY += TwoASquare;
      EllipseError += YChange;
      YChange += TwoASquare;

      if ((2.0f * EllipseError + XChange) > 0) {
         X--;
         StoppingX -= TwoBSquare;
         EllipseError += XChange;
         XChange += TwoBSquare;
      }
   }

   /*
   1st point set is done; start the 2nd set of points
   we just flip the order of iteration, and continue from
   where we left off
   */

   while (X >= 0) {
      proc(bmp, ix + X, iy + Y, d);
      proc(bmp, ix + X, iy - Y, d);
      if (X != 0) {
         proc(bmp, ix - X, iy - Y, d);
         proc(bmp, ix - X, iy + Y, d);
      }

      X--;
      EllipseError += XChange;
      XChange += TwoBSquare;

      if((2.0f * EllipseError + YChange) < 0)   {
         Y++;
         EllipseError += YChange;
         YChange += TwoASquare;
      }
   }
}


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/