92 lines
2.4 KiB
C
92 lines
2.4 KiB
C
/* ************************************************************************** */
|
|
/* */
|
|
/* ML_filled_polygon.c */
|
|
/* | Project : libmonochrome */
|
|
/* */
|
|
/* By: Pierre "PierrotLL" Le Gall <legallpierre89@gmail.com> */
|
|
/* Last updated: 2011/11/22 */
|
|
/* */
|
|
/* ************************************************************************** */
|
|
|
|
#include <monochrome/internals.h>
|
|
|
|
static int ML_filled_polygon_quicksord_partition(int *t, int p, int r)
|
|
{
|
|
int i, j, x, tmp;
|
|
j = p - 1;
|
|
x = t[r];
|
|
for(i=p ; i<r ; i++)
|
|
{
|
|
if(x > t[i])
|
|
{
|
|
j++;
|
|
tmp = t[j];
|
|
t[j] = t[i];
|
|
t[i] = tmp;
|
|
}
|
|
}
|
|
t[r] = t[j+1];
|
|
t[j+1] = x;
|
|
return j + 1;
|
|
}
|
|
|
|
static void ML_filled_polygon_quicksord(int* t, int p, int r)
|
|
{
|
|
int q;
|
|
if(p < r)
|
|
{
|
|
q = ML_filled_polygon_quicksord_partition(t, p, r);
|
|
ML_filled_polygon_quicksord(t, p, q-1);
|
|
ML_filled_polygon_quicksord(t, q+1, r);
|
|
}
|
|
}
|
|
|
|
|
|
void ML_filled_polygon(const int *x, const int *y, int nb_vertices, ML_Color color)
|
|
{
|
|
int i, j, dx, dy, ymin, ymax;
|
|
int *cut_in_line, nb_cut;
|
|
if(nb_vertices < 3) return;
|
|
cut_in_line = malloc(nb_vertices*sizeof(int));
|
|
if(!cut_in_line) return;
|
|
ymin = ymax = y[0];
|
|
for(i=1 ; i<nb_vertices ; i++)
|
|
{
|
|
if(y[i] < ymin) ymin = y[i];
|
|
if(y[i] > ymax) ymax = y[i];
|
|
}
|
|
for(i=ymin ; i<=ymax ; i++)
|
|
{
|
|
nb_cut = 0;
|
|
for(j=0 ; j<nb_vertices ; j++)
|
|
{
|
|
if((y[j]<=i && y[(j+1)%nb_vertices]>=i) || (y[j]>=i && y[(j+1)%nb_vertices]<=i))
|
|
{
|
|
dy = abs(y[j]-y[(j+1)%nb_vertices]);
|
|
if(dy)
|
|
{
|
|
dx = x[(j+1)%nb_vertices]-x[j];
|
|
cut_in_line[nb_cut] = x[j] + rnd(abs(i-y[j]+sgn(i-y[j])/2)*dx/dy);
|
|
nb_cut++;
|
|
}
|
|
}
|
|
}
|
|
ML_filled_polygon_quicksord(cut_in_line, 0, nb_cut-1);
|
|
j = 0;
|
|
while(j<nb_cut-2 && cut_in_line[j]==cut_in_line[j+1]) j++;
|
|
while(j < nb_cut)
|
|
{
|
|
if(j == nb_cut-1) ML_horizontal_line(i, cut_in_line[j-1]+1, cut_in_line[j], color);
|
|
else
|
|
{
|
|
dx = 1;
|
|
while(j+dx<nb_cut-1 && cut_in_line[j+dx]==cut_in_line[j+dx+1]) dx++;
|
|
ML_horizontal_line(i, cut_in_line[j], cut_in_line[j+dx], color);
|
|
j += dx;
|
|
}
|
|
j++;
|
|
}
|
|
}
|
|
free(cut_in_line);
|
|
}
|