什么是贝塞尔曲线

贝塞尔曲线(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*P4uint32_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);
}

四阶绘制效果

多阶用移位方式优化导致了部分精度丢失,所以线段毛刺严重(运算能力强的控制单元可以考虑适用浮点运算)

绘制代码如下

/**************************************************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 listlv_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_4ui_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);
#elsefor(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_4for(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]);
#elsefor(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*****************************************************/

理解贝塞尔曲线后,可以根据需要搭建多阶算法(阶数越多,曲线拟合更贴切,但算法量越大,对算力较弱的芯片不推荐)

【LVGL笔记】-- 贝塞尔曲线绘制相关推荐

  1. android运动轨迹怎么画,Android 利用三阶贝塞尔曲线绘制运动轨迹的示例

    本篇文章主要介绍了Android 利用三阶贝塞尔曲线绘制运动轨迹的示例,分享给大家,具体如下: 实现点赞效果,自定义起始点以及运动轨迹 效果图: xml布局: xmlns:tools="ht ...

  2. android 贝塞尔曲线_OpenGL 实践之贝塞尔曲线绘制

    说到贝塞尔曲线,大家肯定都不陌生,网上有很多关于介绍和理解贝塞尔曲线的优秀文章和动态图. 以下两个是比较经典的动图了. 二阶贝塞尔曲线: 三阶贝塞尔曲线: 由于在工作中经常要和贝塞尔曲线打交道,所以简 ...

  3. 自定义view实战(10):贝塞尔曲线绘制小红点

    前言 上一篇文章用扇形图练习了一下安卓的多点触控,实现了单指旋转.二指放大.三指移动,四指以上同时按下进行复位的功能.今天这篇文章用很多应用常见的小红点,来练习一下贝塞尔曲线的使用. 需求 这里想法来 ...

  4. 红橙Darren视频笔记 贝塞尔曲线实现消息拖拽粘性效果 画笔练习

    效果图 要实现这样的效果 我们要先知道那段弧线是如何绘制的,实际上那段弧线就是贝塞尔曲线 一. 什么是贝塞尔曲线 https://www.jianshu.com/p/8f82db9556d2 上面有个 ...

  5. android 贝塞尔曲线 人脸,贝塞尔曲线绘制人脸框(框内全透明,框外半透明)

    参考CropImage 制作截取头像框https://github.com/cokeduo/CropImage https://www.jianshu.com/p/c883fbf52681 //贝塞尔 ...

  6. canvas学习笔记-贝塞尔曲线

    3.4 贝塞尔曲线 canvas提供了两个绘制贝塞尔曲线api: ctx.quadraticCurveTo(cpx, cpy, x, y); 二次贝塞尔曲线,(cpx, cpy)控制点 (x, y)终 ...

  7. HTML5 JS Canvas利用贝塞尔曲线绘制圆角矩形

    啥也不说,先上示例代码: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...

  8. 贝塞尔曲线绘制原理 unity 3d实现绘制贝塞尔曲线

    贝塞尔曲线是一种绘制曲线的方法,它的原理很简单: 以二阶贝塞尔曲线为例 如图,在p0,p1之间移动着一个点,我们先称之为a0,同样在p1,p2之间移动着一个点,我们称之为a1.他们需要满足的条件是这样 ...

  9. canvas贝塞尔曲线爱心_canvas学习笔记-贝塞尔曲线

    3.4 贝塞尔曲线 canvas提供了两个绘制贝塞尔曲线api: ctx.quadraticCurveTo(cpx, cpy, x, y); 二次贝塞尔曲线,(cpx, cpy)控制点 (x, y)终 ...

最新文章

  1. Reflection带来的潜在威胁
  2. Specify compute hosts with SSDs
  3. Linux文件系统简介及常用命令
  4. 【深度学习】图像去模糊算法代码实践!
  5. Linux + RIL.pdf
  6. VGG网络结构(二)
  7. 腾讯公布5G开放平台全景图,定义12大场景,引入45个应用
  8. 我是这么自学Java的
  9. 软考初级程序员---题目(五)
  10. Winform 视频流叠加透明控件. 使用DSkin皮肤框架实现
  11. java计算机毕业设计小型企业财务报销管理源码+lw文档+系统+数据库
  12. linux下dft计算标准函数,FFT/DFT计算方法
  13. 不同Costa环鉴相器鉴别特性
  14. 各系统查询IP地址和MAC地址的脚本或命令
  15. coreldraw2021全名和序列号 cdr2021安装下载图文教程
  16. [小O地图-XOMAP] - 功能简介
  17. iOS13苹果登录的后台验证token(JAVA)
  18. 发送邮箱验证码进行注册验证
  19. 大数据入门-什么是Kudu
  20. Transform.Forward和Vector3.Forward的正确使用方法

热门文章

  1. 详解shell脚本中的变量
  2. R语言数据标签、变量赋值、修改赋值
  3. cubemx stm32 基于uln2003模块的步进电机驱动代码
  4. 迎新年[风火之旅]新区新服倾情开启!
  5. 中文版电子书全部免费
  6. Ultimate, Community, Educational 终极版 社区版 教育版 区别 不同
  7. vue项目打包部署到服务器
  8. 开核有望?AMD Ryzen 5处理器确认8核阉割
  9. 联盟化的LPL是否能带来精彩的英雄联盟比赛?
  10. 小家电品牌通过网红营销成功出海,背后的营销“套路”是什么