renew file structure
This commit is contained in:
parent
fc6f2c8ebe
commit
0b0821a803
@ -7,3 +7,4 @@ edition = "2021"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
meval = "0.2.0"
|
meval = "0.2.0"
|
||||||
|
image = "0.24.8"
|
||||||
|
|||||||
BIN
grid_image.png
Normal file
BIN
grid_image.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 747 KiB |
149
src/function.rs
Normal file
149
src/function.rs
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
pub fn default_points(points: &mut [[f64;2];3]) {
|
||||||
|
if points.iter().all(|row| row.iter().all(|&x| x == 0.0)) {
|
||||||
|
*points = [[-1.0,1.0], [2.0,4.0], [3.0,9.0]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn group_by_x(arr: &mut [[f64;2];3]) {
|
||||||
|
arr.sort_by(|a, b| a[0].partial_cmp(&b[0]).unwrap_or(std::cmp::Ordering::Equal));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_points(args: Vec<String>) -> [[f64;2];3] {
|
||||||
|
let mut points: [[f64; 2]; 3] = [[0.0; 2]; 3];
|
||||||
|
|
||||||
|
for (i, part) in args.iter().enumerate().take(3) {
|
||||||
|
let values: Vec<f64> = part
|
||||||
|
.split(':')
|
||||||
|
.filter_map(|s| s.parse().ok())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
if values.len() == 2 {
|
||||||
|
points[i][0] = values[0];
|
||||||
|
points[i][1] = values[1];
|
||||||
|
} else {
|
||||||
|
println!("Invalid input format: {}", part);
|
||||||
|
println!("Usage: $0 -1:1 3:-5 10:1.5")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
default_points(&mut points);
|
||||||
|
|
||||||
|
points
|
||||||
|
}
|
||||||
|
|
||||||
|
fn nearest_to_zero(arr: &[[f64;2];3]) -> usize {
|
||||||
|
let mut nearest = arr[1][1];
|
||||||
|
let mut nearest_index = 0;
|
||||||
|
for (i, point) in arr.iter().enumerate() {
|
||||||
|
if nearest < point[1].abs() {
|
||||||
|
nearest = point[i-1];
|
||||||
|
nearest_index = i-1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nearest_index
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn straight_string(m: f64, points: &[[f64;2];3]) -> String {
|
||||||
|
format!(
|
||||||
|
"{}x{}",
|
||||||
|
if m != 1.0 {
|
||||||
|
format!("{} * ", m)
|
||||||
|
} else {
|
||||||
|
"".to_string()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
let lowest_y = nearest_to_zero(points);
|
||||||
|
let result = points[lowest_y][0] - points[lowest_y][1] * m;
|
||||||
|
if result != 0.0 {
|
||||||
|
format!(
|
||||||
|
"{}{}",
|
||||||
|
if result < 0.0 {
|
||||||
|
" - ".to_string()
|
||||||
|
} else {
|
||||||
|
" + ".to_string()
|
||||||
|
},
|
||||||
|
result.abs()
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
"".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn square_string(points: &[[f64;2];3]) -> String {
|
||||||
|
let a = -((points[0][0] * points[1][1] -
|
||||||
|
points[0][0] * points[2][1] -
|
||||||
|
points[1][0] * points[0][1] +
|
||||||
|
points[1][0] * points[2][1] +
|
||||||
|
points[2][0] * points[0][1] -
|
||||||
|
points[2][0] * points[1][1])
|
||||||
|
/
|
||||||
|
((points[0][0] - points[1][0]) *
|
||||||
|
(points[0][0] - points[2][0]) *
|
||||||
|
(points[1][0] - points[2][0])));
|
||||||
|
|
||||||
|
let b = (points[0][0].powi(2) * points[1][1] -
|
||||||
|
points[0][0].powi(2) * points[2][1] -
|
||||||
|
points[1][0].powi(2) * points[0][1] +
|
||||||
|
points[1][0].powi(2) * points[2][1] +
|
||||||
|
points[2][0].powi(2) * points[0][1] -
|
||||||
|
points[2][0].powi(2) * points[1][1])
|
||||||
|
/
|
||||||
|
((points[0][0] - points[1][0]) *
|
||||||
|
(points[0][0] - points[2][0]) *
|
||||||
|
(points[1][0] - points[2][0]));
|
||||||
|
|
||||||
|
let c = (points[0][0].powi(2) * points[1][0] * points[2][1] -
|
||||||
|
points[0][0].powi(2) * points[2][0] * points[1][1] -
|
||||||
|
points[0][0] * points[1][0].powi(2) * points[2][1] +
|
||||||
|
points[0][0] * points[2][0].powi(2) * points[1][1] +
|
||||||
|
points[1][0].powi(2) * points[2][0] * points[0][1] -
|
||||||
|
points[1][0] * points[2][0].powi(2) * points[0][1])
|
||||||
|
/
|
||||||
|
((points[0][0] - points[1][0]) *
|
||||||
|
(points[0][0] - points[2][0]) *
|
||||||
|
(points[1][0] - points[2][0]));
|
||||||
|
|
||||||
|
format!(
|
||||||
|
"{}x^2{}{}",
|
||||||
|
if a == -1.0 {
|
||||||
|
"-".to_string()
|
||||||
|
} else if a != 1.0 {
|
||||||
|
format!("{}{}", a, " * ")
|
||||||
|
} else {
|
||||||
|
"".to_string()
|
||||||
|
},
|
||||||
|
if b != 0.0 {
|
||||||
|
format!(
|
||||||
|
"{}{}",
|
||||||
|
if b < 0.0 {
|
||||||
|
" - ".to_string()
|
||||||
|
} else {
|
||||||
|
" + ".to_string()
|
||||||
|
},
|
||||||
|
if b != 1.0 {
|
||||||
|
format!("{} * x", b.abs())
|
||||||
|
} else {
|
||||||
|
"x".to_string()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
"".to_string()
|
||||||
|
},
|
||||||
|
if c != 0.0 {
|
||||||
|
format!(
|
||||||
|
"{}{}",
|
||||||
|
if c < 0.0 {
|
||||||
|
" - ".to_string()
|
||||||
|
} else {
|
||||||
|
" + ".to_string()
|
||||||
|
},
|
||||||
|
c.abs()
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
"".to_string()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
21
src/image.rs
Normal file
21
src/image.rs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
use image::{ImageBuffer, RgbImage, Rgb};
|
||||||
|
|
||||||
|
pub fn get_image(width: u32, height: u32) -> ImageBuffer<Rgb<u8>, Vec<u8>> {
|
||||||
|
let mut img = RgbImage::new(width, height);
|
||||||
|
let grid_spacing = 100;
|
||||||
|
let grid_color = Rgb([255,9,255]);
|
||||||
|
|
||||||
|
for x in (0..width).step_by(grid_spacing) {
|
||||||
|
for y in 0..height {
|
||||||
|
img.put_pixel(x, y, grid_color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for y in (0..height).step_by(grid_spacing) {
|
||||||
|
for x in 0..width {
|
||||||
|
img.put_pixel(x, y, grid_color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
img
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
182
src/main.rs
182
src/main.rs
@ -1,27 +1,13 @@
|
|||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
|
mod function;
|
||||||
|
mod image;
|
||||||
|
use crate::function::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let args: Vec<String> = env::args().skip(1).take(3).collect();
|
let args: Vec<String> = env::args().skip(1).take(3).collect();
|
||||||
let mut points: [[f64; 2]; 3] = [[0.0; 2]; 3];
|
|
||||||
|
|
||||||
for (i, part) in args.iter().enumerate().take(3) {
|
|
||||||
let values: Vec<f64> = part
|
|
||||||
.split(':')
|
|
||||||
.filter_map(|s| s.parse().ok())
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
if values.len() == 2 {
|
|
||||||
points[i][0] = values[0];
|
|
||||||
points[i][1] = values[1];
|
|
||||||
} else {
|
|
||||||
println!("Invalid input format: {}", part);
|
|
||||||
println!("Usage: $0 -1:1 3:-5 10:1.5")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
default_points(&mut points);
|
|
||||||
|
|
||||||
|
let mut points = get_points(args);
|
||||||
group_by_x(&mut points);
|
group_by_x(&mut points);
|
||||||
|
|
||||||
let m1 = (points[0][1] - points[1][1]) / (points[0][0] - points[1][0]);
|
let m1 = (points[0][1] - points[1][1]) / (points[0][0] - points[1][0]);
|
||||||
@ -34,135 +20,53 @@ fn main() {
|
|||||||
if function.contains("NaN") {
|
if function.contains("NaN") {
|
||||||
panic!("Contains NaN, this is probably the result of bad math");
|
panic!("Contains NaN, this is probably the result of bad math");
|
||||||
}
|
}
|
||||||
// let expr2 = tokenize(function.as_str()).unwrap();
|
|
||||||
// println!("{:?}", expr2);
|
|
||||||
let rust_function = function.parse::<meval::Expr>().unwrap().bind("x").unwrap();
|
let rust_function = function.parse::<meval::Expr>().unwrap().bind("x").unwrap();
|
||||||
let result = rust_function(9.0);
|
let result = rust_function(9.0);
|
||||||
println!("{}", result);
|
println!("{}", result);
|
||||||
}
|
|
||||||
|
|
||||||
fn default_points(points: &mut [[f64;2];3]) {
|
/*
|
||||||
if points.iter().all(|row| row.iter().all(|&x| x == 0.0)) {
|
let width = 7000;
|
||||||
*points = [[-1.0,1.0], [2.0,4.0], [3.0,9.0]];
|
let height = 7000;
|
||||||
|
let color = [255, 0, 0];
|
||||||
|
let mut img = get_image(4000, 4000);
|
||||||
|
let step: f64 = format!("0.{}1", "0".repeat(6)).parse().unwrap();
|
||||||
|
let mut points = vec![];
|
||||||
|
|
||||||
|
let mut i = 0.0;
|
||||||
|
while i <= 3.0 {
|
||||||
|
points.push(i);
|
||||||
|
i += step;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn group_by_x(arr: &mut [[f64;2];3]) {
|
|
||||||
arr.sort_by(|a, b| a[0].partial_cmp(&b[0]).unwrap_or(std::cmp::Ordering::Equal));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn nearest_to_zero(arr: &[[f64;2];3]) -> usize {
|
// println!("{points:?}");
|
||||||
let mut nearest = arr[1][1];
|
|
||||||
let mut nearest_index = 0;
|
|
||||||
for (i, point) in arr.iter().enumerate() {
|
let mut x;
|
||||||
if nearest < point[1].abs() {
|
let mut y;
|
||||||
nearest = point[i-1];
|
// let mut x_result_tmp;
|
||||||
nearest_index = i-1;
|
// let mut y_result_tmp;
|
||||||
|
for point in points {
|
||||||
|
// NOTE: convert later to u32 because deviding may change actual value
|
||||||
|
x = point * 1000.0_f64;
|
||||||
|
y = rust_function(point) * 1000.0;
|
||||||
|
if width as f64 / 2.0 + y < (width - 5) as f64 {
|
||||||
|
img.put_pixel(
|
||||||
|
(width as f64 / 2.0 + x).round() as u32,
|
||||||
|
(height as f64 / 2.0 - y) as u32,
|
||||||
|
Rgb(color)
|
||||||
|
);
|
||||||
|
img.put_pixel(
|
||||||
|
(width as f64 / 2.0 - x).round() as u32,
|
||||||
|
(height as f64 / 2.0 - y).round() as u32,
|
||||||
|
Rgb(color)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nearest_index
|
|
||||||
|
img.save("grid_image.png").expect("Failed to save image");
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
fn straight_string(m: f64, points: &[[f64;2];3]) -> String {
|
|
||||||
format!(
|
|
||||||
"{}x{}",
|
|
||||||
if m != 1.0 {
|
|
||||||
format!("{} * ", m)
|
|
||||||
} else {
|
|
||||||
"".to_string()
|
|
||||||
},
|
|
||||||
{
|
|
||||||
let lowest_y = nearest_to_zero(points);
|
|
||||||
let result = points[lowest_y][0] - points[lowest_y][1] * m;
|
|
||||||
if result != 0.0 {
|
|
||||||
format!(
|
|
||||||
"{}{}",
|
|
||||||
if result < 0.0 {
|
|
||||||
" - ".to_string()
|
|
||||||
} else {
|
|
||||||
" + ".to_string()
|
|
||||||
},
|
|
||||||
result.abs()
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
"".to_string()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn square_string(points: &[[f64;2];3]) -> String {
|
|
||||||
let a = -((points[0][0] * points[1][1] -
|
|
||||||
points[0][0] * points[2][1] -
|
|
||||||
points[1][0] * points[0][1] +
|
|
||||||
points[1][0] * points[2][1] +
|
|
||||||
points[2][0] * points[0][1] -
|
|
||||||
points[2][0] * points[1][1])
|
|
||||||
/
|
|
||||||
((points[0][0] - points[1][0]) *
|
|
||||||
(points[0][0] - points[2][0]) *
|
|
||||||
(points[1][0] - points[2][0])));
|
|
||||||
|
|
||||||
let b = (points[0][0].powi(2) * points[1][1] -
|
|
||||||
points[0][0].powi(2) * points[2][1] -
|
|
||||||
points[1][0].powi(2) * points[0][1] +
|
|
||||||
points[1][0].powi(2) * points[2][1] +
|
|
||||||
points[2][0].powi(2) * points[0][1] -
|
|
||||||
points[2][0].powi(2) * points[1][1])
|
|
||||||
/
|
|
||||||
((points[0][0] - points[1][0]) *
|
|
||||||
(points[0][0] - points[2][0]) *
|
|
||||||
(points[1][0] - points[2][0]));
|
|
||||||
|
|
||||||
let c = (points[0][0].powi(2) * points[1][0] * points[2][1] -
|
|
||||||
points[0][0].powi(2) * points[2][0] * points[1][1] -
|
|
||||||
points[0][0] * points[1][0].powi(2) * points[2][1] +
|
|
||||||
points[0][0] * points[2][0].powi(2) * points[1][1] +
|
|
||||||
points[1][0].powi(2) * points[2][0] * points[0][1] -
|
|
||||||
points[1][0] * points[2][0].powi(2) * points[0][1])
|
|
||||||
/
|
|
||||||
((points[0][0] - points[1][0]) *
|
|
||||||
(points[0][0] - points[2][0]) *
|
|
||||||
(points[1][0] - points[2][0]));
|
|
||||||
|
|
||||||
format!(
|
|
||||||
"{}x^2{}{}",
|
|
||||||
if a == -1.0 {
|
|
||||||
"-".to_string()
|
|
||||||
} else if a != 1.0 {
|
|
||||||
format!("{}{}", a, " * ")
|
|
||||||
} else {
|
|
||||||
"".to_string()
|
|
||||||
},
|
|
||||||
if b != 0.0 {
|
|
||||||
format!(
|
|
||||||
"{}{}",
|
|
||||||
if b < 0.0 {
|
|
||||||
" - ".to_string()
|
|
||||||
} else {
|
|
||||||
" + ".to_string()
|
|
||||||
},
|
|
||||||
if b != 1.0 {
|
|
||||||
format!("{} * x", b.abs())
|
|
||||||
} else {
|
|
||||||
"x".to_string()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
"".to_string()
|
|
||||||
},
|
|
||||||
if c != 0.0 {
|
|
||||||
format!(
|
|
||||||
"{}{}",
|
|
||||||
if c < 0.0 {
|
|
||||||
" - ".to_string()
|
|
||||||
} else {
|
|
||||||
" + ".to_string()
|
|
||||||
},
|
|
||||||
c.abs()
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
"".to_string()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user