diff --git a/libee/Makefile.am b/libee/Makefile.am index ecb2aeb..2bf265e 100644 --- a/libee/Makefile.am +++ b/libee/Makefile.am @@ -19,9 +19,10 @@ libee_a_SOURCES = \ ee.c \ ee.h \ io.c \ - circle.c \ - line.c \ math.c \ + line.c \ + circle.c \ + triangle.c \ $(NULL) libee_a_CPPFLAGS = $(CPPFLAGS_slang) $(CPPFLAGS_ncurses) diff --git a/libee/ee.h b/libee/ee.h index 75f084d..bd91943 100644 --- a/libee/ee.h +++ b/libee/ee.h @@ -73,9 +73,10 @@ void ee_end(void); char ee_get_key(void); -void ee_draw_circle(int, int, int, char); 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_fill_triangle(int, int, int, int, int, int, char); int ee_rand(int, int); int ee_sqrt(int); diff --git a/libee/triangle.c b/libee/triangle.c new file mode 100644 index 0000000..2a63d4a --- /dev/null +++ b/libee/triangle.c @@ -0,0 +1,90 @@ +/* + * 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" + +#include + +#include "ee.h" + +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; + + /* Bubble-sort y1 <= y2 <= y3 */ + if(y1 > y2) + { + ee_fill_triangle(x2, y2, x1, y1, x3, y3, c); + return; + } + + if(y2 > y3) + { + ee_fill_triangle(x1, y1, x3, y3, x2, y2, c); + return; + } + + /* Promote precision */ + x1 *= 4; + x2 *= 4; + x3 *= 4; + + xmax = ee_get_width() - 1; + ymax = ee_get_height() - 1; + + /* Rasterize our triangle */ + for(y = y1 < 0 ? 0 : y1; y <= y3 && y <= ymax; y++) + { + if(y <= y2) + { + xa = (y1 == y2) ? x2 : x1 + (x2 - x1) * (y - y1) / (y2 - y1); + xb = (y1 == y3) ? x3 : x1 + (x3 - x1) * (y - y1) / (y3 - y1); + } + else + { + xa = (y3 == y2) ? x2 : x3 + (x2 - x3) * (y - y3) / (y2 - y3); + xb = (y3 == y1) ? x1 : x3 + (x1 - x3) * (y - y3) / (y1 - y3); + } + + if(xb < xa) + { + int tmp = xb; + xb = xa; xa = tmp; + } + + /* Rescale xa and xb, slightly cropping */ + xa = (xa + 2) / 4; + xb = (xb - 2) / 4; + + if(xb < 0) continue; + if(xa > xmax) continue; + if(xa < 0) xa = 0; + if(xb > xmax) xb = xmax; + + for(x = xa; x <= xb; x++) + { + ee_goto(x, y); + ee_putchar(c); + } + } +} + diff --git a/test/Makefile.am b/test/Makefile.am index 85288bd..665913f 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -20,5 +20,5 @@ bin_PROGRAMS = demo demo_SOURCES = demo.c demo_CPPFLAGS = -I../libee $(CPPFLAGS_slang) $(CPPFLAGS_ncurses) -demo_LDADD = ../libee/libee.a $(LDFLAGS_slang) $(LDFLAGS_ncurses) +demo_LDADD = ../libee/libee.a $(LDFLAGS_slang) $(LDFLAGS_ncurses) -lm diff --git a/test/demo.c b/test/demo.c index f3cc5bd..7e1cc92 100644 --- a/test/demo.c +++ b/test/demo.c @@ -20,6 +20,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "config.h" + #include #include @@ -31,6 +33,7 @@ static void demo_dots(void); static void demo_lines(void); static void demo_thin_lines(void); static void demo_circles(void); +static void demo_triangle(void); static void demo_radar(void); int clipping = 0; @@ -81,6 +84,10 @@ int main(int argc, char **argv) demo = demo_circles; break; case '5': + ee_clear(); + demo = demo_triangle; + break; + case '6': ee_clear(); demo = demo_radar; break; @@ -123,7 +130,9 @@ static void display_menu(void) ee_goto(4, 9); ee_putstr("4: circles demo"); ee_goto(4, 10); - ee_putstr("5: radar demo"); + ee_putstr("5: triangle demo"); + ee_goto(4, 11); + ee_putstr("6: radar demo"); ee_goto(4, yo - 2); ee_putstr("q: quit"); @@ -220,6 +229,52 @@ static void demo_circles(void) ee_refresh(); } +static void demo_triangle(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(); +} + static void demo_radar(void) { static int i = 0;