1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-28 07:03:00 +08:00

fix(draw): be sure angle values are in the correct range

This commit is contained in:
Gabor Kiss-Vamosi 2022-04-27 14:25:12 +02:00
parent a76bb70a79
commit e624b90db3
4 changed files with 28 additions and 10 deletions

View File

@ -63,7 +63,14 @@ lv_obj_clear_flag(arc, LV_OBJ_FLAG_CLICKABLE);
If the `LV_OBJ_FLAG_ADV_HITTEST` flag is enabled the arc can be clicked through in the middle. Clicks are recognized only on the ring of the background arc. `lv_obj_set_ext_click_size()` makes the sensitive area larger inside and outside with the given number of pixels.
### Place another object to the knob
Another object can be positioned according to the current position of the arc in order to follow the arc's current value (angle).
To do this use `lv_arc_align_obj_to_angle(arc, obj_to_align, radius_offset)`.
Similarly `lv_arc_rotate_obj_to_angle(arc, obj_to_rotate, radius_offset)` can be used to rotate the object to the current value of the arc.
It's a typical use case to call these functions in the `VALUE_CHANGED` event of the arc.
## Events
- `LV_EVENT_VALUE_CHANGED` sent when the arc is pressed/dragged to set a new value.

View File

@ -924,6 +924,9 @@ void refr_obj(lv_draw_ctx_t * draw_ctx, lv_obj_t * obj)
lv_draw_img_dsc_init(&draw_dsc);
draw_dsc.opa = opa;
draw_dsc.angle = lv_obj_get_style_transform_angle(obj, 0);
if(draw_dsc.angle > 3600) draw_dsc.angle -= 3600;
if(draw_dsc.angle < 0) draw_dsc.angle += 3600;
draw_dsc.zoom = lv_obj_get_style_transform_zoom(obj, 0);
draw_dsc.blend_mode = lv_obj_get_style_blend_mode(obj, 0);
draw_dsc.antialias = disp_refr->driver->antialiasing;

View File

@ -27,6 +27,8 @@ typedef struct {
int32_t cosma;
int32_t zoom;
int32_t angle;
int32_t pivot_x_256;
int32_t pivot_y_256;
lv_point_t pivot;
} point_transform_dsc_t;
@ -93,6 +95,8 @@ void lv_draw_sw_transform(lv_draw_ctx_t * draw_ctx, const lv_area_t * dest_area,
tr_dsc.cosma = (c1 * (10 - angle_rem) + c2 * angle_rem) / 10;
tr_dsc.sinma = tr_dsc.sinma >> (LV_TRIGO_SHIFT - 10);
tr_dsc.cosma = tr_dsc.cosma >> (LV_TRIGO_SHIFT - 10);
tr_dsc.pivot_x_256 = tr_dsc.pivot.x * 256;
tr_dsc.pivot_y_256 = tr_dsc.pivot.y * 256;
lv_coord_t dest_w = lv_area_get_width(dest_area);
lv_coord_t dest_h = lv_area_get_height(dest_area);
@ -337,8 +341,8 @@ static void transform_point_upscaled(point_transform_dsc_t * t, int32_t xin, int
int32_t * yout)
{
if(t->angle == 0 && t->zoom == LV_IMG_ZOOM_NONE) {
*xout = xin << 8;
*yout = yin << 8;
*xout = xin * 256;
*yout = yin * 256;
return;
}
@ -346,16 +350,16 @@ static void transform_point_upscaled(point_transform_dsc_t * t, int32_t xin, int
yin -= t->pivot.y;
if(t->angle == 0) {
*xout = ((int32_t)(xin * t->zoom)) + (t->pivot.x << 8);
*yout = ((int32_t)(yin * t->zoom)) + (t->pivot.y << 8);
*xout = ((int32_t)(xin * t->zoom)) + (t->pivot_x_256);
*yout = ((int32_t)(yin * t->zoom)) + (t->pivot_y_256);
}
else if(t->zoom == LV_IMG_ZOOM_NONE) {
*xout = ((t->cosma * xin - t->sinma * yin) >> 2) + (t->pivot.x << 8);
*yout = ((t->sinma * xin + t->cosma * yin) >> 2) + (t->pivot.y << 8);
*xout = ((t->cosma * xin - t->sinma * yin) >> 2) + (t->pivot_x_256);
*yout = ((t->sinma * xin + t->cosma * yin) >> 2) + (t->pivot_y_256);
}
else {
*xout = (((t->cosma * xin - t->sinma * yin) * t->zoom) >> 10) + (t->pivot.x << 8);
*yout = (((t->sinma * xin + t->cosma * yin) * t->zoom) >> 10) + (t->pivot.y << 8);
*xout = (((t->cosma * xin - t->sinma * yin) * t->zoom) >> 10) + (t->pivot_x_256);
*yout = (((t->sinma * xin + t->cosma * yin) * t->zoom) >> 10) + (t->pivot_y_256);
}
}

View File

@ -476,9 +476,13 @@ void lv_point_transform(lv_point_t * p, int32_t angle, int32_t zoom, const lv_po
static int32_t sinma;
static int32_t cosma;
if(angle_prev != angle) {
int32_t angle_low = angle / 10;
int32_t angle_limited = angle;
if(angle_limited > 3600) angle_limited -= 3600;
if(angle_limited < 0) angle_limited += 3600;
int32_t angle_low = angle_limited / 10;
int32_t angle_high = angle_low + 1;
int32_t angle_rem = angle - (angle_low * 10);
int32_t angle_rem = angle_limited - (angle_low * 10);
int32_t s1 = lv_trigo_sin(angle_low);
int32_t s2 = lv_trigo_sin(angle_high);