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:
parent
a76bb70a79
commit
e624b90db3
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user