|
|
@ -3,29 +3,49 @@ use crate::astree::{Boundaries, Boundary, Condition, Expression, FunctionType, J |
|
|
|
use crate::error; |
|
|
|
use crate::error; |
|
|
|
use std::collections::HashMap; |
|
|
|
use std::collections::HashMap; |
|
|
|
|
|
|
|
|
|
|
|
pub fn generate(n: u8) -> Result<astree::Structure, error::Error> { |
|
|
|
pub fn generate<T: Into<String> + Clone, S: Into<f64> + Copy>( |
|
|
|
|
|
|
|
n: u8, |
|
|
|
|
|
|
|
prefix_val: Option<T>, |
|
|
|
|
|
|
|
x_offset: Option<T>, |
|
|
|
|
|
|
|
y_offset: Option<T>, |
|
|
|
|
|
|
|
angle_offset: Option<T>, |
|
|
|
|
|
|
|
scale: Option<S>, |
|
|
|
|
|
|
|
previous_labels: Option<HashMap<String, Expression>>, |
|
|
|
|
|
|
|
) -> Result<astree::Structure, error::Error> { |
|
|
|
|
|
|
|
let prefix = if let Some(val) = prefix_val { |
|
|
|
|
|
|
|
val.into() |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
"".to_string() |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
let mut junctions = Vec::<Junction>::with_capacity(n as usize); |
|
|
|
let mut junctions = Vec::<Junction>::with_capacity(n as usize); |
|
|
|
|
|
|
|
|
|
|
|
let mut labels = HashMap::<String, Expression>::new(); |
|
|
|
let mut labels = previous_labels.unwrap_or_default(); |
|
|
|
let mut vars = HashMap::<char, f64>::new(); |
|
|
|
let mut vars = HashMap::<char, f64>::new(); |
|
|
|
vars.insert('s', 1_f64); |
|
|
|
vars.insert('s', 1_f64); |
|
|
|
let vars_eval = Some(&vars); |
|
|
|
let vars_eval = Some(&vars); |
|
|
|
|
|
|
|
|
|
|
|
let double_n: u16 = (n as u16) * 2; |
|
|
|
let double_n: u16 = (n as u16) * 2; |
|
|
|
|
|
|
|
|
|
|
|
let mut min_x = 1_f64; |
|
|
|
let mut min_x = f64::MAX; |
|
|
|
let mut min_x_label = String::from("error"); |
|
|
|
let mut min_x_label = String::from("error"); |
|
|
|
let mut max_x = -1_f64; |
|
|
|
let mut max_x = f64::MIN; |
|
|
|
let mut max_x_label = String::from("error"); |
|
|
|
let mut max_x_label = String::from("error"); |
|
|
|
|
|
|
|
|
|
|
|
let mut min_y = 1_f64; |
|
|
|
let mut min_y = f64::MAX; |
|
|
|
let mut min_y_label = String::from("error"); |
|
|
|
let mut min_y_label = String::from("error"); |
|
|
|
let mut max_y = -1_f64; |
|
|
|
let mut max_y = f64::MIN; |
|
|
|
let mut max_y_label = String::from("error"); |
|
|
|
let mut max_y_label = String::from("error"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let multiplier = if let Some(new_scale) = scale { |
|
|
|
|
|
|
|
Expression::operation('*', Expression::var('s'), Expression::float(new_scale)) |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
Expression::var('s') |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
for i in 0..n { |
|
|
|
for i in 0..n { |
|
|
|
let angle_label = format!("@angle{}", i); |
|
|
|
let angle_label = format!("@{}angle{}", prefix, i); |
|
|
|
let angle_exp = Expression::operation( |
|
|
|
let angle_inner = Expression::operation( |
|
|
|
'/', |
|
|
|
'/', |
|
|
|
Expression::operation( |
|
|
|
Expression::operation( |
|
|
|
'*', |
|
|
|
'*', |
|
|
@ -34,19 +54,32 @@ pub fn generate(n: u8) -> Result<astree::Structure, error::Error> { |
|
|
|
), |
|
|
|
), |
|
|
|
Expression::float(n), |
|
|
|
Expression::float(n), |
|
|
|
); |
|
|
|
); |
|
|
|
|
|
|
|
let angle_offset_clone = angle_offset.clone(); |
|
|
|
|
|
|
|
let angle_exp = if let Some(ident) = angle_offset_clone { |
|
|
|
|
|
|
|
Expression::operation('+', Expression::ident(ident.into()), angle_inner) |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
angle_inner |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
labels.insert(angle_label.to_string(), angle_exp); |
|
|
|
labels.insert(angle_label.to_string(), angle_exp); |
|
|
|
|
|
|
|
|
|
|
|
let idents = Some(&labels); |
|
|
|
let idents = Some(&labels); |
|
|
|
|
|
|
|
|
|
|
|
let x_label = format!("@x{}", i); |
|
|
|
let x_label = format!("@{}x{}", prefix, i); |
|
|
|
let x_exp = Expression::operation( |
|
|
|
let x_base = Expression::operation( |
|
|
|
'*', |
|
|
|
'*', |
|
|
|
Expression::var('s'), |
|
|
|
multiplier.clone(), |
|
|
|
Expression::function( |
|
|
|
Expression::function( |
|
|
|
FunctionType::Cos, |
|
|
|
FunctionType::Cos, |
|
|
|
Expression::ident(angle_label.to_string()), |
|
|
|
Expression::ident(angle_label.to_string()), |
|
|
|
), |
|
|
|
), |
|
|
|
); |
|
|
|
); |
|
|
|
|
|
|
|
let x_offset_clone = x_offset.clone(); |
|
|
|
|
|
|
|
let x_exp = if let Some(ident) = x_offset_clone { |
|
|
|
|
|
|
|
Expression::operation('+', x_base, Expression::ident(ident.into())) |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
x_base |
|
|
|
|
|
|
|
}; |
|
|
|
let x_val = x_exp.eval(&idents, &vars_eval)?; |
|
|
|
let x_val = x_exp.eval(&idents, &vars_eval)?; |
|
|
|
labels.insert(x_label.to_string(), x_exp); |
|
|
|
labels.insert(x_label.to_string(), x_exp); |
|
|
|
|
|
|
|
|
|
|
@ -62,15 +95,21 @@ pub fn generate(n: u8) -> Result<astree::Structure, error::Error> { |
|
|
|
|
|
|
|
|
|
|
|
let idents = Some(&labels); |
|
|
|
let idents = Some(&labels); |
|
|
|
|
|
|
|
|
|
|
|
let y_label = format!("@y{}", i); |
|
|
|
let y_label = format!("@{}y{}", prefix, i); |
|
|
|
let y_exp = Expression::operation( |
|
|
|
let y_base = Expression::operation( |
|
|
|
'*', |
|
|
|
'*', |
|
|
|
Expression::var('s'), |
|
|
|
multiplier.clone(), |
|
|
|
Expression::function( |
|
|
|
Expression::function( |
|
|
|
FunctionType::Sin, |
|
|
|
FunctionType::Sin, |
|
|
|
Expression::ident(angle_label.to_string()), |
|
|
|
Expression::ident(angle_label.to_string()), |
|
|
|
), |
|
|
|
), |
|
|
|
); |
|
|
|
); |
|
|
|
|
|
|
|
let y_offset_clone = y_offset.clone(); |
|
|
|
|
|
|
|
let y_exp = if let Some(ident) = y_offset_clone { |
|
|
|
|
|
|
|
Expression::operation('+', y_base, Expression::ident(ident.into())) |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
y_base |
|
|
|
|
|
|
|
}; |
|
|
|
let y_val = y_exp.eval(&idents, &vars_eval)?; |
|
|
|
let y_val = y_exp.eval(&idents, &vars_eval)?; |
|
|
|
labels.insert(y_label.to_string(), y_exp); |
|
|
|
labels.insert(y_label.to_string(), y_exp); |
|
|
|
|
|
|
|
|
|
|
@ -86,8 +125,8 @@ pub fn generate(n: u8) -> Result<astree::Structure, error::Error> { |
|
|
|
|
|
|
|
|
|
|
|
let normal_index: u16 = (i as u16) * 2 + 1; |
|
|
|
let normal_index: u16 = (i as u16) * 2 + 1; |
|
|
|
|
|
|
|
|
|
|
|
let normal_angle_label = format!("@nangle{}", i); |
|
|
|
let normal_angle_label = format!("@{}nangle{}", prefix, i); |
|
|
|
let normal_angle_exp = Expression::operation( |
|
|
|
let normal_angle_base = Expression::operation( |
|
|
|
'/', |
|
|
|
'/', |
|
|
|
Expression::operation( |
|
|
|
Expression::operation( |
|
|
|
'*', |
|
|
|
'*', |
|
|
@ -96,16 +135,22 @@ pub fn generate(n: u8) -> Result<astree::Structure, error::Error> { |
|
|
|
), |
|
|
|
), |
|
|
|
Expression::float(double_n), |
|
|
|
Expression::float(double_n), |
|
|
|
); |
|
|
|
); |
|
|
|
|
|
|
|
let angle_offset_clone = angle_offset.clone(); |
|
|
|
|
|
|
|
let normal_angle_exp = if let Some(ident) = angle_offset_clone { |
|
|
|
|
|
|
|
Expression::operation('+', normal_angle_base, Expression::ident(ident.into())) |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
normal_angle_base |
|
|
|
|
|
|
|
}; |
|
|
|
labels.insert(normal_angle_label.to_string(), normal_angle_exp); |
|
|
|
labels.insert(normal_angle_label.to_string(), normal_angle_exp); |
|
|
|
|
|
|
|
|
|
|
|
let normal_x_label = format!("@nx{}", i); |
|
|
|
let normal_x_label = format!("@{}nx{}", prefix, i); |
|
|
|
let normal_x_exp = Expression::function( |
|
|
|
let normal_x_exp = Expression::function( |
|
|
|
FunctionType::Cos, |
|
|
|
FunctionType::Cos, |
|
|
|
Expression::ident(normal_angle_label.to_string()), |
|
|
|
Expression::ident(normal_angle_label.to_string()), |
|
|
|
); |
|
|
|
); |
|
|
|
labels.insert(normal_x_label.to_string(), normal_x_exp); |
|
|
|
labels.insert(normal_x_label.to_string(), normal_x_exp); |
|
|
|
|
|
|
|
|
|
|
|
let normal_y_label = format!("@ny{}", i); |
|
|
|
let normal_y_label = format!("@{}ny{}", prefix, i); |
|
|
|
let normal_y_exp = Expression::function( |
|
|
|
let normal_y_exp = Expression::function( |
|
|
|
FunctionType::Sin, |
|
|
|
FunctionType::Sin, |
|
|
|
Expression::ident(normal_angle_label.to_string()), |
|
|
|
Expression::ident(normal_angle_label.to_string()), |
|
|
|