From c264f735ced0a653681d51c6b11492d80441db73 Mon Sep 17 00:00:00 2001
From: bendn <bend.n@outlook.com>
Date: Sun, 15 Oct 2023 10:22:38 +0700
Subject: [PATCH] use vec2's

---
 Cargo.toml          |  1 +
 src/drawing/line.rs | 25 ++++++++++++------------
 src/drawing/poly.rs | 46 ++++++++++++++++++++++++++-------------------
 src/drawing/tri.rs  | 15 ++++++++++-----
 src/lib.rs          |  1 +
 5 files changed, 51 insertions(+), 37 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index 7d1ddc4..1b1bde0 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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 = [
diff --git a/src/drawing/line.rs b/src/drawing/line.rs
index 3498d95..e1dde96 100644
--- a/src/drawing/line.rs
+++ b/src/drawing/line.rs
@@ -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,
         );
     }
diff --git a/src/drawing/poly.rs b/src/drawing/poly.rs
index ecad1ab..0b8f3ac 100644
--- a/src/drawing/poly.rs
+++ b/src/drawing/poly.rs
@@ -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,
             );
         }
diff --git a/src/drawing/tri.rs b/src/drawing/tri.rs
index 1333abe..5fb90bb 100644
--- a/src/drawing/tri.rs
+++ b/src/drawing/tri.rs
@@ -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) };
                 }
             }
         }
diff --git a/src/lib.rs b/src/lib.rs
index 1427562..cd82ba8 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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()) }
     }
 }