MIDP 1.0 fillTriangle Method

One of the (many) limitations of MIDP 1.0 is that it lacks the fillTriangle that is present in MIDP 2.0. Below is a replacement method that works on MIDP 1.0 devices. It is based on notes published by Michal Wronski.

Michal’s algorithm depends on floating-point math – also unavailable in MIDP 1.0. With a little refactoring I was able to create an integer-only approximation. Sadly, rounding errors mean that my routine isn’t pixel perfect. An alternative that would give more accurate results would be to use some kind of fixed-point library. Despite its shortcomings, however, my method is good enough for many practical purposes (including my own).

[sourcecode language='java']
protected void drawHorizontalLine(int x1, int x2, int y)
{
  graphics.drawLine(x1, y, x2, y);
}

protected void fillTriangle(int ax, int ay, int bx, int by, int cx, int cy)
{
  // http://www.geocities.com/wronski12/3d_tutor/tri_fillers.html

  // Sort the points so that ay <= by <= cy.
  if (ay > by)
  {
    temp = ax;
    ax = bx;
    bx = temp;
    temp = ay;
    ay = by;
    by = temp;
  }
  if (by > cy)
  {
    temp = bx;
    bx = cx;
    cx = temp;
    temp = by;
    by = cy;
    cy = temp;
  }
  if (ay > by)
  {
    temp = ax;
    ax = bx;
    bx = temp;
    temp = ay;
    ay = by;
    by = temp;
  }

  // Calc the deltas for each edge.
  int ab_num;
  int ab_den;
  if (by - ay > 0)
  {
    ab_num = (bx - ax);
    ab_den = (by - ay);
  }
  else
  {
    ab_num = (bx - ax);
    ab_den = 1;
  }

  int ac_num;
  int ac_den;
  if (cy - ay > 0)
  {
    ac_num = (cx - ax);
    ac_den = (cy - ay);
  }
  else
  {
    ac_num = 0;
    ac_den = 1;
  }

  int bc_num;
  int bc_den;
  if (cy - by > 0)
  {
    bc_num = (cx - bx);
    bc_den = (cy - by);
  }
  else
  {
    bc_num = 0;
    bc_den = 1;
  }

  // The start and end of each line.
  int sx;
  int ex;

  // The heights of the two components of the triangle.
  int h1 = by - ay;
  int h2 = cy - by;

  // If a is to the left of b...
  if (ax < bx)
  {
    // For each row of the top component...
    for (int y = 0; y < h1; y++)
    {
      sx = ax + ac_num * y / ac_den;
      ex = ax + ab_num * y / ab_den;
      drawHorizontalLine(sx, ex, ay + y);
    }
    // For each row of the bottom component...
    for (int y = 0; y < h2; y++)
    {
      int y2 = h1 + y;
      sx = ax + ac_num * y2 / ac_den;
      ex = bx + bc_num * y / bc_den;
      drawHorizontalLine(sx, ex, by + y);
    }
  }
  else
  {
    // For each row of the bottom component...
    for (int y = 0; y < h1; y++)
    {
      sx = ax + ab_num * y / ab_den;
      ex = ax + ac_num * y / ac_den;
      drawHorizontalLine(sx, ex, ay + y);
    }
    // For each row of the bottom component...
    for (int y = 0; y < h2; y++)
    {
      int y2 = h1 + y;
      sx = bx + bc_num * y / bc_den;
      ex = ax + ac_num * y2 / ac_den;
      drawHorizontalLine(sx, ex, by + y);
    }
  }
}
[/sourcecode]

I release this code into the public domain. You can use it as you please.

Be Sociable, Share!
This entry was posted in J2ME. Bookmark the permalink.

0 Responses to MIDP 1.0 fillTriangle Method

  1. Do you think you could help me with my blog? I’m willing to pay you 🙂 Contact me.

Leave a Reply

Your email address will not be published. Required fields are marked *