mirror of
https://github.com/bend-n/fimg.git
synced 2024-12-22 10:28:21 -06:00
use vec2's
This commit is contained in:
parent
cd17b4860f
commit
c264f735ce
|
@ -11,6 +11,7 @@ exclude = ["tdata", "benches/", ".gitignore"]
|
|||
[dependencies]
|
||||
mattr = "0.0.2"
|
||||
png = { version = "0.17", features = ["unstable"], optional = true }
|
||||
vecto = "0.1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
iai = { version = "0.1.1", features = [
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#![allow(clippy::missing_docs_in_private_items)]
|
||||
use crate::Image;
|
||||
use std::iter::Iterator;
|
||||
use vecto::Vec2;
|
||||
|
||||
/// taken from [bresenham-rs](https://github.com/mbr/bresenham-rs)
|
||||
pub struct Bresenham {
|
||||
|
@ -156,20 +157,18 @@ impl<T: AsMut<[u8]> + AsRef<[u8]>, const CHANNELS: usize> Image<T, CHANNELS> {
|
|||
/// ```
|
||||
pub fn thick_line(
|
||||
&mut self,
|
||||
(x1, y1): (f32, f32),
|
||||
(x2, y2): (f32, f32),
|
||||
a: impl Into<Vec2>,
|
||||
b: impl Into<Vec2>,
|
||||
stroke: f32,
|
||||
color: [u8; CHANNELS],
|
||||
) {
|
||||
let (wx, wy) = {
|
||||
let (x, y) = (y1 - y2, -(x1 - x2));
|
||||
let l = (x * x + y * y).sqrt();
|
||||
((x / l) * (stroke / 2.0), (y / l) * (stroke / 2.0))
|
||||
};
|
||||
let a = a.into();
|
||||
let b = b.into();
|
||||
let w = (a - b).orthogonal().normalized() * (stroke / 2.0);
|
||||
macro_rules! p {
|
||||
($x:expr,$y:expr) => {
|
||||
($x:expr) => {
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
($x.round() as i32, $y.round() as i32)
|
||||
($x.x.round() as i32, $x.y.round() as i32)
|
||||
};
|
||||
}
|
||||
// order:
|
||||
|
@ -177,10 +176,10 @@ impl<T: AsMut<[u8]> + AsRef<[u8]>, const CHANNELS: usize> Image<T, CHANNELS> {
|
|||
// [ ]
|
||||
// ^ x3 ^ x4
|
||||
self.quad(
|
||||
p!(x1 - wx, y1 - wy), // x1
|
||||
p!(x2 - wx, y2 - wy), // x2
|
||||
p!(x2 + wx, y2 + wy), // x3
|
||||
p!(x1 + wx, y1 + wy), // x4
|
||||
p!(a - w), // x1
|
||||
p!(b - w), // x2
|
||||
p!(b + w), // x3
|
||||
p!(a + w), // x4
|
||||
color,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
use crate::math::{madd, FExt};
|
||||
use std::cmp::{max, min};
|
||||
use std::f32::consts::TAU;
|
||||
use vecto::Vec2;
|
||||
|
||||
use crate::Image;
|
||||
|
||||
|
@ -97,22 +98,22 @@ impl<T: AsMut<[u8]> + AsRef<[u8]>, const CHANNELS: usize> Image<T, CHANNELS> {
|
|||
/// ```
|
||||
pub fn poly(
|
||||
&mut self,
|
||||
(x, y): (f32, f32),
|
||||
pos: impl Into<Vec2>,
|
||||
sides: usize,
|
||||
radius: f32,
|
||||
rotation: f32,
|
||||
c: [u8; CHANNELS],
|
||||
) {
|
||||
let trans = |a: f32| (a.cos() * radius, a.sin() * radius);
|
||||
let r = |(a, b): (f32, f32)| (a.round() as i32, b.round() as i32);
|
||||
let add = |(a, b)| (a + x, b + y);
|
||||
let pos = pos.into();
|
||||
let trans = |a: f32| Vec2::from_angle(a) * radius;
|
||||
let r = |v: Vec2| (v.x.round() as i32, v.y.round() as i32);
|
||||
match sides {
|
||||
3 => {
|
||||
let space = TAU / 3.0;
|
||||
self.tri(
|
||||
add(trans(space + rotation)),
|
||||
add(trans(rotation)),
|
||||
add(trans(madd(space, 2.0, rotation))),
|
||||
trans(space + rotation) + pos,
|
||||
trans(rotation) + pos,
|
||||
trans(madd(space, 2.0, rotation)) + pos,
|
||||
c,
|
||||
);
|
||||
}
|
||||
|
@ -120,10 +121,10 @@ impl<T: AsMut<[u8]> + AsRef<[u8]>, const CHANNELS: usize> Image<T, CHANNELS> {
|
|||
let space = TAU / sides as f32;
|
||||
for i in (0..sides - 1).step_by(2).map(|i| i as f32) {
|
||||
self.quad(
|
||||
r((x, y)),
|
||||
r(add(trans(madd(space, i, rotation)))),
|
||||
r(add(trans(madd(space, i + 1., rotation)))),
|
||||
r(add(trans(madd(space, i + 2., rotation)))),
|
||||
r(pos),
|
||||
r(trans(madd(space, i, rotation)) + pos),
|
||||
r(trans(madd(space, i + 1., rotation)) + pos),
|
||||
r(trans(madd(space, i + 2., rotation)) + pos),
|
||||
c,
|
||||
);
|
||||
}
|
||||
|
@ -132,9 +133,9 @@ impl<T: AsMut<[u8]> + AsRef<[u8]>, const CHANNELS: usize> Image<T, CHANNELS> {
|
|||
let i = (sides - 1) as f32;
|
||||
// the missing piece
|
||||
self.tri(
|
||||
(x, y),
|
||||
add(trans(madd(space, i, rotation))),
|
||||
add(trans(madd(space, i + 1., rotation))),
|
||||
pos,
|
||||
trans(madd(space, i, rotation)) + pos,
|
||||
trans(madd(space, i + 1., rotation)) + pos,
|
||||
c,
|
||||
);
|
||||
}
|
||||
|
@ -152,13 +153,14 @@ impl<T: AsMut<[u8]> + AsRef<[u8]>, const CHANNELS: usize> Image<T, CHANNELS> {
|
|||
/// ```
|
||||
pub fn border_poly(
|
||||
&mut self,
|
||||
(x, y): (f32, f32),
|
||||
pos: impl Into<Vec2>,
|
||||
sides: usize,
|
||||
radius: f32,
|
||||
rotation: f32,
|
||||
stroke: f32,
|
||||
c: [u8; CHANNELS],
|
||||
) {
|
||||
let pos = pos.into();
|
||||
let space = TAU / sides as f32;
|
||||
let step = stroke / 2.0 / (space / 2.0).cos();
|
||||
let r1 = radius - step;
|
||||
|
@ -167,10 +169,16 @@ impl<T: AsMut<[u8]> + AsRef<[u8]>, const CHANNELS: usize> Image<T, CHANNELS> {
|
|||
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)),
|
||||
r(r1.madd(a.cos(), pos.x), r1.madd(a.sin(), pos.y)),
|
||||
r(
|
||||
r1.madd((a + space).cos(), pos.x),
|
||||
r1.madd((a + space).sin(), pos.y),
|
||||
),
|
||||
r(
|
||||
r2.madd((a + space).cos(), pos.x),
|
||||
r2.madd((a + space).sin(), pos.y),
|
||||
),
|
||||
r(r2.madd(a.cos(), pos.x), r2.madd(a.sin(), pos.y)),
|
||||
c,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
//! trongle drawing
|
||||
use vecto::Vec2;
|
||||
|
||||
use crate::math::madd;
|
||||
use crate::Image;
|
||||
use std::cmp::{max, min};
|
||||
|
@ -19,11 +21,14 @@ impl<T: AsMut<[u8]> + AsRef<[u8]>, const CHANNELS: usize> Image<T, CHANNELS> {
|
|||
/// ```
|
||||
pub fn tri(
|
||||
&mut self,
|
||||
(x2, y2): (f32, f32),
|
||||
(x1, y1): (f32, f32),
|
||||
(x3, y3): (f32, f32),
|
||||
c: [u8; CHANNELS],
|
||||
b: impl Into<Vec2>,
|
||||
a: impl Into<Vec2>,
|
||||
c: impl Into<Vec2>,
|
||||
col: [u8; CHANNELS],
|
||||
) {
|
||||
let Vec2 { x: x1, y: y1 } = a.into();
|
||||
let Vec2 { x: x2, y: y2 } = b.into();
|
||||
let Vec2 { x: x3, y: y3 } = c.into();
|
||||
let ymin = max(y1.min(y2).min(y3) as u32, 0);
|
||||
let ymax = min(y1.max(y2).max(y3) as u32, self.height());
|
||||
let xmin = max(x1.min(x2).min(x3) as u32, 0);
|
||||
|
@ -36,7 +41,7 @@ impl<T: AsMut<[u8]> + AsRef<[u8]>, const CHANNELS: usize> Image<T, CHANNELS> {
|
|||
&& madd(x3 - x1, y as f32 - y3, -(y3 - y1) * (x as f32 - x3)) > 0.
|
||||
{
|
||||
// SAFETY: x, y are bounded
|
||||
unsafe { self.set_pixel(x, y, c) };
|
||||
unsafe { self.set_pixel(x, y, col) };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -254,6 +254,7 @@ impl<const CHANNELS: usize, const N: usize> Image<[u8; N], CHANNELS> {
|
|||
impl<const CHANNELS: usize> Image<&[u8], CHANNELS> {
|
||||
/// Box this image.
|
||||
pub fn boxed(self) -> Image<Box<[u8]>, CHANNELS> {
|
||||
// SAFETY: ctor
|
||||
unsafe { Image::new(self.width, self.height, self.buffer.into()) }
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue