static int _fill_polygon_rgb(uint8_t *img, int npoints, Edge *e, uint32_t color, int w, int h, int rowstride) { int i, j; float *xx; int ymin, ymax; float y; if (npoints <= 0) return 0; /* Find upper and lower polygon boundary (within image) */ ymin = e[0].ymin; ymax = e[0].ymax; for (i = 1; i < npoints; i++) { if (e[i].ymin < ymin) ymin = e[i].ymin; if (e[i].ymax > ymax) ymax = e[i].ymax; } if (ymin < 0) ymin = 0; if (ymax >= h) ymax = h-1; /* Process polygon edges */ xx = malloc(npoints * sizeof(float)); if (!xx) return -1; for (;ymin <= ymax; ymin++) { y = ymin+0.5F; for (i = j = 0; i < npoints; i++) { if (y >= e[i].ymin && y <= e[i].ymax) { if (e[i].d == 0) draw_hline_rgb(img, e[i].xmin, ymin, e[i].xmax, color, w, h, rowstride); else xx[j++] = (y-e[i].y0) * e[i].dx + e[i].x0; } } if (j == 2) { if (xx[0] < xx[1]) draw_hline_rgb(img, CEIL(xx[0]-0.5), ymin, FLOOR(xx[1]+0.5), color, w, h, rowstride); else draw_hline_rgb(img, CEIL(xx[1]-0.5), ymin, FLOOR(xx[0]+0.5), color, w, h, rowstride); } else { qsort(xx, j, sizeof(float), x_cmp); for (i = 0; i < j-1 ; i += 2) draw_hline_rgb(img, CEIL(xx[i]-0.5), ymin, FLOOR(xx[i+1]+0.5), color, w, h, rowstride); } } free(xx); return 0; }
int main(int argc, char **argv) { uint32_t w = 600; uint32_t h = 400; uint32_t rs = w * 3; uint8_t *img = (uint8_t*)malloc( h * rs ); memset(img, 0, h*rs); draw_line_rgb(img, 0, 0, 600, 400, 0xFFFF00, w, h, rs); draw_hline_rgb(img, 0, 200, 200, 0xFF00FF, w, h, rs); draw_hline_rgb(img, 200, 300, 0, 0xFF00FF, w, h, rs); int triangle[] = { 300, 200, 300, 100, 400, 200 }; draw_polygon_rgb(img, 3, triangle, 0x00FF00, 0, w, h, rs); draw_rect_rgb(img, 300, 300, 390, 390, 0xFFFFFF, 1, w, h, rs); draw_rect_rgb(img, 350, 250, 450, 330, 0x80FF0000, 1, w, h, rs); draw_rect_rgb(img, 400, 200, 500, 300, 0xa00000FF, 1, w, h, rs); draw_ellipse_rgb(img, 500, 100, 575, 150, 0x00FFFF, 1, 0, w, h, rs); draw_ellipse_rgb(img, 450, 25, 525, 100, 0x00FFFF, 0, 0, w, h, rs); draw_ellipse_rgb(img, -50,-50,50,50, 0xFFFF00, 1, 0, w, h, rs); FILE *fp = fopen("out.ppm", "wb"); ppm_write( fp, img, w, h, w*3 ); fclose( fp ); free( img ); printf("created out.ppm\n"); return 0; }
void draw_line_rgb(int x0, int y0, int x1, int y1, DrawColor color, DrawImage* img) { int xs; int ys; int dx = x1-x0; if (dx < 0) { dx = -dx; xs = -1; } else xs = 1; int dy = y1-y0; if (dy < 0) { dy = -dy; ys = -1; } else ys = 1; int n = (dx > dy) ? dx : dy; if (dx == 0) { for (int i = 0; i < dy; i++) { draw_point_rgb(x0, y0, color, img); y0 += ys; } } else if (dy == 0) { draw_hline_rgb(x0, y0, x1, color, img); } else if (dx > dy) { n = dx; dy += dy; int e = dy - dx; dx += dx; for(int i = 0; i < n; i++) { draw_point_rgb(x0, y0, color, img); if (e >= 0) { y0 += ys; e -= dx; } e += dy; x0 += xs; } } else { n = dy; dx += dx; int e = dx - dy; dy += dy; for(int i = 0; i < n; i++) { draw_point_rgb(x0, y0, color, img); if (e >= 0) { x0 += xs; e -= dy; } e += dx; y0 += ys; } } }
void draw_box_rgb(int x0, int y0, int x1, int y1, DrawColor color, DrawImage* img) { for(int y=y0; y<=y1; y++) draw_hline_rgb(x0, y, x1, color, img); }
void draw_line_rgb(uint8_t *img, int x0, int y0, int x1, int y1, uint32_t color, int w, int h, int rowstride) { int i, n, e; int dx, dy; int xs, ys; /* normalize coordinates */ dx = x1-x0; if (dx < 0) dx = -dx, xs = -1; else xs = 1; dy = y1-y0; if (dy < 0) dy = -dy, ys = -1; else ys = 1; n = (dx > dy) ? dx : dy; if (dx == 0) { /* vertical */ for (i = 0; i < dy; i++) { draw_point_rgb(img, x0, y0, color, w, h, rowstride); y0 += ys; } } else if (dy == 0) { /* horizontal */ draw_hline_rgb(img, x0, y0, x1, color, w, h, rowstride); } else if (dx > dy) { /* bresenham, horizontal slope */ n = dx; dy += dy; e = dy - dx; dx += dx; for (i = 0; i < n; i++) { draw_point_rgb(img, x0, y0, color, w, h, rowstride); if (e >= 0) { y0 += ys; e -= dx; } e += dy; x0 += xs; } } else { /* bresenham, vertical slope */ n = dy; dx += dx; e = dx - dy; dy += dy; for (i = 0; i < n; i++) { draw_point_rgb(img, x0, y0, color, w, h, rowstride); if (e >= 0) { x0 += xs; e -= dy; } e += dx; y0 += ys; } } }