Browse Source

Add rotation to ngons

main
raffitz 3 years ago
parent
commit
8d63fb2103
Signed by: raffitz
GPG Key ID: BB3596BD0A31252D
  1. 2
      Cargo.lock
  2. 2
      Cargo.toml
  3. 8
      src/astree.rs
  4. 72
      src/main.rs
  5. 81
      src/ngon.rs

2
Cargo.lock generated

@ -311,7 +311,7 @@ checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
[[package]] [[package]]
name = "voxelmap" name = "voxelmap"
version = "0.4.0" version = "0.4.2"
dependencies = [ dependencies = [
"clap", "clap",
"lodepng", "lodepng",

2
Cargo.toml

@ -1,6 +1,6 @@
[package] [package]
name = "voxelmap" name = "voxelmap"
version = "0.4.0" version = "0.4.2"
authors = ["raffitz <raf.a.m.c.gon@gmail.com>"] authors = ["raffitz <raf.a.m.c.gon@gmail.com>"]
edition = "2018" edition = "2018"
description = "Creates voxel maps to build voxelised objects" description = "Creates voxel maps to build voxelised objects"

8
src/astree.rs

@ -2,7 +2,7 @@ use crate::error::Error;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::io::Write; use std::io::Write;
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq, Clone)]
pub enum FunctionType { pub enum FunctionType {
Sin, Sin,
Cos, Cos,
@ -22,7 +22,7 @@ pub enum FunctionType {
Neg, Neg,
} }
#[derive(Debug)] #[derive(Debug, Clone)]
pub struct FunctionData { pub struct FunctionData {
kind: FunctionType, kind: FunctionType,
arg: Box<Expression>, arg: Box<Expression>,
@ -91,7 +91,7 @@ impl FunctionData {
} }
} }
#[derive(Debug)] #[derive(Debug, Clone)]
pub struct OperationData { pub struct OperationData {
kind: char, kind: char,
left: Box<Expression>, left: Box<Expression>,
@ -142,7 +142,7 @@ impl OperationData {
} }
} }
#[derive(Debug)] #[derive(Debug, Clone)]
pub enum Expression { pub enum Expression {
Var(char), Var(char),
Float(f64), Float(f64),

72
src/main.rs

@ -11,15 +11,9 @@ mod error;
mod ngon; mod ngon;
mod parser; mod parser;
macro_rules! scale_message { macro_rules! value_message {
($n:ident) => { ($n:ident, $t:expr) => {
Err(format!("<{}> is not a valid scale value", $n)) Err(format!("<{}> is not a valid {}", $n, $t))
};
}
macro_rules! sides_message {
($n:ident) => {
Err(format!("<{}> is not a valid number of sides", $n))
}; };
} }
@ -59,7 +53,7 @@ fn main() -> Result<(), error::Error> {
return Ok(()); return Ok(());
} }
} }
scale_message!(n) value_message!(n,"scale value")
}), }),
) )
.arg( .arg(
@ -128,6 +122,39 @@ fn main() -> Result<(), error::Error> {
) )
.subcommand(SubCommand::with_name("ngon") .subcommand(SubCommand::with_name("ngon")
.about("Make an ngon") .about("Make an ngon")
.arg(
Arg::with_name("angle")
.short("a")
.long("angle")
.help("Angle in radians by which to rotate the ngon")
.takes_value(true)
.multiple(false)
.value_name("RAD")
.validator(|n: String| -> Result<(), String> {
if n.parse::<f64>().is_err() {
value_message!(n,"angle in radians")
}else{
Ok(())
}
}),
)
.arg(
Arg::with_name("degrees")
.short("e")
.long("degrees")
.help("Angle in degrees by which to rotate the ngon")
.conflicts_with("angle")
.takes_value(true)
.multiple(false)
.value_name("DEG")
.validator(|n: String| -> Result<(), String> {
if n.parse::<f64>().is_err() {
value_message!(n,"angle in degrees")
}else{
Ok(())
}
}),
)
.arg( .arg(
Arg::with_name("N") Arg::with_name("N")
.help("The number of sides of the ngon") .help("The number of sides of the ngon")
@ -139,7 +166,7 @@ fn main() -> Result<(), error::Error> {
return Ok(()); return Ok(());
} }
} }
sides_message!(n) value_message!(n,"number of sides")
}), }),
) )
.arg( .arg(
@ -240,12 +267,33 @@ fn main() -> Result<(), error::Error> {
debug, debug,
)?; )?;
} else if let Some(submatches) = matches.subcommand_matches("ngon") { } else if let Some(submatches) = matches.subcommand_matches("ngon") {
let mut labels = HashMap::new();
let angleident;
if let Some(value) = submatches.value_of("angle") {
let angle_exp = astree::Expression::float(value.parse::<f64>().unwrap());
labels.insert(String::from("@clangle"), angle_exp);
angleident = Some(String::from("@clangle"));
} else if let Some(value) = submatches.value_of("degrees") {
let angle_exp = astree::Expression::float(value.parse::<f64>().unwrap().to_radians());
labels.insert(String::from("@clangle"), angle_exp);
angleident = Some(String::from("@clangle"));
} else {
angleident = None;
}
output_folder = submatches.value_of("OUTPUT_DIR").unwrap_or(output_folder); output_folder = submatches.value_of("OUTPUT_DIR").unwrap_or(output_folder);
structure = ngon::generate( structure = ngon::generate::<String, f64>(
submatches submatches
.value_of("N") .value_of("N")
.map(|n| n.parse::<u8>().unwrap()) .map(|n| n.parse::<u8>().unwrap())
.unwrap(), .unwrap(),
None,
None,
None,
angleident,
None,
Some(labels),
)?; )?;
} else { } else {
println!("{}", matches.usage()); println!("{}", matches.usage());

81
src/ngon.rs

@ -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()),

Loading…
Cancel
Save