mirror of
https://github.com/bend-n/fimg.git
synced 2024-12-22 10:28:21 -06:00
add Image::circle
This commit is contained in:
parent
e405062947
commit
ac3f07c797
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "fimg"
|
name = "fimg"
|
||||||
version = "0.4.10"
|
version = "0.4.11"
|
||||||
authors = ["bend-n <bend.n@outlook.com>"]
|
authors = ["bend-n <bend.n@outlook.com>"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
|
@ -188,9 +188,7 @@ unsafe fn transpose_non_power_of_two<const CHANNELS: usize, T: DerefMut<Target =
|
||||||
for i in 0..size {
|
for i in 0..size {
|
||||||
for j in i..size {
|
for j in i..size {
|
||||||
// SAFETY: caller ensures squarity
|
// SAFETY: caller ensures squarity
|
||||||
unsafe {
|
unsafe { b.swap_unchecked(i * size + j, j * size + i) };
|
||||||
b.swap_unchecked(i * size + j, j * size + i);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
67
src/drawing/circle.rs
Normal file
67
src/drawing/circle.rs
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
//! draw 2d circles
|
||||||
|
use crate::Image;
|
||||||
|
use std::ops::DerefMut;
|
||||||
|
|
||||||
|
impl<T: DerefMut<Target = [u8]>, const CHANNELS: usize> Image<T, CHANNELS> {
|
||||||
|
/// Draws a circle, using the [Bresenham's circle](https://en.wikipedia.org/wiki/Midpoint_circle_algorithm) algorithm.
|
||||||
|
/// ```
|
||||||
|
/// # use fimg::Image;
|
||||||
|
/// let mut i = Image::alloc(50, 50);
|
||||||
|
/// i.border_circle((25, 25), 20, [255]);
|
||||||
|
/// # assert_eq!(i.buffer(), include_bytes!("../../tdata/circle.imgbuf"));
|
||||||
|
/// ```
|
||||||
|
pub fn border_circle(&mut self, (xc, yc): (i32, i32), radius: i32, c: [u8; CHANNELS]) {
|
||||||
|
let mut x = 0;
|
||||||
|
let mut y = radius;
|
||||||
|
let mut p = 1 - radius;
|
||||||
|
/// bounds the pixels
|
||||||
|
macro_rules! bound {
|
||||||
|
($($x:expr,$y:expr);+;) => {
|
||||||
|
$(if $x >= 0 && $x < self.width() as i32 && $y >= 0 && $y < self.height() as i32 {
|
||||||
|
// SAFETY: ^
|
||||||
|
unsafe { self.set_pixel($x as u32, $y as u32, c) };
|
||||||
|
})+
|
||||||
|
};
|
||||||
|
}
|
||||||
|
while x <= y {
|
||||||
|
bound! {
|
||||||
|
xc + x, yc + y;
|
||||||
|
xc + y, yc + x;
|
||||||
|
xc - y, yc + x;
|
||||||
|
xc - x, yc + y;
|
||||||
|
xc - x, yc - y;
|
||||||
|
xc - y, yc - x;
|
||||||
|
xc + y, yc - x;
|
||||||
|
xc + x, yc - y;
|
||||||
|
};
|
||||||
|
x += 1;
|
||||||
|
if p < 0 {
|
||||||
|
p += 2 * x + 1;
|
||||||
|
} else {
|
||||||
|
y -= 1;
|
||||||
|
p += 2 * (x - y) + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Draw a filled circle.
|
||||||
|
/// ```
|
||||||
|
/// # use fimg::Image;
|
||||||
|
/// let mut i = Image::alloc(50, 50);
|
||||||
|
/// i.circle((25, 25), 20, [255]);
|
||||||
|
/// # assert_eq!(i.buffer(), include_bytes!("../../tdata/circle2.imgbuf"));
|
||||||
|
/// ```
|
||||||
|
pub fn circle(&mut self, (xc, yc): (i32, i32), radius: i32, c: [u8; CHANNELS]) {
|
||||||
|
for x in -radius..radius {
|
||||||
|
let h = ((radius * radius - x * x) as f32).sqrt().round() as i32;
|
||||||
|
for y in -h..h {
|
||||||
|
let x = x + xc;
|
||||||
|
let y = y + yc;
|
||||||
|
if x >= 0 && x < self.width() as i32 && y >= 0 && y < self.height() as i32 {
|
||||||
|
// SAFETY: ^
|
||||||
|
unsafe { self.set_pixel(x as u32, y as u32, c) };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
//! contains drawing operations, like {line, box, triangle, polygon} drawing
|
//! contains drawing operations, like {line, box, triangle, polygon, circle} drawing
|
||||||
mod r#box;
|
mod r#box;
|
||||||
|
mod circle;
|
||||||
mod line;
|
mod line;
|
||||||
mod poly;
|
mod poly;
|
||||||
mod tri;
|
mod tri;
|
||||||
|
|
|
@ -86,6 +86,7 @@ impl<T: DerefMut<Target = [u8]>, const CHANNELS: usize> Image<T, CHANNELS> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draws a regular convex polygon with a specified number of sides, a radius, and a rotation (radians).
|
/// Draws a regular convex polygon with a specified number of sides, a radius, and a rotation (radians).
|
||||||
|
/// Prefer [`Image::circle`] over `poly(.., 600, ..)`.
|
||||||
/// Calls into [`Image::tri`] and [`Image::quad`].
|
/// Calls into [`Image::tri`] and [`Image::quad`].
|
||||||
/// ```
|
/// ```
|
||||||
/// # use fimg::Image;
|
/// # use fimg::Image;
|
||||||
|
@ -113,7 +114,7 @@ impl<T: DerefMut<Target = [u8]>, const CHANNELS: usize> Image<T, CHANNELS> {
|
||||||
self.tri(
|
self.tri(
|
||||||
add(trans(space + rotation)),
|
add(trans(space + rotation)),
|
||||||
add(trans(rotation)),
|
add(trans(rotation)),
|
||||||
add(trans(space * 2.0 + rotation)),
|
add(trans(space.mul_add(2.0, rotation))),
|
||||||
c,
|
c,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -122,9 +123,9 @@ impl<T: DerefMut<Target = [u8]>, const CHANNELS: usize> Image<T, CHANNELS> {
|
||||||
for i in (0..sides - 1).step_by(2).map(|i| i as f32) {
|
for i in (0..sides - 1).step_by(2).map(|i| i as f32) {
|
||||||
self.quad(
|
self.quad(
|
||||||
r((x, y)),
|
r((x, y)),
|
||||||
r(add(trans(space * i + rotation))),
|
r(add(trans(space.mul_add(i, rotation)))),
|
||||||
r(add(trans(space * (i + 1.) + rotation))),
|
r(add(trans(space.mul_add(i + 1., rotation)))),
|
||||||
r(add(trans(space * (i + 2.) + rotation))),
|
r(add(trans(space.mul_add(i + 2., rotation)))),
|
||||||
c,
|
c,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -134,8 +135,8 @@ impl<T: DerefMut<Target = [u8]>, const CHANNELS: usize> Image<T, CHANNELS> {
|
||||||
// the missing piece
|
// the missing piece
|
||||||
self.tri(
|
self.tri(
|
||||||
(x, y),
|
(x, y),
|
||||||
add(trans(space * i + rotation)),
|
add(trans(space.mul_add(i, rotation))),
|
||||||
add(trans(space * (i + 1.) + rotation)),
|
add(trans(space.mul_add(i + 1., rotation))),
|
||||||
c,
|
c,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
BIN
tdata/circle.imgbuf
Normal file
BIN
tdata/circle.imgbuf
Normal file
Binary file not shown.
BIN
tdata/circle2.imgbuf
Normal file
BIN
tdata/circle2.imgbuf
Normal file
Binary file not shown.
Loading…
Reference in a new issue