From cd17b4860f90a21796a8eb22b9e7ee1a4fef5933 Mon Sep 17 00:00:00 2001 From: bendn Date: Fri, 13 Oct 2023 20:55:33 +0700 Subject: [PATCH] add Image::border_poly --- Cargo.toml | 2 +- src/drawing/poly.rs | 36 ++++++++++++++++++++++++++++++++++- src/math.rs | 12 ++++++++++++ tdata/border_pentagon.imgbuf | Bin 0 -> 10000 bytes 4 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 tdata/border_pentagon.imgbuf 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 0000000000000000000000000000000000000000..39004de8952c9cfc9e637a86a79d0035677228f1 GIT binary patch literal 10000 zcmeH{S(3vr2t;%LOFNPiHVY{TaFu5Ye<5i48N9q+b=3xH1GRzLKy9ElP#gH;8#s>R z-U%9@U-v;i{x?DxpojUBTmbou5zsSFBOb*FjA5N4f-o`=vHRMd?+$b;FA__E%7w7a5kr_5K?E|I z58I6h5iwN=`FJ3M9*y;uL5W&5B+&qZp$7{34GeN6fetJXGRlke&Vej=L=KdtoFgI| z9(|24GLcR#a(HjtQL0*-2{hEavFkJ`25JNUZ3AzQXoj)? literal 0 HcmV?d00001