use image::{ImageBuffer, Rgba};
use self::{
axis_x::{draw_x_axis, draw_x_axis_scale_markings, get_x_axis_pixel_length},
axis_y::{draw_y_axis, draw_y_axis_scale_markings, get_y_axis_pixel_length},
};
use super::quadrants::Quadrants;
pub mod axis_x;
pub mod axis_y;
#[allow(clippy::too_many_arguments)]
pub fn get_xy_axis_pixel_min_max(
quadrants: &Quadrants,
vertical_pixels_from_top: u32,
horizontal_pixels_from_right: u32,
vertical_pixels_from_bottom: u32,
horizontal_pixels_from_left: u32,
canvas_size: (u32, u32),
x_axis_resolution: u32,
y_axis_resolution: u32,
) -> ((u32, u32), (u32, u32)) {
match quadrants {
Quadrants::RightPair => {
let minimum_possible_x = horizontal_pixels_from_left;
let maximum_possible_x = canvas_size.0 - horizontal_pixels_from_right;
let mut x = maximum_possible_x;
'outer_x_rp: for i in 0..maximum_possible_x {
if get_x_axis_pixel_length(minimum_possible_x, x - i) % x_axis_resolution == 0 {
x -= i;
break 'outer_x_rp;
}
}
let minimum_possible_y = vertical_pixels_from_top;
let maximum_possible_y = canvas_size.1 - vertical_pixels_from_bottom;
let mut y1 = minimum_possible_y;
let y0 = maximum_possible_y;
'outer_y_rp: for i in 0..minimum_possible_y {
if get_y_axis_pixel_length(y1 + i, maximum_possible_y) / 2 % y_axis_resolution == 0
&& get_y_axis_pixel_length(y1 + i, maximum_possible_y) / 2 % 2 == 0
{
y1 += i;
break 'outer_y_rp;
}
}
((minimum_possible_x, y0), (x, y1))
}
Quadrants::LeftPair => {
let minimum_possible_x = horizontal_pixels_from_left;
let maximum_possible_x = canvas_size.0 - horizontal_pixels_from_right;
let mut x = maximum_possible_x;
'outer_x_lp: for i in 0..maximum_possible_x {
if get_x_axis_pixel_length(minimum_possible_x, x - i) % x_axis_resolution == 0 {
x -= i;
break 'outer_x_lp;
}
}
let minimum_possible_y = vertical_pixels_from_top;
let maximum_possible_y = canvas_size.1 - vertical_pixels_from_bottom;
let mut y1 = minimum_possible_y;
let y0 = maximum_possible_y;
'outer_y_lp: for i in 0..minimum_possible_y {
if get_y_axis_pixel_length(y1 + i, maximum_possible_y) / 2 % y_axis_resolution == 0
{
y1 += i;
break 'outer_y_lp;
}
}
((minimum_possible_x, y0), (x, y1))
}
Quadrants::TopPair => {
let minimum_possible_x = horizontal_pixels_from_left;
let maximum_possible_x = canvas_size.0 - horizontal_pixels_from_right;
let mut x0 = minimum_possible_x;
let x1 = maximum_possible_x;
'outer_x_tp: for i in 0..maximum_possible_x {
if get_x_axis_pixel_length(x0 + i, maximum_possible_x) / 2 % x_axis_resolution == 0
{
x0 += i;
break 'outer_x_tp;
}
}
let minimum_possible_y = vertical_pixels_from_top;
let maximum_possible_y = canvas_size.1 - vertical_pixels_from_bottom;
let mut y = minimum_possible_y;
'outer_y_tp: for i in 0..minimum_possible_y {
if get_y_axis_pixel_length(y + i, maximum_possible_y) % y_axis_resolution == 0 {
y += i;
break 'outer_y_tp;
}
}
((x0, maximum_possible_y), (x1, y))
}
Quadrants::BottomPair => {
let minimum_possible_x = horizontal_pixels_from_left;
let maximum_possible_x = canvas_size.0 - horizontal_pixels_from_right;
let mut x0 = minimum_possible_x;
let x1 = maximum_possible_x;
'outer_x_bp: for i in 0..maximum_possible_x {
if get_x_axis_pixel_length(x0 + i, maximum_possible_x) / 2 % x_axis_resolution == 0
{
x0 += i;
break 'outer_x_bp;
}
}
let minimum_possible_y = vertical_pixels_from_top;
let maximum_possible_y = canvas_size.1 - vertical_pixels_from_bottom;
let mut y = minimum_possible_y;
'outer_y_bp: for i in 0..maximum_possible_y {
if get_y_axis_pixel_length(y + i, maximum_possible_y) % y_axis_resolution == 0 {
y += i;
break 'outer_y_bp;
}
}
((x0, maximum_possible_y), (x1, y))
}
Quadrants::AllQuadrants => {
let minimum_possible_x = horizontal_pixels_from_left;
let maximum_possible_x = canvas_size.0 - horizontal_pixels_from_right;
let mut x0 = minimum_possible_x;
let x1 = maximum_possible_x;
'outer_x0: for i in 0..maximum_possible_x {
if get_x_axis_pixel_length(x0 + i, maximum_possible_x) / 2 % x_axis_resolution == 0
{
x0 += i;
break 'outer_x0;
}
}
let minimum_possible_y = vertical_pixels_from_top;
let maximum_possible_y = canvas_size.1 - vertical_pixels_from_bottom;
let mut y1 = minimum_possible_y;
let y0 = maximum_possible_y;
'outer_y1: for i in 0..minimum_possible_y {
if get_y_axis_pixel_length(y1 + i, maximum_possible_y) / 2 % y_axis_resolution == 0
&& get_y_axis_pixel_length(y1 + i, maximum_possible_y) / 2 % 2 == 0
{
y1 += i;
break 'outer_y1;
}
}
((x0, y0), (x1, y1))
}
Quadrants::TopRight => {
let minimum_possible_x = horizontal_pixels_from_left;
let maximum_possible_x = canvas_size.0 - horizontal_pixels_from_right;
let mut x = maximum_possible_x;
'outer_x: for i in 0..maximum_possible_x {
if get_x_axis_pixel_length(minimum_possible_x, x - i) % x_axis_resolution == 0 {
x -= i;
break 'outer_x;
}
}
let minimum_possible_y = vertical_pixels_from_top;
let maximum_possible_y = canvas_size.1 - vertical_pixels_from_bottom;
let mut y = minimum_possible_y;
'outer_y: for i in 0..minimum_possible_y {
if get_y_axis_pixel_length(y + i, maximum_possible_y) % y_axis_resolution == 0 {
y += i;
break 'outer_y;
}
}
((minimum_possible_x, maximum_possible_y), (x, y))
}
Quadrants::TopLeft => {
let minimum_possible_x = horizontal_pixels_from_left;
let maximum_possible_x = canvas_size.0 - horizontal_pixels_from_right;
let mut x = minimum_possible_x;
'outer_x_tl: for i in 0..maximum_possible_x {
if get_x_axis_pixel_length(x + i, maximum_possible_x) % x_axis_resolution == 0 {
x += i;
break 'outer_x_tl;
}
}
let minimum_possible_y = vertical_pixels_from_top;
let maximum_possible_y = canvas_size.1 - vertical_pixels_from_bottom;
let mut y = minimum_possible_y;
'outer_y_tl: for i in 0..minimum_possible_y {
if get_y_axis_pixel_length(y + i, maximum_possible_y) % y_axis_resolution == 0 {
y += i;
break 'outer_y_tl;
}
}
((x, maximum_possible_y), (maximum_possible_x, y))
}
Quadrants::BottomRight => {
let minimum_possible_x = horizontal_pixels_from_left;
let maximum_possible_x = canvas_size.0 - horizontal_pixels_from_right;
let mut x = maximum_possible_x;
'outer_x_br: for i in 0..maximum_possible_x {
if get_x_axis_pixel_length(minimum_possible_x, x - i) % x_axis_resolution == 0 {
x -= i;
break 'outer_x_br;
}
}
let minimum_possible_y = vertical_pixels_from_top;
let maximum_possible_y = canvas_size.1 - vertical_pixels_from_bottom;
let mut y = minimum_possible_y;
'outer_y_br: for i in 0..maximum_possible_y {
if get_y_axis_pixel_length(y + i, maximum_possible_y) % y_axis_resolution == 0 {
y += i;
break 'outer_y_br;
}
}
((minimum_possible_x, maximum_possible_y), (x, y))
}
Quadrants::BottomLeft => {
let minimum_possible_x = horizontal_pixels_from_left;
let maximum_possible_x = canvas_size.0 - horizontal_pixels_from_right;
let mut x = maximum_possible_x;
'outer_x_bl: for i in 0..maximum_possible_x {
if get_x_axis_pixel_length(minimum_possible_x, x - i) % x_axis_resolution == 0 {
x -= i;
break 'outer_x_bl;
}
}
let minimum_possible_y = vertical_pixels_from_top;
let maximum_possible_y = canvas_size.1 - vertical_pixels_from_bottom;
let mut y = minimum_possible_y;
'outer_y_bl: for i in 0..maximum_possible_y {
if get_y_axis_pixel_length(y + i, maximum_possible_y) % y_axis_resolution == 0 {
y += i;
break 'outer_y_bl;
}
}
((minimum_possible_x, maximum_possible_y), (x, y))
}
}
}
pub fn get_xy_axis_pixel_origin(
quadrants: &Quadrants,
axis_min: (u32, u32),
axis_max: (u32, u32),
) -> (u32, u32) {
match quadrants {
Quadrants::RightPair => {
let y_l = get_y_axis_pixel_length(axis_max.1, axis_min.1);
let y_o = axis_max.1 + y_l / 2;
(axis_min.0, y_o)
}
Quadrants::LeftPair => {
let y_l = get_y_axis_pixel_length(axis_max.1, axis_min.1);
let y_o = axis_max.1 + y_l / 2;
(axis_max.0, y_o)
}
Quadrants::TopPair => {
let x_l = get_x_axis_pixel_length(axis_min.0, axis_max.0);
let x_o = axis_min.0 + x_l / 2;
(x_o, axis_min.1)
}
Quadrants::BottomPair => {
let x_l = get_x_axis_pixel_length(axis_min.0, axis_max.0);
let x_o = axis_min.0 + x_l / 2;
(x_o, axis_max.1)
}
Quadrants::AllQuadrants => {
let x_l = get_x_axis_pixel_length(axis_min.0, axis_max.0);
let x_o = axis_min.0 + x_l / 2;
let y_l = get_y_axis_pixel_length(axis_max.1, axis_min.1);
let y_o = axis_max.1 + y_l / 2;
(x_o, y_o)
}
Quadrants::TopRight => {
let gradient = (axis_min.1 - axis_max.1) / (axis_max.0 - axis_min.0);
let intercept = axis_min.1 - (gradient * axis_min.0);
let pixel_origin_y = gradient * axis_min.0 + intercept;
(axis_min.0, pixel_origin_y)
}
Quadrants::TopLeft => {
let gradient = (axis_min.1 - axis_max.1) / (axis_max.0 - axis_min.0);
let intercept = axis_min.1 - (gradient * axis_min.0);
let pixel_origin_y = gradient * axis_max.0 + intercept;
(axis_max.0, pixel_origin_y)
}
Quadrants::BottomRight => (axis_min.0, axis_max.1),
Quadrants::BottomLeft => (axis_max.0, axis_max.1),
}
}
#[allow(clippy::too_many_arguments)]
pub fn draw_xy_axes(
quadrants: &Quadrants,
canvas: &mut ImageBuffer<Rgba<u8>, Vec<u8>>,
axis_origin_pixel: (u32, u32),
axis_min_pixel: (u32, u32),
axis_max_pixel: (u32, u32),
x_axis_length: u32,
y_axis_length: u32,
x_data_min_max_limits: (i32, i32),
y_data_min_max_limits: (i32, i32),
font_size: f32,
has_grid: bool,
x_axis_resolution: u32,
y_axis_resolution: u32,
) {
draw_x_axis_scale_markings(
quadrants,
canvas,
axis_min_pixel,
axis_origin_pixel,
axis_max_pixel,
x_axis_length,
x_data_min_max_limits,
font_size,
has_grid,
x_axis_resolution,
);
draw_y_axis_scale_markings(
quadrants,
canvas,
axis_min_pixel,
axis_origin_pixel,
axis_max_pixel,
y_axis_length,
y_data_min_max_limits,
font_size,
has_grid,
y_axis_resolution,
);
draw_x_axis(canvas, axis_min_pixel, axis_origin_pixel, axis_max_pixel);
draw_y_axis(canvas, axis_min_pixel, axis_origin_pixel, axis_max_pixel);
}