diff --git a/Cargo.toml b/Cargo.toml index da0a8aa..7d1ddc4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "fimg" -version = "0.4.15" +version = "0.4.16" authors = ["bend-n "] license = "MIT" edition = "2021" diff --git a/src/drawing/poly.rs b/src/drawing/poly.rs index 69ca4a3..ecad1ab 100644 --- a/src/drawing/poly.rs +++ b/src/drawing/poly.rs @@ -1,5 +1,5 @@ //! draw polygons -use crate::math::madd; +use crate::math::{madd, FExt}; use std::cmp::{max, min}; use std::f32::consts::TAU; @@ -141,4 +141,38 @@ impl + AsRef<[u8]>, const CHANNELS: usize> Image { } } } + + /// Draw a bordered polygon. + /// Prefer [`Image::border_circle`] to draw circles. + /// See also [`Image::poly`]. + /// ``` + /// let mut i = fimg::Image::alloc(100, 100); + /// i.border_poly((50., 50.), 5, 25., 0., 7., [255]); + /// # assert_eq!(i.buffer(), include_bytes!("../../tdata/border_pentagon.imgbuf")); + /// ``` + pub fn border_poly( + &mut self, + (x, y): (f32, f32), + sides: usize, + radius: f32, + rotation: f32, + stroke: f32, + c: [u8; CHANNELS], + ) { + let space = TAU / sides as f32; + let step = stroke / 2.0 / (space / 2.0).cos(); + let r1 = radius - step; + let r2 = radius + step; + let r = |a: f32, b: f32| (a.round() as i32, b.round() as i32); + for i in 0..sides { + let a = space.madd(i as f32, rotation); + self.quad( + r(r1.madd(a.cos(), x), r1.madd(a.sin(), y)), + r(r1.madd((a + space).cos(), x), r1.madd((a + space).sin(), y)), + r(r2.madd((a + space).cos(), x), r2.madd((a + space).sin(), y)), + r(r2.madd(a.cos(), x), r2.madd(a.sin(), y)), + c, + ); + } + } } diff --git a/src/math.rs b/src/math.rs index 6ff5572..08e8457 100644 --- a/src/math.rs +++ b/src/math.rs @@ -8,3 +8,15 @@ pub fn madd(a: f32, b: f32, c: f32) -> f32 { a * b + c } } + +/// helps +pub trait FExt { + /// Calculates `a * b + c`, with hardware support if possible. + fn madd(self, a: f32, b: f32) -> Self; +} + +impl FExt for f32 { + fn madd(self, a: f32, b: f32) -> Self { + madd(self, a, b) + } +} diff --git a/tdata/border_pentagon.imgbuf b/tdata/border_pentagon.imgbuf new file mode 100644 index 0000000..39004de Binary files /dev/null and b/tdata/border_pentagon.imgbuf differ