use crate::concentric_circles_adapters::{scaling_range_skip_r, scaling_range_take_r};
use crate::{Add, FromAs, PhantomData, Radii, RangeInclusive, Scaling, Zero};
impl<T: ?Sized> PointWithColor for T where T: Iterator {}
pub trait PointWithColor: Iterator {
#[inline]
fn crown_with_color<U, Color>(self, width: U, height: U) -> CrownWithColor<Self, U, Color>
where
Self: Sized + Iterator<Item = (U, U, Color)>,
U: Zero + Copy,
{
CrownWithColor {
iter: self,
x_bound_min: U::zero(),
y_bound_min: U::zero(),
x_bound_max: width,
y_bound_max: height,
}
}
#[inline]
fn crown_with_size_color<T, Color>(self, size: (T, T, T, T)) -> CrownWithColor<Self, T, Color>
where
Self: Sized + Iterator<Item = (T, T, Color)>,
T: Copy,
{
CrownWithColor {
iter: self,
x_bound_min: size.0,
y_bound_min: size.1,
x_bound_max: size.2,
y_bound_max: size.3,
}
}
#[inline]
fn map_circle_sector<T, F, Color>(
self,
angle_take_from: usize,
angle_take_to: usize,
f: F,
) -> MapCircleSector<Self, F>
where
Self: Iterator<Item = (T, T, Color)> + Radii + Sized,
F: FnMut(usize, &mut Color),
{
let inner_radius: usize = self.current_inner_radius();
let outer_radius: usize = self.outer_radius();
let (angle_take_from, angle_take_to) = if angle_take_from >= angle_take_to {
(360, 360)
} else {
(
angle_take_from,
if angle_take_to > 360 {
360
} else {
angle_take_to
},
)
};
let mut take_values_iter = scaling_range_take_r(outer_radius, angle_take_to);
let mut skip_values_iter = scaling_range_skip_r(outer_radius, angle_take_from);
if inner_radius > 1 {
let _ = take_values_iter.nth(inner_radius - 2);
let _ = skip_values_iter.nth(inner_radius - 2);
}
MapCircleSector {
iter: self,
f,
take_values_iter,
skip_values_iter,
take_values: 0,
skip_values: 0,
inner_radius: 0,
count_points: 0,
}
}
#[inline]
fn map_color_radial<T, F, Color>(self, f: F) -> MapColorRadial<Self, F>
where
Self: Iterator<Item = (T, T, Color)> + Sized,
F: FnMut(usize, &mut Color),
{
MapColorRadial { iter: self, f }
}
#[inline]
fn to_image_coordinates_with_color<T, U>(
self,
x_offset: T,
y_offset: T,
) -> ToImageCoordinatesWithColor<Self, T, U>
where
Self: Sized + Iterator,
{
ToImageCoordinatesWithColor {
iter: self,
x_offset,
y_offset,
phantom: PhantomData,
}
}
}
#[derive(Clone, Debug)]
pub struct CrownWithColor<I: Iterator<Item = (U, U, Color)>, U, Color> {
iter: I,
x_bound_min: U,
y_bound_min: U,
x_bound_max: U,
y_bound_max: U,
}
impl<I, U, Color> Iterator for CrownWithColor<I, U, Color>
where
I: Iterator<Item = (U, U, Color)>,
U: PartialOrd + Copy,
{
type Item = (U, U, Color);
#[inline]
fn next(&mut self) -> Option<Self::Item> {
for (x, y, color) in self.iter.by_ref() {
if x >= self.x_bound_min
&& y >= self.y_bound_min
&& x < self.x_bound_max
&& y < self.y_bound_max
{
return Some((x, y, color));
}
}
None
}
}
#[derive(Debug, Clone)]
pub struct MapCircleSector<I, F>
where
I: Iterator,
{
iter: I,
f: F,
take_values_iter: Scaling<RangeInclusive<usize>, usize, usize>,
skip_values_iter: Scaling<RangeInclusive<usize>, usize, usize>,
take_values: usize,
skip_values: usize,
inner_radius: usize,
count_points: usize,
}
impl<I, T, F, Color> Iterator for MapCircleSector<I, F>
where
I: Iterator<Item = (T, T, Color)> + Radii,
F: FnMut(usize, &mut Color),
{
type Item = I::Item;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
let (x, y, mut a) = self.iter.next()?;
let current_inner_radius = self.current_inner_radius();
if self.inner_radius != current_inner_radius {
self.inner_radius = current_inner_radius;
self.skip_values = self.skip_values_iter.next()?;
self.take_values = self.take_values_iter.next()?;
self.count_points = 0;
}
self.count_points += 1;
if self.skip_values < self.count_points && self.count_points <= self.take_values {
(self.f)(current_inner_radius, &mut a);
}
Some((x, y, a))
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
#[derive(Debug, Clone)]
pub struct MapColorRadial<I, F> {
iter: I,
f: F,
}
impl<I, T, F, Color> Iterator for MapColorRadial<I, F>
where
I: Iterator<Item = (T, T, Color)> + Radii,
F: FnMut(usize, &mut Color),
{
type Item = I::Item;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
let (x, y, mut a) = self.iter.next()?;
(self.f)(self.iter.current_inner_radius(), &mut a);
Some((x, y, a))
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
#[derive(Clone, Debug)]
pub struct ToImageCoordinatesWithColor<I, T, U> {
iter: I,
x_offset: T,
y_offset: T,
phantom: PhantomData<U>,
}
impl<I, T, U, Color> Iterator for ToImageCoordinatesWithColor<I, T, U>
where
I: Iterator<Item = (T, T, Color)>,
T: Add<Output = T> + Copy,
U: FromAs<T> + Copy,
{
type Item = (U, U, Color);
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|(x, y, color)| {
(
U::from_as(x + self.x_offset),
U::from_as(y + self.y_offset),
color,
)
})
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<I, F> Radii for MapCircleSector<I, F>
where
I: Iterator + Radii,
{
#[inline]
fn outer_radius(&self) -> usize {
self.iter.outer_radius()
}
#[inline]
fn current_inner_radius(&self) -> usize {
self.iter.current_inner_radius()
}
}
impl<I, F> Radii for MapColorRadial<I, F>
where
I: Iterator + Radii,
{
#[inline]
fn outer_radius(&self) -> usize {
self.iter.outer_radius()
}
#[inline]
fn current_inner_radius(&self) -> usize {
self.iter.current_inner_radius()
}
}
impl<I, T, U> Radii for ToImageCoordinatesWithColor<I, T, U>
where
I: Iterator<Item = (T, T)> + Radii,
{
#[inline]
fn outer_radius(&self) -> usize {
self.iter.outer_radius()
}
#[inline]
fn current_inner_radius(&self) -> usize {
self.iter.current_inner_radius()
}
}