From b216ac030a032e6a972f56b299675e6eab85de70 Mon Sep 17 00:00:00 2001 From: sam Date: Tue, 11 Nov 2003 10:22:19 +0000 Subject: [PATCH] * libee/triangle.c: + Wrote ee_draw_triangle() and ee_draw_thin_triangle(). * libee/box.c: + Wrote ee_draw_box(), ee_draw_thin_box() and ee_fill_box(). * libee/conic.c: + Wrote ee_fill_ellipse(). + First attempt at ee_draw_thin_ellipse(), to be reworked. * test/demo.c: + Merged demo_lines() and demo_thin_lines(). + Merged demo_triangles() and demo_outlined_triangles(). + Wrote demo_box(). + Use ee_fill_ellipse() in demo_all(). git-svn-id: file:///srv/caca.zoy.org/var/lib/svn/ttyvaders/trunk@152 92316355-f0b4-4df1-b90c-862c8a59935f --- libee/Makefile.am | 1 + libee/box.c | 127 +++++++++++++++++++++++ libee/conic.c | 88 ++++++++++++++++ libee/ee.h | 10 ++ libee/triangle.c | 14 +++ test/demo.c | 254 ++++++++++++++-------------------------------- 6 files changed, 319 insertions(+), 175 deletions(-) create mode 100644 libee/box.c diff --git a/libee/Makefile.am b/libee/Makefile.am index 9dacf92..0858f7f 100644 --- a/libee/Makefile.am +++ b/libee/Makefile.am @@ -10,6 +10,7 @@ libee_a_SOURCES = \ io.c \ math.c \ line.c \ + box.c \ conic.c \ triangle.c \ sprite.c \ diff --git a/libee/box.c b/libee/box.c new file mode 100644 index 0000000..6dc197c --- /dev/null +++ b/libee/box.c @@ -0,0 +1,127 @@ +/* + * libee ASCII-Art library + * Copyright (c) 2002, 2003 Sam Hocevar + * All Rights Reserved + * + * $Id$ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "config.h" + +#ifdef USE_SLANG +# include +#elif USE_NCURSES +# include +#endif + +#include + +#include "ee.h" + +void ee_draw_box(int x1, int y1, int x2, int y2, char c) +{ + ee_draw_line(x1, y1, x1, y2, c); + ee_draw_line(x1, y2, x2, y2, c); + ee_draw_line(x2, y2, x2, y1, c); + ee_draw_line(x2, y1, x1, y1, c); +} + +void ee_draw_thin_box(int x1, int y1, int x2, int y2) +{ + int x, y, xmax, ymax; + + if(x1 > x2) + { + int tmp = x1; + x1 = x2; x2 = tmp; + } + + if(y1 > y2) + { + int tmp = y1; + y1 = y2; y2 = tmp; + } + + xmax = ee_get_width() - 1; + ymax = ee_get_height() - 1; + + if(x2 < 0 || y2 < 0 || x1 > xmax || y1 > ymax) + return; + + /* Draw edges */ + if(y1 >= 0) + for(x = x1 < 0 ? 1 : x1 + 1; x < x2 && x < xmax; x++) + ee_putchar(x, y1, '-'); + + if(y2 < ymax) + for(x = x1 < 0 ? 1 : x1 + 1; x < x2 && x < xmax; x++) + ee_putchar(x, y2, '-'); + + if(x1 >= 0) + for(y = y1 < 0 ? 1 : y1 + 1; y < y2 && y < ymax; y++) + ee_putchar(x1, y, '|'); + + if(x2 < xmax) + for(y = y1 < 0 ? 1 : y1 + 1; y < y2 && y < ymax; y++) + ee_putchar(x2, y, '|'); + + /* Draw corners */ + if(x1 >= 0 && y1 >= 0) + ee_putchar(x1, y1, ','); + + if(x1 >= 0 && y2 <= ymax) + ee_putchar(x1, y2, '`'); + + if(x2 <= xmax && y1 >= 0) + ee_putchar(x2, y1, '.'); + + if(x2 <= xmax && y2 <= ymax) + ee_putchar(x2, y2, '\''); +} + +void ee_fill_box(int x1, int y1, int x2, int y2, char c) +{ + int x, y, xmax, ymax; + + if(x1 > x2) + { + int tmp = x1; + x1 = x2; x2 = tmp; + } + + if(y1 > y2) + { + int tmp = y1; + y1 = y2; y2 = tmp; + } + + xmax = ee_get_width() - 1; + ymax = ee_get_height() - 1; + + if(x2 < 0 || y2 < 0 || x1 > xmax || y1 > ymax) + return; + + if(x1 < 0) x1 = 0; + if(y1 < 0) y1 = 0; + if(x2 > xmax) x2 = xmax; + if(y2 > ymax) y2 = ymax; + + for(y = y1; y <= y2; y++) + for(x = x1; x <= x2; x++) + ee_putchar(x, y, c); +} + diff --git a/libee/conic.c b/libee/conic.c index b178838..460c0e8 100644 --- a/libee/conic.c +++ b/libee/conic.c @@ -49,6 +49,51 @@ void ee_draw_circle(int x, int y, int r, char c) } } +void ee_fill_ellipse(int xo, int yo, int a, int b, char c) +{ + int d2; + int x = 0; + int y = b; + int d1 = b*b - (a*a*b) + (a*a/4); + + while( a*a*y - a*a/2 > b*b*(x+1)) + { + if(d1 < 0) + { + d1 += b*b*(2*x+1); /* XXX: "Computer Graphics" has + 3 here. */ + } + else + { + d1 += b*b*(2*x*1) + a*a*(-2*y+2); + ee_draw_line(xo - x, yo - y, xo + x, yo - y, c); + ee_draw_line(xo - x, yo + y, xo + x, yo + y, c); + y--; + } + x++; + } + + ee_draw_line(xo - x, yo - y, xo + x, yo - y, c); + ee_draw_line(xo - x, yo + y, xo + x, yo + y, c); + + d2 = b*b*(x+0.5)*(x+0.5) + a*a*(y-1)*(y-1) - a*a*b*b; + while(y > 0) + { + if(d2 < 0) + { + d2 += b*b*(2*x+2) + a*a*(-2*y+3); + x++; + } + else + { + d2 += a*a*(-2*y+3); + } + + y--; + ee_draw_line(xo - x, yo - y, xo + x, yo - y, c); + ee_draw_line(xo - x, yo + y, xo + x, yo + y, c); + } +} + void ee_draw_ellipse(int xo, int yo, int a, int b, char c) { int d2; @@ -91,6 +136,49 @@ void ee_draw_ellipse(int xo, int yo, int a, int b, char c) } } +void ee_draw_thin_ellipse(int xo, int yo, int a, int b) +{ + /* FIXME: this is not correct */ + int d2; + int x = 0; + int y = b; + int d1 = b*b - (a*a*b) + (a*a/4); + + ellipsepoints(xo, yo, x, y, '-'); + + while( a*a*y - a*a/2 > b*b*(x+1)) + { + if(d1 < 0) + { + d1 += b*b*(2*x+1); /* XXX: "Computer Graphics" has + 3 here. */ + } + else + { + d1 += b*b*(2*x*1) + a*a*(-2*y+2); + y--; + } + x++; + ellipsepoints(xo, yo, x, y, '-'); + } + + d2 = b*b*(x+0.5)*(x+0.5) + a*a*(y-1)*(y-1) - a*a*b*b; + while(y > 0) + { + if(d2 < 0) + { + d2 += b*b*(2*x+2) + a*a*(-2*y+3); + x++; + } + else + { + d2 += a*a*(-2*y+3); + } + + y--; + ellipsepoints(xo, yo, x, y, '|'); + } +} + static void ellipsepoints(int xo, int yo, int x, int y, char c) { uint8_t b = 0; diff --git a/libee/ee.h b/libee/ee.h index f08d528..38b27ef 100644 --- a/libee/ee.h +++ b/libee/ee.h @@ -58,8 +58,18 @@ void ee_clear(void); void ee_draw_line(int, int, int, int, char); void ee_draw_thin_line(int, int, int, int); + void ee_draw_circle(int, int, int, char); void ee_draw_ellipse(int, int, int, int, char); +void ee_draw_thin_ellipse(int, int, int, int); +void ee_fill_ellipse(int, int, int, int, char); + +void ee_draw_box(int, int, int, int, char); +void ee_draw_thin_box(int, int, int, int); +void ee_fill_box(int, int, int, int, char); + +void ee_draw_triangle(int, int, int, int, int, int, char); +void ee_draw_thin_triangle(int, int, int, int, int, int); void ee_fill_triangle(int, int, int, int, int, int, char); int ee_rand(int, int); diff --git a/libee/triangle.c b/libee/triangle.c index 6c50ab4..8899366 100644 --- a/libee/triangle.c +++ b/libee/triangle.c @@ -32,6 +32,20 @@ #include "ee.h" +void ee_draw_triangle(int x1, int y1, int x2, int y2, int x3, int y3, char c) +{ + ee_draw_line(x1, y1, x2, y2, c); + ee_draw_line(x2, y2, x3, y3, c); + ee_draw_line(x3, y3, x1, y1, c); +} + +void ee_draw_thin_triangle(int x1, int y1, int x2, int y2, int x3, int y3) +{ + ee_draw_thin_line(x1, y1, x2, y2); + ee_draw_thin_line(x2, y2, x3, y3); + ee_draw_thin_line(x3, y3, x1, y1); +} + void ee_fill_triangle(int x1, int y1, int x2, int y2, int x3, int y3, char c) { int x, y, xa, xb, xmax, ymax; diff --git a/test/demo.c b/test/demo.c index d9ff3b2..ae9d7f3 100644 --- a/test/demo.c +++ b/test/demo.c @@ -33,14 +33,14 @@ static void demo_all(void); static void demo_dots(void); static void demo_lines(void); -static void demo_thin_lines(void); -static void demo_circles(void); +static void demo_boxes(void); static void demo_ellipses(void); static void demo_triangles(void); -static void demo_outlined_triangles(void); static void demo_sprites(void); int force_clipping = 0; +int outline = 0; +int thin = 0; struct ee_sprite *sprite = NULL; int main(int argc, char **argv) @@ -87,28 +87,38 @@ int main(int argc, char **argv) case '2': ee_clear(); demo = demo_lines; + thin = 0; break; case '3': ee_clear(); - demo = demo_thin_lines; + demo = demo_lines; + thin = 1; break; case '4': ee_clear(); - demo = demo_circles; + demo = demo_boxes; + outline = 0; break; case '5': ee_clear(); - demo = demo_ellipses; + demo = demo_boxes; + outline = 1; break; case '6': ee_clear(); - demo = demo_triangles; + demo = demo_ellipses; break; case '7': ee_clear(); - demo = demo_outlined_triangles; + demo = demo_triangles; + outline = 0; break; case '8': + ee_clear(); + demo = demo_triangles; + outline = 1; + break; + case '9': ee_clear(); demo = demo_sprites; break; @@ -145,11 +155,12 @@ static void display_menu(void) ee_putstr(4, 7, "1: dots demo"); ee_putstr(4, 8, "2: lines demo"); ee_putstr(4, 9, "3: thin lines demo"); - ee_putstr(4, 10, "4: circles demo"); - ee_putstr(4, 11, "5: ellipses demo"); - ee_putstr(4, 12, "6: triangles demo"); - ee_putstr(4, 13, "7: outlined triangles demo"); - ee_putstr(4, 14, "8: sprites demo"); + ee_putstr(4, 10, "4: boxes demo"); + ee_putstr(4, 11, "5: outlined boxes demo"); + ee_putstr(4, 12, "6: ellipses demo"); + ee_putstr(4, 13, "7: triangles demo"); + ee_putstr(4, 14, "8: outlined triangles demo"); + ee_putstr(4, 15, "9: sprites demo"); ee_putstr(4, yo - 2, "q: quit"); @@ -178,14 +189,11 @@ static void demo_all(void) ee_draw_thin_line(xo, yo, x1, y1); } + j = 15 + sin(0.03*i) * 8; ee_color(EE_WHITE); - for(j = 15 + sin(0.03*i) * 8; j--;) - { - ee_draw_circle(xo, yo, j, '#'); - } - + ee_fill_ellipse(xo, yo, j, j / 2, '#'); ee_color(EE_YELLOW); - ee_draw_circle(xo, yo, 15 + sin(0.03*i) * 8, '#'); + ee_draw_ellipse(xo, yo, j, j / 2, '#'); /* Draw the pyramid */ xo = ee_get_width() * 5 / 8; @@ -203,23 +211,17 @@ static void demo_all(void) ee_color(EE_GREEN); ee_fill_triangle(xo, yo, x2, y2, x1, y1, '%'); ee_color(EE_YELLOW); - ee_draw_thin_line(xo, yo, x2, y2); - ee_draw_thin_line(x2, y2, x1, y1); - ee_draw_thin_line(x1, y1, xo, yo); + ee_draw_thin_triangle(xo, yo, x2, y2, x1, y1); ee_color(EE_RED); ee_fill_triangle(x1, y1, x2, y2, x3, y3, '#'); ee_color(EE_YELLOW); - ee_draw_thin_line(x1, y1, x2, y2); - ee_draw_thin_line(x2, y2, x3, y3); - ee_draw_thin_line(x3, y3, x1, y1); + ee_draw_thin_triangle(x1, y1, x2, y2, x3, y3); ee_color(EE_BLUE); ee_fill_triangle(xo, yo, x2, y2, x3, y3, '%'); ee_color(EE_YELLOW); - ee_draw_thin_line(xo, yo, x2, y2); - ee_draw_thin_line(x2, y2, x3, y3); - ee_draw_thin_line(x3, y3, xo, yo); + ee_draw_thin_triangle(xo, yo, x2, y2, x3, y3); /* Draw a background triangle */ x1 = 2; @@ -231,12 +233,8 @@ static void demo_all(void) x3 = ee_get_width() / 3; y3 = ee_get_height() - 3; - ee_color(EE_BLUE); -// ee_fill_triangle(x1, y1, x2, y2, x3, y3, '.'); ee_color(EE_CYAN); - ee_draw_thin_line(x1, y1, x3, y3); - ee_draw_thin_line(x2, y2, x1, y1); - ee_draw_thin_line(x3, y3, x2, y2); + ee_draw_thin_triangle(x1, y1, x2, y2, x3, y3); xo = ee_get_width() / 2 + cos(0.027*i) * ee_get_width() / 3; yo = ee_get_height() / 2 - sin(0.027*i) * ee_get_height() / 2; @@ -245,7 +243,7 @@ static void demo_all(void) ee_draw_thin_line(x2, y2, xo, yo); ee_draw_thin_line(x3, y3, xo, yo); - /* Draw a sprite behind the pyramid */ + /* Draw a sprite on the pyramid */ ee_draw_sprite(xo, yo, sprite); /* Draw a trail behind the foreground sprite */ @@ -287,70 +285,52 @@ static void demo_lines(void) { int w = ee_get_width(); int h = ee_get_height(); + int x1, y1, x2, y2; - /* Draw lines */ - ee_color(ee_rand(1, 10)); if(force_clipping) { - ee_draw_line(ee_rand(- w, 2 * w), ee_rand(- h, 2 * h), - ee_rand(- w, 2 * w), ee_rand(- h, 2 * h), '#'); + x1 = ee_rand(- w, 2 * w); y1 = ee_rand(- h, 2 * h); + x2 = ee_rand(- w, 2 * w); y2 = ee_rand(- h, 2 * h); } else { - ee_draw_line(ee_rand(0, w - 1), ee_rand(0, h - 1), - ee_rand(0, w - 1), ee_rand(0, h - 1), '#'); + x1 = ee_rand(0, w - 1); y1 = ee_rand(0, h - 1); + x2 = ee_rand(0, w - 1); y2 = ee_rand(0, h - 1); } - ee_refresh(); -} - -static void demo_thin_lines(void) -{ - int w = ee_get_width(); - int h = ee_get_height(); - /* Draw lines */ ee_color(ee_rand(1, 10)); - if(force_clipping) - { - ee_draw_thin_line(ee_rand(- w, 2 * w), ee_rand(- h, 2 * h), - ee_rand(- w, 2 * w), ee_rand(- h, 2 * h)); - } + if(thin) + ee_draw_thin_line(x1, y1, x2, y2); else - { - ee_draw_thin_line(ee_rand(0, w), ee_rand(0, h), - ee_rand(0, w), ee_rand(0, h)); - } + ee_draw_line(x1, y1, x2, y2, '#'); + ee_refresh(); } -static void demo_circles(void) +static void demo_boxes(void) { int w = ee_get_width(); int h = ee_get_height(); + int x1, y1, x2, y2; - /* Draw circles */ if(force_clipping) { - ee_color(ee_rand(1, 10)); - ee_draw_circle(ee_rand(- w, 2 * w), - ee_rand(- h, 2 * h), - ee_rand(0, (w + h) / 2), - '#'); + x1 = ee_rand(- w, 2 * w); y1 = ee_rand(- h, 2 * h); + x2 = ee_rand(- w, 2 * w); y2 = ee_rand(- h, 2 * h); } else { - int x = ee_rand(0, w); - int y = ee_rand(0, h); - int r = ee_rand(0, (w + h) / 2); + x1 = ee_rand(0, w - 1); y1 = ee_rand(0, h - 1); + x2 = ee_rand(0, w - 1); y2 = ee_rand(0, h - 1); + } - if(x - r < 0 || x + r >= w || y - r < 0 || y + r >= h) - { - demo_circles(); - return; - } + ee_color(ee_rand(1, 10)); + ee_fill_box(x1, y1, x2, y2, '#'); + if(outline) + { ee_color(ee_rand(1, 10)); - ee_draw_circle(x, y, r, '#'); + ee_draw_thin_box(x1, y1, x2, y2); } ee_refresh(); @@ -360,93 +340,63 @@ static void demo_ellipses(void) { int w = ee_get_width(); int h = ee_get_height(); + int x, y, a, b; - /* Draw circles */ if(force_clipping) { - ee_color(ee_rand(1, 10)); - ee_draw_ellipse(ee_rand(- w, 2 * w), - ee_rand(- h, 2 * h), - ee_rand(0, w), - ee_rand(0, h), - '#'); + x = ee_rand(- w, 2 * w); y = ee_rand(- h, 2 * h); + a = ee_rand(0, w); b = ee_rand(0, h); } else { - int x = ee_rand(0, w); - int y = ee_rand(0, h); - int a = ee_rand(0, w); - int b = ee_rand(0, h); - - if(x - a < 0 || x + a >= w || y - b < 0 || y + b >= h) + do { - demo_ellipses(); - return; - } + x = ee_rand(0, w); y = ee_rand(0, h); + a = ee_rand(0, w); b = ee_rand(0, h); - ee_color(ee_rand(1, 10)); - ee_draw_ellipse(x, y, a, b, '#'); + } while(x - a < 0 || x + a >= w || y - b < 0 || y + b >= h); } - ee_refresh(); -} - -static void demo_triangles(void) -{ - int w = ee_get_width(); - int h = ee_get_height(); - - /* Draw lines */ ee_color(ee_rand(1, 10)); - if(force_clipping) - { - ee_fill_triangle(ee_rand(- w, 2 * w), ee_rand(- h, 2 * h), - ee_rand(- w, 2 * w), ee_rand(- h, 2 * h), - ee_rand(- w, 2 * w), ee_rand(- h, 2 * h), '#'); - } - else + ee_fill_ellipse(x, y, a, b, '#'); + + if(outline) { - ee_fill_triangle(ee_rand(0, w - 1), ee_rand(0, h - 1), - ee_rand(0, w - 1), ee_rand(0, h - 1), - ee_rand(0, w - 1), ee_rand(0, h - 1), '#'); + ee_color(ee_rand(1, 10)); + ee_draw_thin_ellipse(x, y, a, b); } + ee_refresh(); } -static void demo_outlined_triangles(void) +static void demo_triangles(void) { int w = ee_get_width(); int h = ee_get_height(); int x1, y1, x2, y2, x3, y3; - /* Draw lines */ - ee_color(ee_rand(1, 10)); if(force_clipping) { - x1 = ee_rand(- w, 2 * w); - y1 = ee_rand(- h, 2 * h); - x2 = ee_rand(- w, 2 * w); - y2 = ee_rand(- h, 2 * h); - x3 = ee_rand(- w, 2 * w); - y3 = ee_rand(- h, 2 * h); + x1 = ee_rand(- w, 2 * w); y1 = ee_rand(- h, 2 * h); + x2 = ee_rand(- w, 2 * w); y2 = ee_rand(- h, 2 * h); + x3 = ee_rand(- w, 2 * w); y3 = ee_rand(- h, 2 * h); } else { - x1 = ee_rand(0, w - 1); - y1 = ee_rand(0, h - 1); - x2 = ee_rand(0, w - 1); - y2 = ee_rand(0, h - 1); - x3 = ee_rand(0, w - 1); - y3 = ee_rand(0, h - 1); + x1 = ee_rand(0, w - 1); y1 = ee_rand(0, h - 1); + x2 = ee_rand(0, w - 1); y2 = ee_rand(0, h - 1); + x3 = ee_rand(0, w - 1); y3 = ee_rand(0, h - 1); } + ee_color(ee_rand(1, 10)); ee_fill_triangle(x1, y1, x2, y2, x3, y3, '#'); - ee_color(ee_rand(1, 10)); - ee_draw_thin_line(x1, y1, x2, y2); - ee_draw_thin_line(x2, y2, x3, y3); - ee_draw_thin_line(x3, y3, x1, y1); + if(outline) + { + ee_color(ee_rand(1, 10)); + ee_draw_thin_triangle(x1, y1, x2, y2, x3, y3); + } ee_refresh(); } @@ -458,49 +408,3 @@ static void demo_sprites(void) ee_refresh(); } -static void demo_pyramid(void) -{ - static int i = 0; - - int xo, yo, x1, y1, x2, y2, x3, y3; - - i++; - - xo = ee_get_width() * 5 / 8; - yo = 2; - - x1 = ee_get_width() / 8 + sin(0.03*i) * 5; - y1 = ee_get_height() / 2 + cos(0.03*i) * 5; - - x2 = ee_get_width() - 10 - cos(0.02*i) * 10; - y2 = ee_get_height() - 5 + sin(0.02*i) * 5; - - x3 = ee_get_width() / 4 - sin(0.02*i) * 5; - y3 = ee_get_height() + cos(0.02*i) * 5; - - ee_clear(); - - ee_color(EE_GREEN); - ee_fill_triangle(xo, yo, x2, y2, x1, y1, '%'); - ee_color(EE_YELLOW); - ee_draw_thin_line(xo, yo, x2, y2); - ee_draw_thin_line(x2, y2, x1, y1); - ee_draw_thin_line(x1, y1, xo, yo); - - ee_color(EE_RED); - ee_fill_triangle(x1, y1, x2, y2, x3, y3, '#'); - ee_color(EE_YELLOW); - ee_draw_thin_line(x1, y1, x2, y2); - ee_draw_thin_line(x2, y2, x3, y3); - ee_draw_thin_line(x3, y3, x1, y1); - - ee_color(EE_BLUE); - ee_fill_triangle(xo, yo, x2, y2, x3, y3, '%'); - ee_color(EE_YELLOW); - ee_draw_thin_line(xo, yo, x2, y2); - ee_draw_thin_line(x2, y2, x3, y3); - ee_draw_thin_line(x3, y3, xo, yo); - - ee_refresh(); -} -