refactor(arc_label): improve angle calculations and type safety

- Use lv_value_precise_t for angle calculations to increase precision
- Add explicit type casts to prevent implicit conversion warnings
- Refactor some calculations for better readability and maintainability

Signed-off-by: Benign X <1341398182@qq.com>
This commit is contained in:
Benign X
2025-05-14 16:13:33 +08:00
committed by Felipe Neves
parent 5e8add3957
commit 6cbf36afaa
+44 -19
View File
@@ -20,10 +20,13 @@
#if LV_USE_FLOAT
#include <math.h>
#endif
#ifndef M_PI
#define M_PI 3.14159265358979323846
#include <float.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846264338327950288
#endif
#else
/* Use fixed point math for integer only platforms $ M_PI << 8 $ */
#define M_PI 804
#endif
/*********************
@@ -50,6 +53,8 @@ static lv_value_precise_t calc_arc_text_total_angle(const char * text, const lv_
static const char * recolor_cmd_get_next(const char * text_in, uint32_t len_in,
const char ** text_out, uint32_t * len_out,
lv_color_t * color_out);
static lv_value_precise_t deg_to_rad(lv_value_precise_t deg, int32_t radius);
static lv_value_precise_t rad_to_deg(lv_value_precise_t rad, int32_t radius);
/**********************
* STATIC VARIABLES
@@ -413,7 +418,7 @@ static void arc_label_draw_main(lv_event_t * e)
arc_r += arc_label->dir == LV_ARC_LABEL_DIR_CLOCKWISE ? -arc_r_delta : arc_r_delta;
const int32_t offset = arc_label->offset;
const int32_t angle_offset = offset / M_PI * 180 / arc_r;
const lv_value_precise_t angle_offset = rad_to_deg(offset, arc_r);
switch(arc_label->text_align_h) {
case LV_ARC_LABEL_TEXT_ALIGN_LEADING:
@@ -433,8 +438,8 @@ static void arc_label_draw_main(lv_event_t * e)
uint32_t processed_word_count = 0;
lv_value_precise_t prev_letter_w = 0;
lv_value_precise_t total_arc_length = arc_label->angle_size * M_PI / 180 * arc_r;
lv_value_precise_t curr_total_arc_length = angle_start * M_PI / 180 * arc_r;
lv_value_precise_t total_arc_length = deg_to_rad(arc_label->angle_size, arc_r);
lv_value_precise_t curr_total_arc_length = deg_to_rad(angle_start, arc_r);
while(text) {
uint32_t word_i = 0;
@@ -457,20 +462,22 @@ static void arc_label_draw_main(lv_event_t * e)
}
}
const lv_value_precise_t curr_angle = arc_label->angle_start + (arc_label->dir == LV_ARC_LABEL_DIR_CLOCKWISE ?
curr_total_arc_length : total_arc_length - curr_total_arc_length) * 180 / M_PI / arc_r;
const lv_value_precise_t curr_angle = arc_label->angle_start
+ rad_to_deg(arc_label->dir == LV_ARC_LABEL_DIR_CLOCKWISE
? curr_total_arc_length
: total_arc_length - curr_total_arc_length, arc_r);
#if LV_USE_FLOAT
const lv_value_precise_t x = cos(curr_angle * M_PI / 180) * arc_r;
const lv_value_precise_t y = sin(curr_angle * M_PI / 180) * arc_r;
const lv_value_precise_t x = cosf(deg_to_rad(curr_angle, 1)) * arc_r;
const lv_value_precise_t y = sinf(deg_to_rad(curr_angle, 1)) * arc_r;
#else
const lv_value_precise_t x = lv_trigo_cos(curr_angle) * arc_r / 32767;
const lv_value_precise_t y = lv_trigo_sin(curr_angle) * arc_r / 32767;
const lv_value_precise_t x = (lv_value_precise_t)(lv_trigo_cos(curr_angle) * arc_r / 32767);
const lv_value_precise_t y = (lv_value_precise_t)(lv_trigo_sin(curr_angle) * arc_r / 32767);
#endif
lv_point_t point = {
x + lv_area_get_width(&coords) / 2 + coords.x1 + arc_label->center_offset.x,
y + lv_area_get_height(&coords) / 2 + coords.y1 + arc_label->center_offset.y,
(int32_t)(x + (lv_value_precise_t)(lv_area_get_width(&coords) / 2 + coords.x1 + arc_label->center_offset.x)),
(int32_t)(y + (lv_value_precise_t)(lv_area_get_height(&coords) / 2 + coords.y1 + arc_label->center_offset.y)),
};
lv_draw_letter_dsc_t dsc;
@@ -478,8 +485,8 @@ static void arc_label_draw_main(lv_event_t * e)
dsc.font = font;
dsc.color = arc_label->recolor ? recolor_color : color;
dsc.opa = opa;
if(arc_label->dir == LV_ARC_LABEL_DIR_CLOCKWISE) dsc.rotation = (curr_angle + 90) * 10;
else dsc.rotation = (curr_angle - 90) * 10;
if(arc_label->dir == LV_ARC_LABEL_DIR_CLOCKWISE) dsc.rotation = (int32_t)((curr_angle + 90) * 10);
else dsc.rotation = (int32_t)((curr_angle - 90) * 10);
dsc.unicode = letter;
if(dsc.unicode == 0) {
@@ -518,7 +525,7 @@ static lv_value_precise_t calc_arc_text_total_angle(const char * text, const lv_
const char * text_start = text;
uint32_t processed_letter_count = 0;
lv_value_precise_t prev_letter_w = 0;
const lv_value_precise_t angle_size_in_arc_length = angle_size * M_PI / 180 * radius;
const lv_value_precise_t angle_size_in_arc_length = deg_to_rad(angle_size, radius);
lv_value_precise_t total_arc_length = 0;
while(text) {
@@ -554,7 +561,7 @@ static lv_value_precise_t calc_arc_text_total_angle(const char * text, const lv_
}
}
return total_arc_length * 180 / M_PI / radius;
return rad_to_deg(total_arc_length, radius);
}
static const char * recolor_cmd_get_next(const char * text_in, uint32_t len_in,
@@ -609,4 +616,22 @@ static const char * recolor_cmd_get_next(const char * text_in, uint32_t len_in,
return text < text_end && *text ? text : NULL;
}
static lv_value_precise_t deg_to_rad(lv_value_precise_t deg, int32_t radius)
{
#if LV_USE_FLOAT
return (lv_value_precise_t)(deg * radius * M_PI / 180);
#else
return (lv_value_precise_t)((deg * radius * M_PI / 180) >> 8);
#endif
}
static lv_value_precise_t rad_to_deg(lv_value_precise_t rad, int32_t radius)
{
#if LV_USE_FLOAT
return (lv_value_precise_t)(rad * 180 / M_PI / radius);
#else
return (lv_value_precise_t)(((rad * 180) << 8) / M_PI / radius);
#endif
}
#endif