plotEllipseRectAA function

void plotEllipseRectAA(
  1. double x0,
  2. double y0,
  3. double x1,
  4. double y1,
  5. SetPixel setPixel,
)

Implementation

void plotEllipseRectAA(double x0, double y0, double x1, double y1, SetPixel setPixel) {
  /* draw a black anti-aliased rectangular ellipse on white background */
  double a = (x1 - x0).abs();
  final double b = (y1 - y0).abs();
  int b1 = b.floor() & 1; /* diameter */
  double dx = 4 * (a - 1) * b * b;
  double dy = 4 * (b1 + 1) * a * a; /* error increment */
  double ed;
  double i;
  var err = b1 * a * a - dx + dy; /* error of 1.step */

  if (a == 0 || b == 0) {
    return plotLine(x0, y0, x1, y1, setPixel);
  }
  if (x0 > x1) {
    x0 = x1;
    x1 += a;
  } /* if called with swapped points */
  if (y0 > y1) {
    y0 = y1; /* .. exchange them */
  }
  y0 += (b.floor() + 1) >> 1;
  y1 = y0 - b1; /* starting pixel */
  a = 8 * a * a;
  b1 = 8 * b.floor() * b.floor();

  for (;;) {
    /* approximate ed=Math.sqrt(dx*dx+dy*dy) */
    i = math.min(dx, dy);
    ed = math.max(dx, dy);
    if (y0 == y1 + 1 && err > dy && a > b1) {
      ed = 255 * 4 / a; /* x-tip */
    } else {
      ed = 255 / (ed + 2 * ed * i * i / (4 * ed * ed + i * i)); /* approximation */
    }

    i = ed * (err + dx - dy).abs(); /* get intensity value by pixel err */
    setPixel(x0, y0, i.round());
    setPixel(x0, y1, i.round());
    setPixel(x1, y0, i.round());
    setPixel(x1, y1, i.round());

    final bool f = 2 * err + dy >= 0;
    if (f) {
      /* x step, remember condition */
      if (x0 >= x1) {
        break;
      }
      i = ed * (err + dx);
      if (i < 256) {
        setPixel(x0, y0 + 1, i.round());
        setPixel(x0, y1 - 1, i.round());
        setPixel(x1, y0 + 1, i.round());
        setPixel(x1, y1 - 1, i.round());
      } /* do error increment later since values are still needed */
    }
    if (2 * err <= dx) {
      /* y step */
      i = ed * (dy - err);
      if (i < 256) {
        setPixel(x0 + 1, y0, i.round());
        setPixel(x1 - 1, y0, i.round());
        setPixel(x0 + 1, y1, i.round());
        setPixel(x1 - 1, y1, i.round());
      }
      y0++;
      y1--;
      err += dy += a;
    }
    if (f) {
      x0++;
      x1--;
      err -= dx -= b1;
    } /* x error increment */
  }
  if (--x0 == x1++) {
    /* too early stop of flat ellipses */
    while (y0 - y1 < b) {
      i = 255 * 4 * (err + dx).abs() / b1; /* -> finish tip of ellipse */
      setPixel(x0, ++y0, i.round());
      setPixel(x1, y0, i.round());
      setPixel(x0, --y1, i.round());
      setPixel(x1, y1, i.round());
      err += dy += a;
    }
  }
}