This commit is contained in:
kraus 2023-08-13 10:45:55 +02:00
parent 723c5b603d
commit 272321282f
3 changed files with 157 additions and 0 deletions

12
sys/sdl/draw_arc/Makefile Normal file
View File

@ -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

143
sys/sdl/draw_arc/main.c Normal file
View File

@ -0,0 +1,143 @@
#include "u8g2.h"
#include <stdio.h>
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;
}

View File

@ -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