fix: fan sensor angle handling (#14)

Angles > 360° need to be normalized.

Fixes #12
This commit is contained in:
Markus Zehnder
2025-08-30 17:23:55 +02:00
committed by GitHub
parent 016942631f
commit 21bf19ce31
2 changed files with 19 additions and 6 deletions
+1
View File
@@ -11,6 +11,7 @@ _Changes in the next release_
### Fixed
- Misplaced text sensors in custom panels (#11).
- Wrong start position for circular progress (fan) sensor using a counter-clockwise direction (#12).
### Added
- Simple sensor panel with a file-based data source (#6).
+18 -6
View File
@@ -251,7 +251,6 @@ impl PanelRenderer {
}
/// Mode 2 - Circular/Arc progress indicator
/// TODO needs testing
fn render_fan(
&mut self,
sensor: &Sensor,
@@ -306,7 +305,6 @@ impl PanelRenderer {
(start, end)
} else {
// Counter-clockwise
// FIXME SensorDirection::RightToLeft does not yet work. Might also be related to certain minAngle / maxAngle values
let start = 360.0 - min_angle - (max_angle - min_angle) * progress - 90.0;
let end = 360.0 - min_angle - 90.0;
(start, end)
@@ -496,8 +494,22 @@ impl PanelRenderer {
Ok(())
}
/// Draws a pieslice sector of `source` into `layer`, centered at (center_x, center_y),
/// from `start_deg` to `end_deg` (both in degrees), blending with alpha.
/// Draws a pieslice sector of the `source` image into the `layer` destination.
///
/// Pixels in the sector are alpha-blended from source into the destination layer at the given
/// center_x/center_y placement.
///
/// Positive and negative angles are supported and are automatically normalized if > +/- 360°.
///
/// # Arguments
///
/// * `layer`: Destination layer.
/// * `source`: Source image to cut out a pie-slice sector.
/// * `center_x`: Center x position.
/// * `center_y`: Center y position.
/// * `start_deg`: Starting angle, in degrees. Angles are measured from 3 oclock, increasing clockwise.
/// * `end_deg`: Ending angle, in degrees.
///
fn draw_pie_slice(
layer: &mut RgbaImage,
source: &RgbaImage,
@@ -510,8 +522,8 @@ impl PanelRenderer {
// Radius is half the smaller dimension
let radius = (src_w.min(src_h) as f32) / 2.0;
// Convert angles to radians and normalize
let start = start_deg.to_radians();
let end = end_deg.to_radians();
let start = (start_deg % 360f32).to_radians();
let end = (end_deg % 360f32).to_radians();
// Helper: check if angle t is between start and end (clockwise)
let in_sector = |t: f32| {
let mut a = t;