mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-01-20 20:31:06 +00:00
feat(core/rust): introduce f32 angles for sector drawing
[no changelog]
This commit is contained in:
parent
e3a383526b
commit
f03e4c8d9c
@ -4,7 +4,7 @@ use crate::ui::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use super::super::{
|
use super::super::{
|
||||||
utils::{circle_points, line_points, sin_i16, PI4},
|
utils::{circle_points, line_points, sin_f32},
|
||||||
BitmapView, Viewport,
|
BitmapView, Viewport,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -576,12 +576,12 @@ pub trait Canvas: BasicCanvas {
|
|||||||
&mut self,
|
&mut self,
|
||||||
center: Point,
|
center: Point,
|
||||||
radius: i16,
|
radius: i16,
|
||||||
mut start: i16,
|
mut start: f32,
|
||||||
mut end: i16,
|
mut end: f32,
|
||||||
color: Color,
|
color: Color,
|
||||||
) {
|
) {
|
||||||
start = (PI4 * 8 + start % (PI4 * 8)) % (PI4 * 8);
|
start = (360.0 + start % 360.0) % 360.0;
|
||||||
end = (PI4 * 8 + end % (PI4 * 8)) % (PI4 * 8);
|
end = (360.0 + end % 360.0) % 360.0;
|
||||||
|
|
||||||
let alpha = 255;
|
let alpha = 255;
|
||||||
let alpha_mul = |a: u8| -> u8 { ((a as u16 * alpha as u16) / 255) as u8 };
|
let alpha_mul = |a: u8| -> u8 { ((a as u16 * alpha as u16) / 255) as u8 };
|
||||||
@ -591,12 +591,14 @@ pub trait Canvas: BasicCanvas {
|
|||||||
self.draw_pixel(center, color);
|
self.draw_pixel(center, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PI4: f32 = 45.0;
|
||||||
|
|
||||||
for octant in 0..8 {
|
for octant in 0..8 {
|
||||||
let angle = octant * PI4;
|
let angle = PI4 * octant as f32;
|
||||||
|
|
||||||
// Function for calculation of 'u' coordinate inside the circle octant
|
// Function for calculation of 'u' coordinate inside the circle octant
|
||||||
// radius * sin(angle)
|
// radius * sin(angle)
|
||||||
let sin = |angle: i16| -> i16 { sin_i16(angle, radius) };
|
let sin = |angle: f32| -> i16 { (sin_f32(angle) * radius as f32 + 0.5) as i16 };
|
||||||
|
|
||||||
// Calculate the octant's bounding rectangle
|
// Calculate the octant's bounding rectangle
|
||||||
let p = Point::new(sin(PI4) + 1, -radius - 1).rot(octant);
|
let p = Point::new(sin(PI4) + 1, -radius - 1).rot(octant);
|
||||||
@ -660,7 +662,7 @@ pub trait Canvas: BasicCanvas {
|
|||||||
} else {
|
} else {
|
||||||
// Partial fill
|
// Partial fill
|
||||||
let u1 = if start <= angle {
|
let u1 = if start <= angle {
|
||||||
sin(corr(0))
|
sin(corr(0.0))
|
||||||
} else {
|
} else {
|
||||||
sin(corr(start - angle))
|
sin(corr(start - angle))
|
||||||
};
|
};
|
||||||
@ -682,7 +684,7 @@ pub trait Canvas: BasicCanvas {
|
|||||||
// Partial fill
|
// Partial fill
|
||||||
if (end > angle) && (end < angle + PI4) {
|
if (end > angle) && (end < angle + PI4) {
|
||||||
// Fill up to `end`
|
// Fill up to `end`
|
||||||
fill_octant(radius, sin(corr(0)), sin(corr(end - angle)), filler);
|
fill_octant(radius, sin(corr(0.0)), sin(corr(end - angle)), filler);
|
||||||
}
|
}
|
||||||
if start < angle + PI4 {
|
if start < angle + PI4 {
|
||||||
// Fill all from `start`
|
// Fill all from `start`
|
||||||
|
@ -15,8 +15,8 @@ pub struct Circle {
|
|||||||
bg_color: Option<Color>,
|
bg_color: Option<Color>,
|
||||||
thickness: i16,
|
thickness: i16,
|
||||||
alpha: u8,
|
alpha: u8,
|
||||||
start_angle: Option<i16>,
|
start_angle: Option<f32>,
|
||||||
end_angle: Option<i16>,
|
end_angle: Option<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Circle {
|
impl Circle {
|
||||||
@ -55,14 +55,14 @@ impl Circle {
|
|||||||
Self { alpha, ..self }
|
Self { alpha, ..self }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_start_angle(self, from_angle: i16) -> Self {
|
pub fn with_start_angle(self, from_angle: f32) -> Self {
|
||||||
Self {
|
Self {
|
||||||
start_angle: Some(from_angle),
|
start_angle: Some(from_angle),
|
||||||
..self
|
..self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_end_angle(self, to_angle: i16) -> Self {
|
pub fn with_end_angle(self, to_angle: f32) -> Self {
|
||||||
Self {
|
Self {
|
||||||
end_angle: Some(to_angle),
|
end_angle: Some(to_angle),
|
||||||
..self
|
..self
|
||||||
@ -119,8 +119,8 @@ impl Shape<'_> for Circle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let start = self.start_angle.unwrap_or(0);
|
let start = self.start_angle.unwrap_or(0.0);
|
||||||
let end = self.end_angle.unwrap_or(360);
|
let end = self.end_angle.unwrap_or(360.0);
|
||||||
|
|
||||||
if let Some(color) = self.fg_color {
|
if let Some(color) = self.fg_color {
|
||||||
if th > 0 {
|
if th > 0 {
|
||||||
|
@ -6,4 +6,4 @@ mod trigo;
|
|||||||
pub use blur::{BlurAlgorithm, BlurBuff};
|
pub use blur::{BlurAlgorithm, BlurBuff};
|
||||||
pub use circle::circle_points;
|
pub use circle::circle_points;
|
||||||
pub use line::line_points;
|
pub use line::line_points;
|
||||||
pub use trigo::{sin_i16, PI4};
|
pub use trigo::sin_f32;
|
||||||
|
@ -1,29 +1,12 @@
|
|||||||
/// Integer representing an angle of 45 degress (PI/4).
|
|
||||||
//
|
|
||||||
// Changing this constant requires revisiting isin() algorithm
|
|
||||||
// (for higher values consider changing T type to i64 or f32)
|
|
||||||
pub const PI4: i16 = 45;
|
|
||||||
|
|
||||||
/// Fast sine approximation.
|
/// Fast sine approximation.
|
||||||
///
|
///
|
||||||
/// Returns mult * sin(angle).
|
/// Returns sin(angle).
|
||||||
///
|
///
|
||||||
/// Angle must be in range <0..PI4>.
|
/// Angle must be in range <0..45>.
|
||||||
/// This function provides an error within +-1 for multiplier up to 500
|
pub fn sin_f32(angle: f32) -> f32 {
|
||||||
pub fn sin_i16(angle: i16, mult: i16) -> i16 {
|
assert!((0.0..=45.0).contains(&angle));
|
||||||
assert!((0..=PI4).contains(&angle));
|
|
||||||
assert!(mult <= 2500);
|
|
||||||
|
|
||||||
type T = i32;
|
// Applying the approximation x - x^3 / 6
|
||||||
|
let x = (angle / 180.0) * core::f32::consts::PI;
|
||||||
// Based on polynomial x - x^3 / 6
|
x - x * x * x / 6.0
|
||||||
let x = angle as T;
|
|
||||||
|
|
||||||
// Constants for the approximation
|
|
||||||
const K: f32 = (PI4 as f32) * 4.0 / core::f32::consts::PI;
|
|
||||||
const M: T = (6.0 * K * K + 0.5) as T;
|
|
||||||
const N: T = (6.0 * K * K * K + 0.5) as T;
|
|
||||||
|
|
||||||
// Applying the approximation
|
|
||||||
(((M * x - x * x * x) * mult as T + N / 2) / N) as i16
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user