fast image operations
-rw-r--r--Cargo.toml2
-rw-r--r--src/drawing/poly.rs36
-rw-r--r--src/math.rs12
-rw-r--r--tdata/border_pentagon.imgbufbin0 -> 10000 bytes
4 files changed, 48 insertions, 2 deletions
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 <[email protected]>"]
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<T: AsMut<[u8]> + AsRef<[u8]>, const CHANNELS: usize> Image<T, CHANNELS> {
}
}
}
+
+ /// 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
--- /dev/null
+++ b/tdata/border_pentagon.imgbuf
Binary files differ