add Image::border_poly

This commit is contained in:
bendn 2023-10-13 20:55:33 +07:00
parent 06fc71d4bc
commit cd17b4860f
No known key found for this signature in database
GPG key ID: 0D9D3A2A3B2A93D6
4 changed files with 48 additions and 2 deletions

View file

@ -1,6 +1,6 @@
[package]
name = "fimg"
version = "0.4.15"
version = "0.4.16"
authors = ["bend-n <bend.n@outlook.com>"]
license = "MIT"
edition = "2021"

View file

@ -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,
);
}
}
}

View file

@ -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)
}
}

Binary file not shown.