圆弧 (Geometry Arc)
概述
圆弧控件是一个轻量级的 GUI 绘图组件,专门用于在用户界面中绘制圆弧和圆环图形。该控件提供了简洁易用的 API ,支持自定义圆弧的起始角度、结束角度、线宽、颜色等属性,能够满足各种圆弧绘制需求。

核心功能
描述 |
API |
|---|---|
创建控件 |
|
设置位置 |
|
设置半径 |
|
设置颜色 |
|
设置不透明度 |
|
设置起始角度 |
|
设置结束角度 |
|
设置线宽 |
|
注册点击事件回调 |
|
旋转变换 |
|
缩放变换 |
|
平移变换 |
|
设置角度渐变 |
|
添加渐变色点 |
|
清除渐变色 |
圆弧组功能
描述 |
API |
|---|---|
创建圆弧组 |
|
添加圆弧到组 |
|
设置圆弧渐变 |
|
添加渐变色点 |
角度说明
圆弧的角度系统采用标准的数学坐标系:
0°: 3点钟方向(正东方向)
90°: 6点钟方向(正南方向)
180°: 9点钟方向(正西方向)
270°: 12点钟方向(正北方向)
渐变色填充
圆弧控件支持角度渐变色填充,可以沿着圆弧的角度方向实现平滑的颜色过渡效果。

渐变色工作原理
渐变色沿圆弧的角度方向线性插值
支持最多 8 个颜色停止点(color stops)
颜色停止点的位置用 0.0 ~ 1.0 的归一化值表示,其中 0.0 对应起始角度,1.0 对应结束角度
像素颜色通过在相邻颜色停止点之间进行线性插值计算得出
采用角度渐变(Angular Gradient)方式,沿圆弧的角度方向平滑过渡
使用步骤
创建圆弧控件
调用
gui_arc_set_angular_gradient()设置渐变范围调用
gui_arc_add_gradient_stop()添加颜色停止点(至少需要 2 个)可选:调用
gui_arc_clear_gradient()清除渐变设置
关键要点
无缝循环: 对于完整圆环(0° 到 360°),起始颜色和结束颜色应相同,以实现无缝的颜色循环
颜色插值: 支持 RGBA 颜色空间的线性插值,包括透明度通道
性能优化: 采用颜色查找表(LUT)预计算,确保高效的渲染性能
特性亮点
高性能: 采用优化的绘制算法,确保流畅的渲染性能
抗锯齿: 支持边缘抗锯齿,提供平滑的视觉效果
灵活配置: 支持自定义角度范围、线宽和颜色
轻量级: 内存占用小,适合嵌入式系统和资源受限环境
圆环支持: 当起始角度和结束角度相差360°时,自动绘制完整圆环
矩阵变换: 支持旋转、缩放、平移等矩阵变换操作,实现复杂的圆弧变换效果
批量渲染: 圆弧组控件支持将多个静态圆弧批量渲染到单个缓冲区,提升渲染性能
圆弧组控件
圆弧组控件专为批量渲染多个静态圆弧而设计,通过将多个圆弧合并到单个缓冲区中,显著减少硬件传输操作,提升渲染性能。
性能优势
应用场景
活动圆环(健身追踪显示)
多层进度指示器
带有多个圆形元素的仪表盘背景
静态装饰性圆弧图案
限制说明
每组最多支持 8 个圆弧(可通过 MAX_ARCS_IN_GROUP 配置)
组内所有圆弧共享同一缓冲区并一起渲染
最适合静态或不经常变化的内容
应用场景
圆弧控件适用于以下场景:
进度指示器: 用于显示加载进度、电池电量等
仪表盘: 构建速度表、温度计等仪表界面
数据可视化: 展示比例数据、统计图表
用户界面装饰: 作为界面的装饰元素
状态指示: 表示系统状态、连接状态等
变换动画: 利用旋转、缩放、平移实现复杂的圆弧动画效果
配置说明
要使用圆弧控件,需要在配置文件中启用相应的宏定义:
通过 menuconfig 启用 Kconfig 选项:
cd win32_sim
menuconfig ../Kconfig.gui
选择 Geometry ARC Demo ( CONFIG_REALTEK_BUILD_REAL_LITE_ARC ),保存到 win32_sim/.config。
#define CONFIG_REALTEK_BUILD_REAL_LITE_ARC 1
完整示例
#include "guidef.h"
#include "gui_components_init.h"
#include "gui_arc.h"
#include "gui_arc_group.h"
#include "gui_rect.h"
#include "gui_circle.h"
static void create_activity_rings(float center_x, float center_y)
{
// bg track color
gui_color_t track_color_move = gui_rgba(52, 14, 11, 200);
gui_color_t track_color_exercise = gui_rgba(16, 37, 17, 200);
gui_color_t track_color_stand = gui_rgba(17, 32, 52, 200);
// fg color
gui_color_t col_move = gui_rgba(255, 0, 0, 255); // Move red
gui_color_t col_exercise = gui_rgba(0, 255, 0, 255); // Exercise green
gui_color_t col_stand = gui_rgba(0, 0, 255, 255); // Stand blue
// circle radius and thickness
float outer_radius = 163.0f; float outer_thickness = 22.0f;
float mid_radius = 136.5f; float mid_thickness = 22.0f;
float inner_radius = 110.0f; float inner_thickness = 22.0f;
uint16_t start_angle = 0;
// background rings
gui_arc_t *ring_move = gui_arc_create(gui_obj_get_root(), "test_ring_move", center_x,
center_y, outer_radius, 0, 360, outer_thickness,
track_color_move);
gui_arc_t *ring_exercise = gui_arc_create(gui_obj_get_root(), "test_ring_exercise",
center_x, center_y, mid_radius, 0, 360, mid_thickness,
track_color_exercise);
gui_arc_t *ring_stand = gui_arc_create(gui_obj_get_root(), "test_ring_stand", center_x,
center_y, inner_radius, 0, 360, inner_thickness,
track_color_stand);
GUI_UNUSED(ring_move);
GUI_UNUSED(ring_exercise);
GUI_UNUSED(ring_stand);
// arc style
gui_arc_t *arc_move = gui_arc_create(gui_obj_get_root(), "test_arc_move", center_x,
center_y, outer_radius,
start_angle, start_angle + 252.0f, outer_thickness, col_move);
gui_arc_t *arc_exercise = gui_arc_create(gui_obj_get_root(), "test_arc_exercise",
center_x, center_y, mid_radius,
start_angle, start_angle + 72.0f, mid_thickness, col_exercise);
gui_arc_t *arc_stand = gui_arc_create(gui_obj_get_root(), "test_arc_stand", center_x,
center_y, inner_radius,
start_angle, start_angle + 198.0f, inner_thickness, col_stand);
GUI_UNUSED(arc_move);
GUI_UNUSED(arc_exercise);
GUI_UNUSED(arc_stand);
}
void example_arc_gradient(void *parent)
{
// Example 1: Simple two-color angular gradient (red to blue)
// NOTE: Arc is 0-360 (full circle), but gradient is 0-361 (exceeds 360)
// This allows the end cap to show gradient color for smooth transition
gui_arc_t *arc1 = gui_arc_create(parent, "arc_gradient_1",
120, 120, 80, // center x, y, radius
270, 270, // start angle, end angle (FULL CIRCLE)
20, // line width
gui_rgba(255, 0, 0, 255)); // fallback color (red)
// Set angular gradient with span > 360 for end cap gradient
gui_arc_set_angular_gradient(arc1, 270, 270);
gui_arc_add_gradient_stop(arc1, 0.0f, gui_rgba(255, 0, 0, 255)); // Red
gui_arc_add_gradient_stop(arc1, 1.0f, gui_rgba(0, 0, 255, 255)); // Blue
// Example 2: Multi-color rainbow gradient (full circle, seamless loop)
gui_arc_t *arc2 = gui_arc_create(parent, "arc_gradient_2",
320, 120, 80,
0, 360,
20,
gui_rgba(255, 0, 0, 255)); // fallback color (red)
gui_arc_set_angular_gradient(arc2, 0, 360);
// Redistribute color stops with 7 intervals, step ~0.142
// Key point: 0.0f and 1.0f must be the same color (Red) for seamless loop
// 1. Red (start)
gui_arc_add_gradient_stop(arc2, 0.00f, gui_rgba(255, 0, 0, 255));
// 2. Orange
gui_arc_add_gradient_stop(arc2, 0.14f, gui_rgba(255, 127, 0, 255));
// 3. Yellow
gui_arc_add_gradient_stop(arc2, 0.28f, gui_rgba(255, 255, 0, 255));
// 4. Green
gui_arc_add_gradient_stop(arc2, 0.42f, gui_rgba(0, 255, 0, 255));
// 5. Blue
gui_arc_add_gradient_stop(arc2, 0.57f, gui_rgba(0, 0, 255, 255));
// 6. Indigo
gui_arc_add_gradient_stop(arc2, 0.71f, gui_rgba(75, 0, 130, 255));
// 7. Violet - not at 1.0f to leave space for transition back to red
gui_arc_add_gradient_stop(arc2, 0.85f, gui_rgba(148, 0, 211, 255));
// 8. Red (end) - must return to red to eliminate seam
gui_arc_add_gradient_stop(arc2, 1.00f, gui_rgba(255, 0, 0, 255));
// Example 3: Gradient with transparency (fade effect)
gui_arc_t *arc3 = gui_arc_create(parent, "arc_gradient_3",
120, 320, 80,
45, 315,
25,
gui_rgba(0, 255, 0, 255)); // fallback color (green)
gui_arc_set_angular_gradient(arc3, 45, 315);
gui_arc_add_gradient_stop(arc3, 0.0f, gui_rgba(0, 255, 0, 255)); // Opaque green
gui_arc_add_gradient_stop(arc3, 0.5f, gui_rgba(0, 255, 255, 255)); // Cyan
gui_arc_add_gradient_stop(arc3, 1.0f, gui_rgba(0, 255, 0, 51)); // Transparent green (alpha=51)
// Example 4: Progress bar style gradient
gui_arc_t *arc4 = gui_arc_create(parent, "arc_gradient_4",
320, 320, 80,
-90, 180, // Start from top
30,
gui_rgba(0, 255, 0, 255)); // fallback color (green)
gui_arc_set_angular_gradient(arc4, -90, 180);
gui_arc_add_gradient_stop(arc4, 0.0f, gui_rgba(255, 0, 0, 255)); // Red (start)
gui_arc_add_gradient_stop(arc4, 0.5f, gui_rgba(255, 255, 0, 255)); // Yellow (middle)
gui_arc_add_gradient_stop(arc4, 1.0f, gui_rgba(0, 255, 0, 255)); // Green (end)
}
void example_arc_group(void *parent)
{
// Example: Arc Group for batch rendering multiple static arcs
// This is useful for background rings that don't change frequently
// Performance benefit: Reduces DMA/GPU transfer calls by combining multiple arcs into one buffer
float center_x = 240.0f;
float center_y = 240.0f;
// Calculate bounding box for the arc group
float outer_radius = 163.0f;
float outer_thickness = 22.0f;
int box_size = (int)(outer_radius + outer_thickness / 2 + 2) * 2 + 4;
int box_x = (int)center_x - box_size / 2;
int box_y = (int)center_y - box_size / 2;
// Create arc group for background rings
gui_arc_group_t *bg_group = gui_arc_group_create(parent, "bg_rings",
box_x, box_y, box_size, box_size);
float group_cx = box_size / 2.0f, group_cy = group_cx;
// Add first arc (outer ring) with gradient
int arc0 = gui_arc_group_add_arc(bg_group, group_cx, group_cy,
163.0f, 0, 360, 22.0f, gui_rgba(50, 50, 50, 255));
gui_arc_group_set_gradient(bg_group, arc0, 0, 360);
gui_arc_group_add_gradient_stop(bg_group, arc0, 0.0f, gui_rgba(60, 0, 0, 100));
gui_arc_group_add_gradient_stop(bg_group, arc0, 0.5f, gui_rgba(80, 20, 20, 100));
gui_arc_group_add_gradient_stop(bg_group, arc0, 1.0f, gui_rgba(60, 0, 0, 100));
// Add second arc (middle ring) with gradient
int arc1 = gui_arc_group_add_arc(bg_group, group_cx, group_cy,
136.5f, 0, 360, 22.0f, gui_rgba(50, 50, 50, 255));
gui_arc_group_set_gradient(bg_group, arc1, 0, 360);
gui_arc_group_add_gradient_stop(bg_group, arc1, 0.0f, gui_rgba(0, 60, 0, 100));
gui_arc_group_add_gradient_stop(bg_group, arc1, 0.5f, gui_rgba(20, 80, 20, 100));
gui_arc_group_add_gradient_stop(bg_group, arc1, 1.0f, gui_rgba(0, 60, 0, 100));
// Add third arc (inner ring) with gradient
int arc2 = gui_arc_group_add_arc(bg_group, group_cx, group_cy,
110.0f, 0, 360, 22.0f, gui_rgba(50, 50, 50, 255));
gui_arc_group_set_gradient(bg_group, arc2, 0, 360);
gui_arc_group_add_gradient_stop(bg_group, arc2, 0.0f, gui_rgba(0, 20, 60, 100));
gui_arc_group_add_gradient_stop(bg_group, arc2, 0.5f, gui_rgba(20, 40, 80, 100));
gui_arc_group_add_gradient_stop(bg_group, arc2, 1.0f, gui_rgba(0, 20, 60, 100));
// Create foreground arcs separately (these can change dynamically)
gui_arc_t *arc_move = gui_arc_create(parent, "fg_arc_move", center_x, center_y,
163.0f, 0, 252.0f, 22.0f, gui_rgba(255, 0, 0, 255));
gui_arc_set_angular_gradient(arc_move, 0, 252.0f);
gui_arc_add_gradient_stop(arc_move, 0.0f, gui_rgba(250, 17, 79, 255));
gui_arc_add_gradient_stop(arc_move, 1.0f, gui_rgba(255, 100, 150, 255));
gui_arc_t *arc_exercise = gui_arc_create(parent, "fg_arc_exercise", center_x, center_y,
136.5f, 0, 72.0f, 22.0f, gui_rgba(0, 255, 0, 255));
gui_arc_set_angular_gradient(arc_exercise, 0, 72.0f);
gui_arc_add_gradient_stop(arc_exercise, 0.0f, gui_rgba(164, 255, 4, 255));
gui_arc_add_gradient_stop(arc_exercise, 1.0f, gui_rgba(255, 255, 0, 255));
gui_arc_t *arc_stand = gui_arc_create(parent, "fg_arc_stand", center_x, center_y,
110.0f, 0, 198.0f, 22.0f, gui_rgba(0, 0, 255, 255));
gui_arc_set_angular_gradient(arc_stand, 0, 198.0f);
gui_arc_add_gradient_stop(arc_stand, 0.0f, gui_rgba(0, 255, 255, 255));
gui_arc_add_gradient_stop(arc_stand, 1.0f, gui_rgba(0, 150, 255, 255));
GUI_UNUSED(bg_group);
GUI_UNUSED(arc_move);
GUI_UNUSED(arc_exercise);
GUI_UNUSED(arc_stand);
}
static int geometry_demo_init(void)
{
// float center_x = 480 / 2.0f;
// float center_y = 480 / 2.0f;
// create_activity_rings(center_x, center_y);
// example_arc_gradient(gui_obj_get_root());
example_arc_group(gui_obj_get_root());
return 0;
}
GUI_INIT_APP_EXPORT(geometry_demo_init);
API
Functions
-
gui_arc_t *gui_arc_create(void *parent, const char *name, int x, int y, int radius, float start_angle, float end_angle, float line_width, gui_color_t color)
-
Create a new arc widget.
- 参数:
parent -- Parent widget or NULL for top-level widget.
name -- Name of the widget.
x -- Center X coordinate.
y -- Center Y coordinate.
radius -- Arc radius.
start_angle -- Start angle in degrees.
end_angle -- End angle in degrees.
line_width -- Line width.
color -- Arc color.
- 返回:
-
Pointer to the created arc widget.
-
void gui_arc_set_position(gui_arc_t *arc, int x, int y)
-
Move arc geometry.
- 参数:
arc -- Pointer to the arc widget.
x -- New center X coordinate relative to widget.
y -- New center Y coordinate relative to widget.
-
void gui_arc_set_radius(gui_arc_t *arc, int radius)
-
Set the radius of the arc widget.
- 参数:
arc -- Pointer to the arc widget.
radius -- Arc radius.
-
void gui_arc_set_opacity(gui_arc_t *arc, uint8_t opacity)
-
Set the opacity of the arc widget.
- 参数:
arc -- Pointer to the arc widget.
opacity -- Opacity value (0-255).
-
void gui_arc_set_color(gui_arc_t *arc, gui_color_t color)
-
Set the color of the arc widget.
- 参数:
arc -- Pointer to the arc widget.
color -- Arc color.
-
void gui_arc_set_start_angle(gui_arc_t *arc, float start_angle)
-
Set the start angle of the arc widget.
- 参数:
arc -- Pointer to the arc widget.
start_angle -- Start angle in degrees.
-
void gui_arc_set_end_angle(gui_arc_t *arc, float end_angle)
-
Set the end angle of the arc widget.
- 参数:
arc -- Pointer to the arc widget.
end_angle -- End angle in degrees.
-
void gui_arc_set_line_width(gui_arc_t *arc, float line_width)
-
Set the line width of the arc widget.
- 参数:
arc -- Pointer to the arc widget.
line_width -- Line width.
-
void gui_arc_on_click(gui_arc_t *arc, void *callback, void *parameter)
-
Register click event callback for arc widget.
- 参数:
arc -- Pointer to the arc widget.
callback -- Callback function pointer.
parameter -- Optional parameter to pass to callback.
-
void gui_arc_rotate(gui_arc_t *arc, float degrees)
-
Apply rotation transformation to the arc widget.
- 参数:
arc -- Pointer to the arc widget.
degrees -- Rotation angle in degrees (clockwise).
-
void gui_arc_scale(gui_arc_t *arc, float scale_x, float scale_y)
-
Apply scale transformation to the arc widget.
- 参数:
arc -- Pointer to the arc widget.
scale_x -- Scale factor in X direction.
scale_y -- Scale factor in Y direction.
-
void gui_arc_translate(gui_arc_t *arc, float tx, float ty)
-
Apply translation transformation to the arc widget.
- 参数:
arc -- Pointer to the arc widget.
tx -- Translation in X direction (pixels).
ty -- Translation in Y direction (pixels).
-
void gui_arc_set_angular_gradient(gui_arc_t *arc, float start_angle, float end_angle)
-
Set angular gradient for arc widget.
- 参数:
arc -- Pointer to the arc widget.
start_angle -- Start angle for gradient (degrees).
end_angle -- End angle for gradient (degrees).
-
struct gui_arc_t
-
Arc widget structure.
Public Members
-
gui_obj_t base
-
Base widget.
-
draw_img_t *draw_img
-
Drawing image object.
-
uint8_t *pixel_buffer
-
Cached pixel buffer.
-
uint32_t buffer_size
-
Buffer size.
-
int buffer_w
-
Actual buffer width (may be optimized).
-
int buffer_h
-
Actual buffer height (may be optimized).
-
bool buffer_valid
-
Buffer cache valid flag.
-
DrawContext draw_ctx
-
Drawing context.
-
uint8_t opacity_value
-
Opacity value.
-
int x
-
Center X coordinate relative to widget.
-
int y
-
Center Y coordinate relative to widget.
-
int radius
-
Arc radius.
-
float start_angle
-
Start angle in degrees.
-
float end_angle
-
End angle in degrees.
-
float line_width
-
Line width.
-
gui_color_t color
-
Arc color (stored as uint32_t internally).
-
int cached_x
-
int cached_y
-
int cached_radius
-
float cached_start_angle
-
float cached_end_angle
-
float cached_line_width
-
gui_color_t cached_color
-
uint32_t cached_not_show
-
float degrees
-
Rotation angle in degrees.
-
float scale_x
-
Scale factor in X direction.
-
float scale_y
-
Scale factor in Y direction.
-
float offset_x
-
Translation offset in X direction.
-
float offset_y
-
Translation offset in Y direction.
-
Gradient *gradient
-
Optional gradient for arc stroke.
-
bool use_gradient
-
Flag to enable gradient rendering.
-
gui_obj_t base
Defines
-
MAX_ARCS_IN_GROUP 8
Functions
-
gui_arc_group_t *gui_arc_group_create(void *parent, const char *name, int x, int y, int w, int h)
-
Create arc group widget.
- 参数:
parent -- Parent widget.
name -- Widget name.
x -- X position.
y -- Y position.
w -- Width.
h -- Height.
- 返回:
-
Pointer to created arc group.
-
int gui_arc_group_add_arc(gui_arc_group_t *group, float cx, float cy, float radius, float start_angle, float end_angle, float line_width, gui_color_t color)
-
Add arc to group.
- 参数:
group -- Arc group widget.
cx -- Center X relative to group.
cy -- Center Y relative to group.
radius -- Arc radius.
start_angle -- Start angle.
end_angle -- End angle.
line_width -- Line width.
color -- Arc color.
- 返回:
-
Index of added arc, or -1 if group is full.
-
void gui_arc_group_set_gradient(gui_arc_group_t *group, int arc_index, float start_angle, float end_angle)
-
Set gradient for arc in group.
- 参数:
group -- Arc group widget.
arc_index -- Index of arc (returned by add_arc).
start_angle -- Gradient start angle.
end_angle -- Gradient end angle.
-
void gui_arc_group_add_gradient_stop(gui_arc_group_t *group, int arc_index, float position, gui_color_t color)
-
Add gradient stop to arc in group.
- 参数:
group -- Arc group widget.
arc_index -- Index of arc.
position -- Stop position (0.0-1.0).
color -- Stop color.
-
struct arc_def_t
-
Arc definition for group rendering
Public Members
-
float cx
-
Center X relative to group.
-
float cy
-
Center Y relative to group.
-
float radius
-
Arc radius.
-
float start_angle
-
Start angle in degrees.
-
float end_angle
-
End angle in degrees.
-
float line_width
-
Line width.
-
Gradient *gradient
-
Optional gradient.
-
bool use_gradient
-
Use gradient flag.
-
gui_color_t color
-
Solid color (if no gradient).
-
float cx
-
struct gui_arc_group_t
-
Arc group widget structure
Public Members
-
gui_obj_t base
-
Base widget.
-
draw_img_t *draw_img
-
Drawing image object.
-
uint8_t *pixel_buffer
-
Cached pixel buffer.
-
uint32_t buffer_size
-
Buffer size.
-
bool buffer_valid
-
Buffer cache valid flag.
-
DrawContext draw_ctx
-
Drawing context.
-
uint8_t opacity_value
-
Opacity value.
-
int arc_count
-
Number of arcs in group.
-
int buffer_w
-
Buffer width.
-
int buffer_h
-
Buffer height.
-
gui_obj_t base