
/*
 * Make an estimate of the scale of the current transformation. 
 * We do this by computing the determinants of the 2D section of the transformation matrix.
 */
static float get_scale(void)
{
#define DET2D(T) (fabs((T)->m[0][0] * (T)->m[1][1] - (T)->m[0][1] * (T)->m[1][0]))

   const ALLEGRO_TRANSFORM* t = al_get_current_transform();
   float scale_sq = DET2D(t);
   ALLEGRO_BITMAP* b = al_get_target_bitmap();
   if (b) {
      const ALLEGRO_TRANSFORM* p = al_get_current_projection_transform();
      /* Divide by 4.0f as the screen coordinates range from -1 to 1 on both axes. */
      scale_sq *= DET2D(p) * al_get_bitmap_width(b) * al_get_bitmap_height(b) / 4.0f;
   }

   return sqrtf(scale_sq);

#undef DET2D
}

/* Function: al_draw_filled_pieslice
 */
void al_draw_filled_elliptical_arc(float cx, float cy, float rx, float ry, float start_theta,
   float delta_theta, ALLEGRO_COLOR color)
{
   ALLEGRO_VERTEX vertex_cache[ALLEGRO_VERTEX_CACHE_SIZE];
   float scale = get_scale();
   int num_segments, ii;
   
   if(rx<0||ry<0)return;
   //ASSERT(rx >= 0);ASSERT(ry >= 0);
   
   num_segments = fabs(delta_theta / (2 * ALLEGRO_PI) * ALLEGRO_PRIM_QUALITY * sqrtf(scale * (rx+ry)/2.0f));

   if (num_segments < 2)
      num_segments = 2;
   
   if (num_segments + 1 >= ALLEGRO_VERTEX_CACHE_SIZE) {
      num_segments = ALLEGRO_VERTEX_CACHE_SIZE - 1 - 1;
   }
      
   al_calculate_arc(&(vertex_cache[1].x), sizeof(ALLEGRO_VERTEX), cx, cy, rx, ry, start_theta, delta_theta, 0, num_segments);
   vertex_cache[0].x = cx; vertex_cache[0].y = cy;
   
   for (ii = 0; ii < num_segments + 1; ii++) {
      vertex_cache[ii].color = color;
      vertex_cache[ii].z = 0;
   }
   
   al_draw_prim(vertex_cache, 0, 0, 0, num_segments + 1, ALLEGRO_PRIM_TRIANGLE_FAN);
}
