From 0a9b9eb74141de43dfd24a3b4d04b9b066cefc08 Mon Sep 17 00:00:00 2001 From: Stanislav N Mikhailov Date: Tue, 24 Mar 2026 21:52:09 +0300 Subject: [PATCH] Split render primitives into dedicated modules --- include/display/render/bezier.h | 19 ++++++++++++++ include/display/render/grid.h | 13 ++++++++++ include/display/render/line.h | 13 ++++++++++ include/display/render/sine_wave.h | 22 ++++++++++++++++ src/render/bezier.c | 41 ++++++++++++++++++++++++++++++ src/render/grid.c | 17 +++++++++++++ src/render/line.c | 29 +++++++++++++++++++++ src/render/sine_wave.c | 27 ++++++++++++++++++++ 8 files changed, 181 insertions(+) create mode 100644 include/display/render/bezier.h create mode 100644 include/display/render/grid.h create mode 100644 include/display/render/line.h create mode 100644 include/display/render/sine_wave.h create mode 100644 src/render/bezier.c create mode 100644 src/render/grid.c create mode 100644 src/render/line.c create mode 100644 src/render/sine_wave.c diff --git a/include/display/render/bezier.h b/include/display/render/bezier.h new file mode 100644 index 0000000..ec18e08 --- /dev/null +++ b/include/display/render/bezier.h @@ -0,0 +1,19 @@ +#pragma once + +#include "display/render/context.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void render_bezier( + render_ctx_t* ctx, + const int* points_x, + const int* points_y, + size_t num_points, + uint16_t color +); + +#ifdef __cplusplus +} +#endif diff --git a/include/display/render/grid.h b/include/display/render/grid.h new file mode 100644 index 0000000..a4a253f --- /dev/null +++ b/include/display/render/grid.h @@ -0,0 +1,13 @@ +#pragma once + +#include "display/render/line.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void render_grid(render_ctx_t* ctx, uint16_t x, uint16_t y, uint16_t step, uint16_t color); + +#ifdef __cplusplus +} +#endif diff --git a/include/display/render/line.h b/include/display/render/line.h new file mode 100644 index 0000000..c184d90 --- /dev/null +++ b/include/display/render/line.h @@ -0,0 +1,13 @@ +#pragma once + +#include "display/render/context.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void render_line(render_ctx_t* ctx, int x0, int y0, int x1, int y1, uint16_t color); + +#ifdef __cplusplus +} +#endif diff --git a/include/display/render/sine_wave.h b/include/display/render/sine_wave.h new file mode 100644 index 0000000..39ab275 --- /dev/null +++ b/include/display/render/sine_wave.h @@ -0,0 +1,22 @@ +#pragma once + +#include "display/render/context.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void render_sine_wave( + render_ctx_t* ctx, + uint16_t num_points, + int amplitude, + float frequency, + int offset_x, + int offset_y, + float phase_shift, + uint16_t color +); + +#ifdef __cplusplus +} +#endif diff --git a/src/render/bezier.c b/src/render/bezier.c new file mode 100644 index 0000000..a27f0aa --- /dev/null +++ b/src/render/bezier.c @@ -0,0 +1,41 @@ +#include "display/render/bezier.h" +#include + +static float bernstein(int i, int n, float t) +{ + float binomial = 1.0f; + for (int j = 0; j < i; ++j) + { + binomial *= (float)(n - j) / (float)(j + 1); + } + return binomial * powf(t, (float)i) * powf(1.0f - t, (float)(n - i)); +} + +void render_bezier( + render_ctx_t* ctx, + const int* points_x, + const int* points_y, + size_t num_points, + uint16_t color +) +{ + if (num_points < 2) + return; + + const int steps = 1000; + for (int s = 0; s <= steps; ++s) + { + float t = (float)s / (float)steps; + float x = 0.0f; + float y = 0.0f; + + for (size_t i = 0; i < num_points; ++i) + { + float b = bernstein((int)i, (int)num_points - 1, t); + x += b * (float)points_x[i]; + y += b * (float)points_y[i]; + } + + render_pixel(ctx, (int)(x + 0.5f), (int)(y + 0.5f), color); + } +} diff --git a/src/render/grid.c b/src/render/grid.c new file mode 100644 index 0000000..119a427 --- /dev/null +++ b/src/render/grid.c @@ -0,0 +1,17 @@ +#include "display/render/grid.h" + +void render_grid(render_ctx_t* ctx, uint16_t x, uint16_t y, uint16_t step, uint16_t color) +{ + if (step == 0 || ctx->width == 0 || ctx->height == 0) + return; + + for (uint16_t v = x; v < ctx->width; v = (uint16_t)(v + step)) + { + render_line(ctx, v, 0, v, (int)ctx->height - 1, color); + } + + for (uint16_t h = y; h < ctx->height; h = (uint16_t)(h + step)) + { + render_line(ctx, 0, h, (int)ctx->width - 1, h, color); + } +} diff --git a/src/render/line.c b/src/render/line.c new file mode 100644 index 0000000..0431946 --- /dev/null +++ b/src/render/line.c @@ -0,0 +1,29 @@ +#include "display/render/line.h" + +void render_line(render_ctx_t* ctx, int x0, int y0, int x1, int y1, uint16_t color) +{ + int dx = (x1 >= x0) ? (x1 - x0) : (x0 - x1); + int sx = (x0 < x1) ? 1 : -1; + int dy = (y1 >= y0) ? (y0 - y1) : (y1 - y0); + int sy = (y0 < y1) ? 1 : -1; + int err = dx + dy; + + while (1) + { + render_pixel(ctx, x0, y0, color); + if (x0 == x1 && y0 == y1) + break; + + int e2 = err * 2; + if (e2 >= dy) + { + err += dy; + x0 += sx; + } + if (e2 <= dx) + { + err += dx; + y0 += sy; + } + } +} diff --git a/src/render/sine_wave.c b/src/render/sine_wave.c new file mode 100644 index 0000000..5dad2e6 --- /dev/null +++ b/src/render/sine_wave.c @@ -0,0 +1,27 @@ +#include "display/render/sine_wave.h" +#include + +void render_sine_wave( + render_ctx_t* ctx, + uint16_t num_points, + int amplitude, + float frequency, + int offset_x, + int offset_y, + float phase_shift, + uint16_t color +) +{ + if (num_points < 2 || ctx->width == 0 || ctx->height == 0) + return; + + float step = (2.0f * (float)M_PI * frequency) / (float)(num_points - 1u); + float x_step = (float)ctx->width / (float)(num_points - 1u); + + for (uint16_t i = 0; i < num_points; ++i) + { + int x = offset_x + (int)((float)i * x_step); + int y = offset_y + (int)((float)amplitude * sinf((float)i * step + phase_shift)); + render_pixel(ctx, x, y, color); + } +}