diff --git a/sys/sdl/draw_arc/Makefile b/sys/sdl/draw_arc/Makefile new file mode 100644 index 000000000..5030fe50e --- /dev/null +++ b/sys/sdl/draw_arc/Makefile @@ -0,0 +1,12 @@ +CFLAGS = -g -Wall -I../../../csrc/. `sdl2-config --cflags` + +SRC = $(shell ls ../../../csrc/*.c) $(shell ls ../common/*.c ) $(shell ls ../../bitmap/common/*.c ) $(shell ls *.c ) + +OBJ = $(SRC:.c=.o) + +u8g2_sdl: $(OBJ) + $(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) `sdl2-config --libs` -o u8g2_sdl + +clean: + -rm $(OBJ) u8g2_sdl + diff --git a/sys/sdl/draw_arc/main.c b/sys/sdl/draw_arc/main.c new file mode 100644 index 000000000..f24c1de75 --- /dev/null +++ b/sys/sdl/draw_arc/main.c @@ -0,0 +1,143 @@ + +#include "u8g2.h" +#include + + +typedef float (*u8g2_atan2f_t)(float, float); + + +static const float M_PI_2 = 1.57079632679489661923; +static const float M_PI_4 = 0.78539816339744830962; + +void u8g2_draw_arc(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rad_in, u8g2_uint_t rad_out, u8g2_uint_t angle_start, u8g2_uint_t angle_end, u8g2_atan2f_t atan2f_func) +{ + // Declare variables + u8g2_long_t x, y, d, r, as, ae, cnt, num_pts; + + // Manage angle inputs + if(angle_start == angle_end) return; + uint8_t inverted = (angle_start > angle_end); + as = inverted ? angle_end : angle_start; + ae = inverted ? angle_start : angle_end; + + // Trace each arc radius with the Andres circle algorithm + for(r = rad_in; r <= rad_out; r++) + { + x = 0; + y = r; + d = r - 1; + cnt = -1; + num_pts = atan2f_func ? 100 : (r * 8 / 10); // if no atan2f() function is provided, we make a low cost approximation of the number of pixels drawn for a 1/8th circle of radius r + + // Process each pixel of a 1/8th circle of radius r + while (y >= x) + { + // If atan2f() function is provided, get the percentage of 1/8th circle drawn, otherwise count the drawn pixels + cnt = atan2f_func ? ((M_PI_2 - atan2f_func(y, x)) * 100 / M_PI_4) : (cnt + 1); + + // Fill the pixels of the 8 sections of the circle, but only on the arc defined by the angles (start and end) + if((cnt > num_pts * as / 45 && cnt <= num_pts * ae / 45) ^ inverted) u8g2_DrawPixel(u8g2, x0 + y, y0 - x); + if((cnt > num_pts * (90 - ae) / 45 && cnt <= num_pts * (90 - as) / 45) ^ inverted) u8g2_DrawPixel(u8g2, x0 + x, y0 - y); + if((cnt > num_pts * (as - 90) / 45 && cnt <= num_pts * (ae - 90) / 45) ^ inverted) u8g2_DrawPixel(u8g2, x0 - x, y0 - y); + if((cnt > num_pts * (180 - ae) / 45 && cnt <= num_pts * (180 - as) / 45) ^ inverted) u8g2_DrawPixel(u8g2, x0 - y, y0 - x); + if((cnt > num_pts * (as - 180) / 45 && cnt <= num_pts * (ae - 180) / 45) ^ inverted) u8g2_DrawPixel(u8g2, x0 - y, y0 + x); + if((cnt > num_pts * (270 - ae) / 45 && cnt <= num_pts * (270 - as) / 45) ^ inverted) u8g2_DrawPixel(u8g2, x0 - x, y0 + y); + if((cnt > num_pts * (as - 270) / 45 && cnt <= num_pts * (ae - 270) / 45) ^ inverted) u8g2_DrawPixel(u8g2, x0 + x, y0 + y); + if((cnt > num_pts * (360 - ae) / 45 && cnt <= num_pts * (360 - as) / 45) ^ inverted) u8g2_DrawPixel(u8g2, x0 + y, y0 + x); + + // Run Andres circle algorithm to get to the next pixel + if (d >= 2 * x) + { + d = d - 2 * x - 1; + x = x + 1; + } else if (d < 2 * (r - y)) + { + d = d + 2 * y - 1; + y = y - 1; + } else + { + d = d + 2 * (y - x - 1); + y = y - 1; + x = x + 1; + } + } + } +} + +u8g2_t u8g2; + +int main(void) +{ + int x, y; + int k; + int i; + + u8g2_uint_t rad_in = 10; + u8g2_uint_t rad_out = 14; + + u8g2_uint_t angle_start = 0; + u8g2_uint_t angle_end = 60; + + u8g2_SetupBuffer_SDL_128x64_4(&u8g2, &u8g2_cb_r0); + + u8x8_ConnectBitmapToU8x8(u8g2_GetU8x8(&u8g2)); /* connect to bitmap */ + + u8x8_InitDisplay(u8g2_GetU8x8(&u8g2)); + u8x8_SetPowerSave(u8g2_GetU8x8(&u8g2), 0); + + u8g2_SetFont(&u8g2, u8g2_font_helvB18_tn); + + x = 50; + y = 30; + + + for(;;) + { + + + u8g2_FirstPage(&u8g2); + do + { + //u8g2_SetFontDirection(&u8g2, 0); + //u8g2_DrawStr(&u8g2, x, y, "123"); + + u8g2_draw_arc(&u8g2, x, y, rad_in, rad_out, angle_start, angle_end, 0); + + + } while( u8g2_NextPage(&u8g2) ); + + do + { + k = u8g_sdl_get_key(); + } while( k < 0 ); + + if ( k == 273 ) y -= 7; + if ( k == 274 ) y += 7; + if ( k == 276 ) x -= 7; + if ( k == 275 ) x += 7; + + if ( k == 'o' ) rad_out -= 1; + if ( k == 'p' ) rad_out += 1; + + if ( k == 'u' ) rad_in -= 1; + if ( k == 'i' ) rad_in += 1; + + if ( k == 'k' ) angle_end -= 1; + if ( k == 'l' ) angle_end += 1; + + + if ( k == 'e' ) y -= 1; + if ( k == 'x' ) y += 1; + if ( k == 's' ) x -= 1; + if ( k == 'd' ) x += 1; + if ( k == 'q' ) break; + + if ( k == 't' ) + u8x8_SaveBitmapTGA(u8g2_GetU8x8(&u8g2), "screenshot.tga"); + + printf("rad_in=%d rad_out=%d angle_end=%d\n", rad_in, rad_out, angle_end); + } + + return 0; +} + diff --git a/sys/sdl/issue2228/main.c b/sys/sdl/issue2228/main.c index 665f7d76b..5b58af1ff 100644 --- a/sys/sdl/issue2228/main.c +++ b/sys/sdl/issue2228/main.c @@ -34,6 +34,8 @@ int main(void) { u8g2_DrawUTF8(&u8g2, offset,30,"123456789QWERTYUIOPASDFGHJKLZXCVBNM123456789QWERTYUIOPASDFGHJKLZXCVBNM"); u8g2_DrawUTF8X2(&u8g2, offset,60,"123456789QWERTYUIOPASDFGHJKLZXCVBNM123456789QWERTYUIOPASDFGHJKLZXCVBNM"); + //u8g2_DrawHLine(&u8g2, 0, 64, 64); + u8g2_DrawLine(&u8g2, 30, 10, 30, 100); } while( u8g2_NextPage(&u8g2) ); do