Marker points on Arc

Description

I want to draw ‘Marker’ points on top of the Arc control. My initial idea was to simply draw a 1 degree arc at the points where I want the markers. Unfortunately this doesn’t give very consistent markers as they vary in width due to the 360 resolution of the arc.
In this image at the bottom of this post both the green and white markers are just 1 degree, but as you can see they are very different in appearance!

Any ideas how to achieve better markers?
Maybe a solution is to draw a line along a given angle much like the ‘gauge’ widget. Is this possible?

What MCU/Processor/Board and compiler are you using?

Simulation (Visual Studio)

What do you want to achieve?

Better ‘Marker’ points on top of the arc.

What have you tried so far?

Using 1 degree arcs as mentioned above.

Code to reproduce

This is the code that creates the 1 degree makers

	/****************************************************************/
	/* Green Marker*/
	static lv_style_t style_eco;
	lv_style_copy(&style_eco, &lv_style_plain);
	style_eco.line.color = lv_color_hex(COLOUR_MARKER_ECO);
	style_eco.line.width = MARKER_THICKNESS;

	lv_obj_t* arc4 = lv_arc_create(parent, NULL);
	volatile uint16_t temp1 = eco_angle - MARKER_SIZE;
	lv_arc_set_angles(arc4, eco_angle - MARKER_SIZE, eco_angle);
	lv_arc_set_style(arc4, LV_ARC_STYLE_MAIN, &style_eco);
	lv_obj_set_size(arc4, size, size);
	lv_obj_align(arc4, NULL, LV_ALIGN_CENTER, 0, 0);


	/****************************************************************/
	/* WhiteMarker*/
	static lv_style_t style_sp;
	lv_style_copy(&style_sp, &lv_style_plain);
	style_sp.line.color = lv_color_hex(COLOUR_MARKER_PV);
	style_sp.line.width = MARKER_THICKNESS;

	lv_obj_t* arc5 = lv_arc_create(parent, NULL);
	volatile uint16_t temp2 = sp_angle - MARKER_SIZE;
	lv_arc_set_angles(arc5, sp_angle - MARKER_SIZE, sp_angle);
	lv_arc_set_style(arc5, LV_ARC_STYLE_MAIN, &style_sp);
	lv_obj_set_size(arc5, size, size);
	lv_obj_align(arc5, NULL, LV_ALIGN_CENTER, 0, 0);

Screenshot and/or video

Logically, the easiest method would be to find a way of only drawing some lines on an lmeter, and then positioning it on top of an arc. However, filtering which lines are drawn is not supported on an lmeter right now (but it should be a minor change).

As a hack, what if you set the right line to be a degree less or more than the value you want? It might still look reasonable visually.

I dont think just moving the line 1 degree will necessarily make the line thinner. Also this marker is dynamic so I would appear anywhere in the arc.

I’ll take a look at the Imeter and see if I can work it out. thanks.

An other solution would be to use a canvas with a marker and rotate it. You can use LV_IMG_CF_INDEXED_2BIT to consume a few memory but have anti-aliasing. With this, you can have any custom shaped marker.
The easiest way is to have a canvas with the size of the arc, place the marker to the edge, and rotate the canvas around its center.

For a 100x100 arc it will consume 100x100/4 = 2,5 KB RAM for each canvas. It depends on your application if it’s acceptable or not.

Another solution with less memory usage could be to have a small image with the marker only, rotate it and place it where you need. It’ll require some trigonometrical calculation to get the position from the angles.

A third solution is to draw a line (lv_line) where needed. It’d also require some trigonometrical calculations.

1 Like

Thanks for the suggestions. I think that the last option of drawing a line using some trig will probably be my best option. I’ll try and get on to this today and post the results.