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" @@ -311,7 +311,7 @@ checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
[[package]]
name = "voxelmap"
version = "0.4.0"
version = "0.4.2"
dependencies = [
"clap",
"lodepng",

2
Cargo.toml

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

8
src/astree.rs

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

72
src/main.rs

@ -11,15 +11,9 @@ mod error; @@ -11,15 +11,9 @@ mod error;
mod ngon;
mod parser;
macro_rules! scale_message {
($n:ident) => {
Err(format!("<{}> is not a valid scale value", $n))
};
}
macro_rules! sides_message {
($n:ident) => {
Err(format!("<{}> is not a valid number of sides", $n))
macro_rules! value_message {
($n:ident, $t:expr) => {
Err(format!("<{}> is not a valid {}", $n, $t))
};
}
@ -59,7 +53,7 @@ fn main() -> Result<(), error::Error> { @@ -59,7 +53,7 @@ fn main() -> Result<(), error::Error> {
return Ok(());
}
}
scale_message!(n)
value_message!(n,"scale value")
}),
)
.arg(
@ -128,6 +122,39 @@ fn main() -> Result<(), error::Error> { @@ -128,6 +122,39 @@ fn main() -> Result<(), error::Error> {
)
.subcommand(SubCommand::with_name("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::with_name("N")
.help("The number of sides of the ngon")
@ -139,7 +166,7 @@ fn main() -> Result<(), error::Error> { @@ -139,7 +166,7 @@ fn main() -> Result<(), error::Error> {
return Ok(());
}
}
sides_message!(n)
value_message!(n,"number of sides")
}),
)
.arg(
@ -240,12 +267,33 @@ fn main() -> Result<(), error::Error> { @@ -240,12 +267,33 @@ fn main() -> Result<(), error::Error> {
debug,
)?;
} 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);
structure = ngon::generate(
structure = ngon::generate::<String, f64>(
submatches
.value_of("N")
.map(|n| n.parse::<u8>().unwrap())
.unwrap(),
None,
None,
None,
angleident,
None,
Some(labels),
)?;
} else {
println!("{}", matches.usage());

81
src/ngon.rs

@ -3,29 +3,49 @@ use crate::astree::{Boundaries, Boundary, Condition, Expression, FunctionType, J @@ -3,29 +3,49 @@ use crate::astree::{Boundaries, Boundary, Condition, Expression, FunctionType, J
use crate::error;
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 labels = HashMap::<String, Expression>::new();
let mut labels = previous_labels.unwrap_or_default();
let mut vars = HashMap::<char, f64>::new();
vars.insert('s', 1_f64);
let vars_eval = Some(&vars);
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 max_x = -1_f64;
let mut max_x = f64::MIN;
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 max_y = -1_f64;
let mut max_y = f64::MIN;
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 {
let angle_label = format!("@angle{}", i);
let angle_exp = Expression::operation(
let angle_label = format!("@{}angle{}", prefix, i);
let angle_inner = Expression::operation(
'/',
Expression::operation(
'*',
@ -34,19 +54,32 @@ pub fn generate(n: u8) -> Result<astree::Structure, error::Error> { @@ -34,19 +54,32 @@ pub fn generate(n: u8) -> Result<astree::Structure, error::Error> {
),
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);
let idents = Some(&labels);
let x_label = format!("@x{}", i);
let x_exp = Expression::operation(
let x_label = format!("@{}x{}", prefix, i);
let x_base = Expression::operation(
'*',
Expression::var('s'),
multiplier.clone(),
Expression::function(
FunctionType::Cos,
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)?;
labels.insert(x_label.to_string(), x_exp);
@ -62,15 +95,21 @@ pub fn generate(n: u8) -> Result<astree::Structure, error::Error> { @@ -62,15 +95,21 @@ pub fn generate(n: u8) -> Result<astree::Structure, error::Error> {
let idents = Some(&labels);
let y_label = format!("@y{}", i);
let y_exp = Expression::operation(
let y_label = format!("@{}y{}", prefix, i);
let y_base = Expression::operation(
'*',
Expression::var('s'),
multiplier.clone(),
Expression::function(
FunctionType::Sin,
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)?;
labels.insert(y_label.to_string(), y_exp);
@ -86,8 +125,8 @@ pub fn generate(n: u8) -> Result<astree::Structure, error::Error> { @@ -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_angle_label = format!("@nangle{}", i);
let normal_angle_exp = Expression::operation(
let normal_angle_label = format!("@{}nangle{}", prefix, i);
let normal_angle_base = Expression::operation(
'/',
Expression::operation(
'*',
@ -96,16 +135,22 @@ pub fn generate(n: u8) -> Result<astree::Structure, error::Error> { @@ -96,16 +135,22 @@ pub fn generate(n: u8) -> Result<astree::Structure, error::Error> {
),
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);
let normal_x_label = format!("@nx{}", i);
let normal_x_label = format!("@{}nx{}", prefix, i);
let normal_x_exp = Expression::function(
FunctionType::Cos,
Expression::ident(normal_angle_label.to_string()),
);
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(
FunctionType::Sin,
Expression::ident(normal_angle_label.to_string()),

Loading…
Cancel
Save