什么是贝塞尔曲线
贝塞尔曲线(Bézier Curve,也被称为贝塞尔多项式(Bézier Polynomial),是由一系列控制点(Control Point)所定义的一条平滑曲线。Pierre Bézier于1960年开始利用该曲线设计雷诺的车身线条,故命名为贝塞尔曲线。目前,贝塞尔曲线被广泛应用于图形设计、路径优化(无人机、无人驾驶相关)等诸多相关领域中。
贝塞尔具体描述,可以搜索,网上也是一大把,如下链接为推导过程
贝塞尔曲线(Bezier Curve)原理、公式推导及matlab代码实现_beijing_txr的博客-CSDN博客_贝塞尔曲线
lvgl 贝塞尔函数(三阶函数):
lvgl提供了三阶贝塞尔函数(即四个点绘制图形)
/**
* Calculate a value of a Cubic Bezier function.
* @param t time in range of [0..LV_BEZIER_VAL_MAX]
* @param u0 start values in range of [0..LV_BEZIER_VAL_MAX]
* @param u1 control value 1 values in range of [0..LV_BEZIER_VAL_MAX]
* @param u2 control value 2 in range of [0..LV_BEZIER_VAL_MAX]
* @param u3 end values in range of [0..LV_BEZIER_VAL_MAX]
* @return the value calculated from the given parameters in range of [0..LV_BEZIER_VAL_MAX]
*/
#define LV_BEZIER_VAL_MAX 1024 /**< Max time in Bezier functions (not [0..1] to use integers)*/
#define LV_BEZIER_VAL_SHIFT 10 /**< log2(LV_BEZIER_VAL_MAX): used to normalize up scaled values*/
uint32_t lv_bezier3(uint32_t t, uint32_t u0, uint32_t u1, uint32_t u2, uint32_t u3)
{
uint32_t t_rem = LV_BEZIER_VAL_MAX - t;
uint32_t t_rem2 = (t_rem * t_rem) >> 10;
uint32_t t_rem3 = (t_rem2 * t_rem) >> 10;
uint32_t t2 = (t * t) >> 10;
uint32_t t3 = (t2 * t) >> 10;
uint32_t v1 = (t_rem3 * u0) >> 10;
uint32_t v2 = (3 * t_rem2 * t * u1) >> 20;
uint32_t v3 = (3 * t_rem * t2 * u2) >> 20;
uint32_t v4 = (t3 * u3) >> 10;
return v1 + v2 + v3 + v4;
}
注:LV_BEZIER_VAL_MAX 参数值为什么定义是:2^n,这里是为了在嵌入式中可以通过移位,优化算法(毕竟做除法运算量是相当大的),另外很多时候分两次移位,因为uint32_t 做乘法的时候精度丢失。
t:(0~LV_BEZIER_VAL_MAX) 可以理解为横坐标
u0,u1,u2,u3 四个点纵坐标
v1 + v2 + v3 + v4: 算出当前绘制点的纵坐标
三阶绘制效果
贝塞尔函数(二阶函数):
自己手搓优化的二阶贝塞尔函数
转成C语言优化过后如下:
#define MAX_TIME (256)
uint32_t lv_bezier2(uint32_t t, uint32_t u0, uint32_t u1, uint32_t u2)
{
uint32_t t_rem = MAX_TIME - t;
uint32_t t_rem2 = (t_rem * t_rem) >> 8;
uint32_t t2 = (t * t) >> 8;
uint32_t v0 = (t_rem2 * u0) >> 8;
uint32_t v1 = (2 * u1 * t * t_rem) >> 16;
uint32_t v2 = (t2 * u2) >> 8;
return (v0 + v1 + v2);
}
二阶绘制效果
贝塞尔函数(四阶函数):
根据多项式公式,四阶数学函数和C语言代码如下:
P = (1-t)^4P0 + 4(1-t)^3tP1 + 6(1-t)2*t2P2 + 4(1-t)t^3P3 + t^4*P4
uint32_t lv_bezier4(uint32_t t, uint32_t u0, uint32_t u1, uint32_t u2, uint32_t u3, uint32_t u4)
{
//注意数据溢出问题,提前做好移位偏移
uint32_t t_rem = MAX_TIME - t; //差值
//n次方计算
uint32_t t_rem2 = (t_rem * t_rem) >> 8;
uint32_t t_rem3 = (t_rem2 * t_rem) >> 8;
uint32_t t_rem4 = (t_rem3 * t_rem) >> 8;
//n次方计算
uint32_t t2 = (t * t) >> 8;
uint32_t t3 = (t2 * t) >> 8;
uint32_t t4 = (t2 * t2) >> 8;
uint32_t v0 = (t_rem4 * u0) >> 8;
uint32_t v1 = (4 * t_rem3 * t * u1) >> 16;
uint32_t v2 = (6 * t2 * t_rem2 * u2) >> 16;
uint32_t v3 = (4 * t_rem * t3 * u3) >> 16;
uint32_t v4 = (t4 * u4) >> 8;
return (v0 + v1 + v2 + v3 + v4);
}
四阶绘制效果
多阶用移位方式优化导致了部分精度丢失,所以线段毛刺严重(运算能力强的控制单元可以考虑适用浮点运算)
文章来源:https://www.toymoban.com/news/detail-786544.html
绘制代码如下
/**************************************************START OF FILE*****************************************************/
/*------------------------------------------------------------------------------------------------------------------
Includes
*/
#include "lvgl.h"
#include "xGUI_Common.h"
#include "xGUI_ImgLoad.h"
#include "xGUI_Page_Eq.h"
/*------------------------------------------------------------------------------------------------------------------
Macros
*/
#define CHART_POINTS_NUM 256
#define MAX_TIME (256)
#define USE_BEZIER_4 (1) //四阶还是二阶
typedef struct
{
bool is_style_init;
//style list
lv_style_t style_btn_main;
lv_style_t style_src_main;
lv_style_t style_src_main_focused;
lv_style_t style_src_main_enited;
lv_style_t style_src_indicator;
lv_style_t style_combox_main;
lv_obj_t *pWidgetBtnClose;
lv_obj_t *pWidgetBtnSave;
lv_obj_t *pWidgetCombox[3];
lv_obj_t *pWidgetChart[2];
lv_obj_t *pWidgetSubChart;
lv_obj_t *pWidgetBtnChart[3];
lv_chart_series_t *ser1[2];
lv_obj_t *pWidgetArc[6];
uint16_t arcPara[6];
}ui_eq_page_manage_t;
/*------------------------------------------------------------------------------------------------------------------
Variables
*/
extern lv_obj_t *pMainWidget;
ui_eq_page_manage_t ui_eq_page_manage =
{
.arcPara[0] = 127,
.arcPara[1] = 127,
.arcPara[2] = 127,
.arcPara[3] = 127,
.arcPara[4] = 127,
.arcPara[5] = 127,
};
/*------------------------------------------------------------------------------------------------------------------
Functions
*/
static void eq_style_init(void);
static void refer_chart_cubic_bezier(void);
static void btn_event_callback(lv_event_t * e)
{
lv_obj_t *obj = lv_event_get_target(e);
lv_event_code_t event = lv_event_get_code(e);
if (event == LV_EVENT_CLICKED)
{
if(obj == ui_eq_page_manage.pWidgetBtnClose)
{
DisplayPara.MenuID = UI_PAGE_CHAIN;
}
else if(obj == ui_eq_page_manage.pWidgetBtnSave)
{
}
}
}
static void arc_event_callback(lv_event_t * e)
{
lv_obj_t *obj = lv_event_get_target(e);
lv_event_code_t event = lv_event_get_code(e);
uint16_t* puser_data = (uint16_t*)lv_event_get_user_data(e);
char buf[6];
int16_t subData;
if (event == LV_EVENT_VALUE_CHANGED)
{
*puser_data = lv_arc_get_value(obj);
lv_obj_t *label = lv_obj_get_child(obj, NULL);
lv_snprintf(buf, sizeof(buf), "%d", *puser_data);
lv_label_set_text(label ,buf);
}
refer_chart_cubic_bezier();
}
/*
********************************************************************************************************************
@ Brief : 贝塞尔二阶函数
@ Param : None
@ Return : None
@ Author : lyc
@ Date : 2023 - 02 - 17
********************************************************************************************************************
*/
uint32_t lv_bezier2(uint32_t t, uint32_t u0, uint32_t u1, uint32_t u2)
{
uint32_t t_rem = MAX_TIME - t;
uint32_t t_rem2 = (t_rem * t_rem) >> 8;
uint32_t t2 = (t * t) >> 8;
uint32_t v0 = (t_rem2 * u0) >> 8;
uint32_t v1 = (2 * u1 * t * t_rem) >> 16;
uint32_t v2 = (t2 * u2) >> 8;
return (v0 + v1 + v2);
}
uint32_t lv_bezier4(uint32_t t, uint32_t u0, uint32_t u1, uint32_t u2, uint32_t u3, uint32_t u4)
{
//注意数据溢出问题,提前做好移位偏移
uint32_t t_rem = MAX_TIME - t; //差值
//n次方计算
uint32_t t_rem2 = (t_rem * t_rem) >> 8;
uint32_t t_rem3 = (t_rem2 * t_rem) >> 8;
uint32_t t_rem4 = (t_rem3 * t_rem) >> 8;
//n次方计算
uint32_t t2 = (t * t) >> 8;
uint32_t t3 = (t2 * t) >> 8;
uint32_t t4 = (t2 * t2) >> 8;
uint32_t v0 = (t_rem4 * u0) >> 8;
uint32_t v1 = (4 * t_rem3 * t * u1) >> 16;
uint32_t v2 = (6 * t2 * t_rem2 * u2) >> 16;
uint32_t v3 = (4 * t_rem * t3 * u3) >> 16;
uint32_t v4 = (t4 * u4) >> 8;
return (v0 + v1 + v2 + v3 + v4);
}
/*
********************************************************************************************************************
@ Brief : 界面显示初始化
@ Param : None
@ Return : None
@ Author : lyc
@ Date : 2023 - 01 - 29
********************************************************************************************************************
*/
void gui_eq_init(void)
{
int i;
lv_obj_t *label;
char buf[30];
eq_style_init();
ui_eq_page_manage.pWidgetBtnClose = lv_label_create(pMainWidget);
lv_obj_align(ui_eq_page_manage.pWidgetBtnClose, LV_ALIGN_DEFAULT, 740, 10);
lv_obj_set_style_text_font(ui_eq_page_manage.pWidgetBtnClose, &icon_font_32, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_text_color(ui_eq_page_manage.pWidgetBtnClose, lv_color_white(), LV_PART_MAIN | LV_STATE_DEFAULT);
lv_label_set_text(ui_eq_page_manage.pWidgetBtnClose, LV_SYMBOL_CLOSE);
lv_obj_add_flag(ui_eq_page_manage.pWidgetBtnClose, LV_OBJ_FLAG_CLICKABLE);
lv_obj_add_event_cb(ui_eq_page_manage.pWidgetBtnClose, btn_event_callback, LV_EVENT_CLICKED, NULL);
label = lv_label_create(pMainWidget);
lv_obj_align(label, LV_ALIGN_DEFAULT, 50, 5);
lv_obj_set_style_text_color(label, lv_palette_main(LV_PALETTE_PURPLE), LV_PART_MAIN | LV_STATE_DEFAULT); //
lv_obj_set_style_text_font(label, &bold_font_20, LV_PART_MAIN);
lv_label_set_text(label , "AI EQ MASTER");
ui_eq_page_manage.pWidgetCombox[0] = lv_dropdown_create(pMainWidget);
lv_obj_set_size(ui_eq_page_manage.pWidgetCombox[0], 200, 40);
lv_obj_align(ui_eq_page_manage.pWidgetCombox[0], LV_ALIGN_DEFAULT, 50, 35);
lv_obj_add_style(ui_eq_page_manage.pWidgetCombox[0],&ui_eq_page_manage.style_combox_main,LV_PART_MAIN);
lv_dropdown_clear_options(ui_eq_page_manage.pWidgetCombox[0]);
for (i = 0; i < 10; i++)
{
lv_snprintf(buf,sizeof(buf), "Type: Destortion%02d", i);
lv_dropdown_add_option(ui_eq_page_manage.pWidgetCombox[0], buf, i);
}
lv_dropdown_set_symbol(ui_eq_page_manage.pWidgetCombox[0], LV_SYMBOL_DOWN);
ui_eq_page_manage.pWidgetCombox[1] = lv_dropdown_create(pMainWidget);
lv_obj_set_size(ui_eq_page_manage.pWidgetCombox[1], 250, 40);
lv_obj_align(ui_eq_page_manage.pWidgetCombox[1], LV_ALIGN_DEFAULT, 270, 35);
lv_obj_add_style(ui_eq_page_manage.pWidgetCombox[1],&ui_eq_page_manage.style_combox_main,LV_PART_MAIN);
lv_dropdown_clear_options(ui_eq_page_manage.pWidgetCombox[1]);
for (i = 0; i < 10; i++)
{
lv_snprintf(buf,sizeof(buf), "80`s Rock Phythm %02d", i);
lv_dropdown_add_option(ui_eq_page_manage.pWidgetCombox[1], buf, i);
}
lv_dropdown_set_symbol(ui_eq_page_manage.pWidgetCombox[1], LV_SYMBOL_DOWN);
ui_eq_page_manage.pWidgetCombox[2] = lv_dropdown_create(pMainWidget);
lv_obj_set_size(ui_eq_page_manage.pWidgetCombox[2], 100, 40);
lv_obj_align(ui_eq_page_manage.pWidgetCombox[2], LV_ALIGN_DEFAULT, 620, 35);
lv_obj_add_style(ui_eq_page_manage.pWidgetCombox[2],&ui_eq_page_manage.style_combox_main,LV_PART_MAIN);
lv_dropdown_clear_options(ui_eq_page_manage.pWidgetCombox[2]);
for (i = 0; i < 10; i++)
{
lv_snprintf(buf,sizeof(buf), "Slot%02d", i);
lv_dropdown_add_option(ui_eq_page_manage.pWidgetCombox[2], buf, i);
}
lv_dropdown_set_symbol(ui_eq_page_manage.pWidgetCombox[2], LV_SYMBOL_DOWN);
ui_eq_page_manage.pWidgetBtnSave = lv_label_create(pMainWidget);
lv_obj_align(ui_eq_page_manage.pWidgetBtnSave, LV_ALIGN_DEFAULT, 560, 40);
lv_obj_set_style_text_font(ui_eq_page_manage.pWidgetBtnSave, &icon_font_32, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_text_color(ui_eq_page_manage.pWidgetBtnSave, lv_color_white(), LV_PART_MAIN | LV_STATE_DEFAULT);
lv_label_set_text(ui_eq_page_manage.pWidgetBtnSave, LV_SYMBOL_SAVE);
lv_obj_add_flag(ui_eq_page_manage.pWidgetBtnSave, LV_OBJ_FLAG_CLICKABLE);
lv_obj_add_event_cb(ui_eq_page_manage.pWidgetBtnSave, btn_event_callback, LV_EVENT_CLICKED, NULL);
#if USE_BEZIER_4
ui_eq_page_manage.pWidgetChart[0] = lv_chart_create(pMainWidget);
lv_obj_align(ui_eq_page_manage.pWidgetChart[0],LV_ALIGN_DEFAULT,50,90);
lv_obj_set_size(ui_eq_page_manage.pWidgetChart[0], 700, 260);
lv_obj_set_style_line_color(ui_eq_page_manage.pWidgetChart[0], lv_palette_main(LV_PALETTE_GREY), LV_PART_MAIN);
lv_obj_set_style_line_opa(ui_eq_page_manage.pWidgetChart[0], LV_OPA_80, LV_PART_MAIN);
lv_obj_set_style_pad_all(ui_eq_page_manage.pWidgetChart[0], 0, LV_PART_MAIN);
lv_obj_set_style_size(ui_eq_page_manage.pWidgetChart[0], 0, LV_PART_INDICATOR);
lv_obj_set_style_bg_color(ui_eq_page_manage.pWidgetChart[0],lv_color_black(),LV_PART_MAIN);
lv_obj_set_style_border_width(ui_eq_page_manage.pWidgetChart[0], 0, LV_PART_MAIN);
lv_chart_set_type(ui_eq_page_manage.pWidgetChart[0], LV_CHART_TYPE_SCATTER);
lv_chart_set_div_line_count(ui_eq_page_manage.pWidgetChart[0], 11, 7);
ui_eq_page_manage.ser1[0] = lv_chart_add_series(ui_eq_page_manage.pWidgetChart[0], lv_palette_main(LV_PALETTE_AMBER), LV_CHART_AXIS_PRIMARY_Y);
lv_chart_set_range(ui_eq_page_manage.pWidgetChart[0], LV_CHART_AXIS_PRIMARY_Y, 0, CHART_POINTS_NUM);
lv_chart_set_range(ui_eq_page_manage.pWidgetChart[0], LV_CHART_AXIS_PRIMARY_X, 0, CHART_POINTS_NUM);
lv_chart_set_point_count(ui_eq_page_manage.pWidgetChart[0], CHART_POINTS_NUM);
#else
for(i=0;i<2;i++)
{
ui_eq_page_manage.pWidgetChart[i] = lv_chart_create(pMainWidget);
lv_obj_align(ui_eq_page_manage.pWidgetChart[i],LV_ALIGN_DEFAULT,50+350*i,90);
lv_obj_set_size(ui_eq_page_manage.pWidgetChart[i], 350, 260);
lv_obj_set_style_line_color(ui_eq_page_manage.pWidgetChart[i], lv_palette_main(LV_PALETTE_GREY), LV_PART_MAIN);
lv_obj_set_style_line_opa(ui_eq_page_manage.pWidgetChart[i], LV_OPA_80, LV_PART_MAIN);
lv_obj_set_style_pad_all(ui_eq_page_manage.pWidgetChart[i], 0, LV_PART_MAIN);
lv_obj_set_style_size(ui_eq_page_manage.pWidgetChart[i], 0, LV_PART_INDICATOR);
lv_obj_set_style_bg_color(ui_eq_page_manage.pWidgetChart[i],lv_color_black(),LV_PART_MAIN);
lv_obj_set_style_border_width(ui_eq_page_manage.pWidgetChart[i], 0, LV_PART_MAIN);
lv_chart_set_type(ui_eq_page_manage.pWidgetChart[i], LV_CHART_TYPE_SCATTER);
lv_chart_set_div_line_count(ui_eq_page_manage.pWidgetChart[i], 11, 7);
ui_eq_page_manage.ser1[i] = lv_chart_add_series(ui_eq_page_manage.pWidgetChart[i], lv_palette_main(LV_PALETTE_AMBER), LV_CHART_AXIS_PRIMARY_Y);
lv_chart_set_range(ui_eq_page_manage.pWidgetChart[i], LV_CHART_AXIS_PRIMARY_Y, 0, CHART_POINTS_NUM);
lv_chart_set_range(ui_eq_page_manage.pWidgetChart[i], LV_CHART_AXIS_PRIMARY_X, 0, CHART_POINTS_NUM);
lv_chart_set_point_count(ui_eq_page_manage.pWidgetChart[i], CHART_POINTS_NUM);
}
#endif
ui_eq_page_manage.pWidgetSubChart = lv_obj_create(pMainWidget);
lv_obj_set_size(ui_eq_page_manage.pWidgetSubChart, 280, 60);
lv_obj_align(ui_eq_page_manage.pWidgetSubChart,LV_ALIGN_TOP_MID,0,270);
lv_obj_set_style_border_opa(ui_eq_page_manage.pWidgetSubChart,LV_OPA_TRANSP,LV_PART_MAIN);
lv_obj_set_style_bg_color(ui_eq_page_manage.pWidgetSubChart,lv_palette_main(LV_PALETTE_GREY),LV_PART_MAIN);
lv_obj_set_style_bg_opa(ui_eq_page_manage.pWidgetSubChart,LV_OPA_40,LV_PART_MAIN);
lv_obj_set_style_pad_gap(ui_eq_page_manage.pWidgetSubChart,0,LV_PART_MAIN);
lv_obj_clear_flag(ui_eq_page_manage.pWidgetSubChart, LV_OBJ_FLAG_SCROLLABLE);
ui_eq_page_manage.pWidgetBtnChart[0] = lv_btn_create(ui_eq_page_manage.pWidgetSubChart);
lv_obj_set_size(ui_eq_page_manage.pWidgetBtnChart[0], 40, 40);
lv_obj_align(ui_eq_page_manage.pWidgetBtnChart[0], LV_ALIGN_CENTER, -90, 0);
lv_obj_add_style(ui_eq_page_manage.pWidgetBtnChart[0],&ui_eq_page_manage.style_btn_main,LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_add_event_cb(ui_eq_page_manage.pWidgetBtnChart[0], btn_event_callback, LV_EVENT_CLICKED, NULL);
label = lv_label_create(ui_eq_page_manage.pWidgetBtnChart[0]);
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
lv_obj_set_style_text_font(label, &icon_font_32, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_label_set_text(label, "\uF111");
ui_eq_page_manage.pWidgetBtnChart[1] = lv_btn_create(ui_eq_page_manage.pWidgetSubChart);
lv_obj_set_size(ui_eq_page_manage.pWidgetBtnChart[1], 40, 40);
lv_obj_align(ui_eq_page_manage.pWidgetBtnChart[1], LV_ALIGN_CENTER, 0, 0);
lv_obj_add_style(ui_eq_page_manage.pWidgetBtnChart[1],&ui_eq_page_manage.style_btn_main,LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_add_event_cb(ui_eq_page_manage.pWidgetBtnChart[1], btn_event_callback, LV_EVENT_CLICKED, NULL);
label = lv_label_create(ui_eq_page_manage.pWidgetBtnChart[1]);
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
lv_obj_set_style_text_font(label, &icon_font_32, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_label_set_text(label, "\uF011");
ui_eq_page_manage.pWidgetBtnChart[2] = lv_btn_create(ui_eq_page_manage.pWidgetSubChart);
lv_obj_set_size(ui_eq_page_manage.pWidgetBtnChart[2], 40, 40);
lv_obj_align(ui_eq_page_manage.pWidgetBtnChart[2], LV_ALIGN_CENTER, 90, 0);
lv_obj_add_style(ui_eq_page_manage.pWidgetBtnChart[2],&ui_eq_page_manage.style_btn_main,LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_add_event_cb(ui_eq_page_manage.pWidgetBtnChart[2], btn_event_callback, LV_EVENT_CLICKED, NULL);
label = lv_label_create(ui_eq_page_manage.pWidgetBtnChart[2]);
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
lv_obj_set_style_text_font(label, &icon_font_32, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_label_set_text(label, "\uF014");
for(i=0;i<6;i++)
{
ui_eq_page_manage.pWidgetArc[i] = lv_arc_create(pMainWidget);
lv_obj_set_size(ui_eq_page_manage.pWidgetArc[i], 80, 80);
lv_obj_align(ui_eq_page_manage.pWidgetArc[i],LV_ALIGN_TOP_MID, -300 + 120*i, 370);
lv_arc_set_bg_angles(ui_eq_page_manage.pWidgetArc[i],135,45);
lv_arc_set_range(ui_eq_page_manage.pWidgetArc[i], 0, MAX_TIME);
lv_arc_set_value(ui_eq_page_manage.pWidgetArc[i], ui_eq_page_manage.arcPara[i]);
lv_obj_add_style(ui_eq_page_manage.pWidgetArc[i],&ui_eq_page_manage.style_src_main,LV_PART_MAIN);
lv_obj_add_style(ui_eq_page_manage.pWidgetArc[i],&ui_eq_page_manage.style_src_indicator,LV_PART_INDICATOR);
lv_obj_add_style(ui_eq_page_manage.pWidgetArc[i],&ui_eq_page_manage.style_src_main_focused,LV_PART_MAIN | LV_STATE_FOCUSED);
lv_obj_add_style(ui_eq_page_manage.pWidgetArc[i],&ui_eq_page_manage.style_src_main_enited,LV_PART_MAIN | LV_STATE_EDITED);
lv_obj_remove_style(ui_eq_page_manage.pWidgetArc[i], NULL, LV_PART_KNOB);
lv_group_add_obj(pGroupEncoder,ui_eq_page_manage.pWidgetArc[i]);
label = lv_label_create(ui_eq_page_manage.pWidgetArc[i]);
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
lv_obj_set_style_text_color(label, lv_color_white(), LV_PART_MAIN | LV_STATE_DEFAULT);
lv_snprintf(buf, sizeof(buf), "%d", ui_eq_page_manage.arcPara[i]);
lv_label_set_text(label ,buf);
lv_obj_add_event_cb(ui_eq_page_manage.pWidgetArc[i],arc_event_callback,LV_EVENT_VALUE_CHANGED,&ui_eq_page_manage.arcPara[i]);
}
lv_group_focus_obj(ui_eq_page_manage.pWidgetArc[0]);
lv_obj_set_style_arc_color(ui_eq_page_manage.pWidgetArc[0],lv_palette_lighten(LV_PALETTE_GREEN,1),LV_PART_INDICATOR | LV_STATE_DEFAULT);
lv_obj_set_style_arc_color(ui_eq_page_manage.pWidgetArc[1],lv_palette_lighten(LV_PALETTE_PINK,1),LV_PART_INDICATOR | LV_STATE_DEFAULT);
lv_obj_set_style_arc_color(ui_eq_page_manage.pWidgetArc[2],lv_palette_lighten(LV_PALETTE_RED,1),LV_PART_INDICATOR | LV_STATE_DEFAULT);
lv_obj_set_style_arc_color(ui_eq_page_manage.pWidgetArc[3],lv_palette_lighten(LV_PALETTE_BLUE,1),LV_PART_INDICATOR | LV_STATE_DEFAULT);
lv_obj_set_style_arc_color(ui_eq_page_manage.pWidgetArc[4],lv_palette_lighten(LV_PALETTE_BLUE,3),LV_PART_INDICATOR | LV_STATE_DEFAULT);
lv_obj_set_style_arc_color(ui_eq_page_manage.pWidgetArc[5],lv_palette_lighten(LV_PALETTE_PURPLE,1),LV_PART_INDICATOR | LV_STATE_DEFAULT);
refer_chart_cubic_bezier();
}
/*
********************************************************************************************************************
@ Brief :
@ Param : None
@ Return : None
@ Date : 2023 - 02 - 02
********************************************************************************************************************
*/
void xGUI_Page_Eq(const DisplayPara_TypeDef *pDisPlay)
{
if(pDisPlay->MenuID != TempDisplayPara.MenuID )
{
if(pMainWidget != NULL)lv_obj_clean(pMainWidget);
gui_eq_init();
TempDisplayPara.MenuID = pDisPlay->MenuID;
}
}
/*
********************************************************************************************************************
@ Brief : 风格类型初始化:当前界面所有控件的风格整理
@ Param : None
@ Return : None
@ Author : lyc
@ Date : 2023 - 01 - 29
********************************************************************************************************************
*/
static void eq_style_init(void)
{
if(ui_eq_page_manage.is_style_init == false)
{
lv_style_init(&ui_eq_page_manage.style_btn_main);
lv_style_set_radius(&ui_eq_page_manage.style_btn_main,4);
lv_style_set_bg_color(&ui_eq_page_manage.style_btn_main,lv_palette_main(LV_PALETTE_GREY));
lv_style_set_bg_opa(&ui_eq_page_manage.style_btn_main,LV_OPA_30);
lv_style_set_shadow_opa(&ui_eq_page_manage.style_btn_main,LV_OPA_TRANSP);
lv_style_init(&ui_eq_page_manage.style_src_main);
lv_style_set_arc_color(&ui_eq_page_manage.style_src_main,lv_palette_darken(LV_PALETTE_GREY,3));
lv_style_set_arc_width(&ui_eq_page_manage.style_src_main,8);
lv_style_init(&ui_eq_page_manage.style_src_indicator);
lv_style_set_arc_color(&ui_eq_page_manage.style_src_indicator,lv_palette_lighten(LV_PALETTE_ORANGE,1));
lv_style_set_arc_width(&ui_eq_page_manage.style_src_indicator,8);
lv_style_init(&ui_eq_page_manage.style_src_main_focused);
lv_style_set_bg_opa(&ui_eq_page_manage.style_src_main_focused,LV_OPA_TRANSP);
lv_style_set_border_opa(&ui_eq_page_manage.style_src_main_focused,LV_OPA_COVER);
lv_style_set_shadow_width(&ui_eq_page_manage.style_src_main_focused,10);
lv_style_set_shadow_color(&ui_eq_page_manage.style_src_main_focused,lv_palette_lighten(LV_PALETTE_BLUE,2));
lv_style_set_arc_color(&ui_eq_page_manage.style_src_main_focused,lv_palette_lighten(LV_PALETTE_GREY,1));
lv_style_init(&ui_eq_page_manage.style_src_main_enited);
lv_style_set_bg_opa(&ui_eq_page_manage.style_src_main_enited,LV_OPA_TRANSP);
lv_style_set_border_opa(&ui_eq_page_manage.style_src_main_enited,LV_OPA_COVER);
lv_style_set_shadow_width(&ui_eq_page_manage.style_src_main_enited,10);
lv_style_set_shadow_color(&ui_eq_page_manage.style_src_main_enited,lv_palette_lighten(LV_PALETTE_PINK,2));
lv_style_set_arc_color(&ui_eq_page_manage.style_src_main_enited,lv_palette_lighten(LV_PALETTE_GREY,3));
lv_style_init(&ui_eq_page_manage.style_combox_main);
lv_style_set_radius(&ui_eq_page_manage.style_combox_main,9);
lv_style_set_border_color(&ui_eq_page_manage.style_combox_main,lv_palette_main(LV_PALETTE_PURPLE));
lv_style_set_border_width(&ui_eq_page_manage.style_combox_main,2);
lv_style_set_bg_color(&ui_eq_page_manage.style_combox_main,lv_color_black());
lv_style_set_text_color(&ui_eq_page_manage.style_combox_main, lv_color_white());
ui_eq_page_manage.is_style_init = true;
}
}
static void refer_chart_cubic_bezier(void)
{
int i;
int32_t step;
#if USE_BEZIER_4
for(i = 0; i <= CHART_POINTS_NUM; i ++)
{
step = lv_bezier4(i, ui_eq_page_manage.arcPara[0], ui_eq_page_manage.arcPara[1], ui_eq_page_manage.arcPara[2],ui_eq_page_manage.arcPara[3], ui_eq_page_manage.arcPara[4]);
lv_chart_set_value_by_id2(ui_eq_page_manage.pWidgetChart[0], ui_eq_page_manage.ser1[0], i, i, step);
}
lv_chart_refresh(ui_eq_page_manage.pWidgetChart[0]);
#else
for(i = 0; i <= CHART_POINTS_NUM; i ++)
{
step = lv_bezier2(i, ui_eq_page_manage.arcPara[0], ui_eq_page_manage.arcPara[1], ui_eq_page_manage.arcPara[2]);
lv_chart_set_value_by_id2(ui_eq_page_manage.pWidgetChart[0], ui_eq_page_manage.ser1[0], i, i, step);
step = lv_bezier2(i, ui_eq_page_manage.arcPara[2], ui_eq_page_manage.arcPara[3], ui_eq_page_manage.arcPara[4]);
lv_chart_set_value_by_id2(ui_eq_page_manage.pWidgetChart[1], ui_eq_page_manage.ser1[1], i, i, step);
}
lv_chart_refresh(ui_eq_page_manage.pWidgetChart[0]);
lv_chart_refresh(ui_eq_page_manage.pWidgetChart[1]);
#endif
}
/****************************************************END OF FILE*****************************************************/
理解贝塞尔曲线后,可以根据需要搭建多阶算法(阶数越多,曲线拟合更贴切,但算法量越大,对算力较弱的芯片不推荐)文章来源地址https://www.toymoban.com/news/detail-786544.html
到了这里,关于【LVGL笔记】-- 贝塞尔曲线绘制的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!