Browse Source

Add remake flag

main
raffitz 3 years ago
parent
commit
4c0c8b7c68
Signed by: raffitz
GPG Key ID: BB3596BD0A31252D
  1. 1
      .gitignore
  2. 2
      Cargo.lock
  3. 2
      Cargo.toml
  4. 147
      src/astree.rs
  5. 63
      src/main.rs
  6. 6
      src/ngon.rs
  7. 120
      src/star.rs
  8. 274
      src/triangle.rs

1
.gitignore vendored

@ -5,4 +5,5 @@ @@ -5,4 +5,5 @@
*/*.csv
*/*.txt
*/*.gv
*/remake.solid
*.gv

2
Cargo.lock generated

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

2
Cargo.toml

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

147
src/astree.rs

@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
use crate::error::Error;
use std::collections::{HashMap, HashSet};
use std::fmt;
use std::io::Write;
#[derive(Debug, PartialEq, Clone)]
@ -22,12 +23,42 @@ pub enum FunctionType { @@ -22,12 +23,42 @@ pub enum FunctionType {
Neg,
}
impl fmt::Display for FunctionType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let text = match *self {
FunctionType::Sin => "sin",
FunctionType::Cos => "cos",
FunctionType::Tan => "tan",
FunctionType::Sec => "sec",
FunctionType::Csc => "csc",
FunctionType::Cot => "cot",
FunctionType::Asin => "asin",
FunctionType::Acos => "acos",
FunctionType::Atan => "atan",
FunctionType::Sign => "sign",
FunctionType::Abs => "abs",
FunctionType::Sqrt => "√",
FunctionType::Exp => "exp",
FunctionType::Ln => "ln",
FunctionType::Log => "log",
FunctionType::Neg => "-",
};
text.fmt(f)
}
}
#[derive(Debug, Clone)]
pub struct FunctionData {
kind: FunctionType,
arg: Box<Expression>,
}
impl fmt::Display for FunctionData {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}({})", self.kind, self.arg)
}
}
impl FunctionData {
pub fn new(kind: FunctionType, arg_exp: Expression) -> Self {
let arg = Box::new(arg_exp);
@ -98,6 +129,12 @@ pub struct OperationData { @@ -98,6 +129,12 @@ pub struct OperationData {
right: Box<Expression>,
}
impl fmt::Display for OperationData {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "({} {} {})", self.left, self.kind, self.right)
}
}
impl OperationData {
pub fn new(kind: char, left_exp: Expression, right_exp: Expression) -> Self {
let left = Box::new(left_exp);
@ -151,6 +188,18 @@ pub enum Expression { @@ -151,6 +188,18 @@ pub enum Expression {
Operation(OperationData),
}
impl fmt::Display for Expression {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Expression::Var(v) => v.fmt(f),
Expression::Float(n) => n.fmt(f),
Expression::Ident(s) => s.fmt(f),
Expression::Function(function) => function.fmt(f),
Expression::Operation(op) => op.fmt(f),
}
}
}
impl Expression {
pub fn var(c: char) -> Self {
Expression::Var(c)
@ -254,34 +303,38 @@ impl Expression { @@ -254,34 +303,38 @@ impl Expression {
pub fn ident_dependencies(
&self,
idents: &Option<&HashMap<String, Expression>>,
) -> Result<HashSet<String>, Error> {
) -> Result<HashSet<(String, usize)>, Error> {
match self {
Expression::Float(_) => Ok(HashSet::new()),
Expression::Function(f) => f.arg.ident_dependencies(idents),
Expression::Operation(o) => {
let left = o.left.ident_dependencies(idents)?;
let right = o.right.ident_dependencies(idents)?;
let mut result: HashSet<String> = HashSet::new();
for dep in left {
result.insert(dep);
}
for dep in right {
result.insert(dep);
let mut result: HashSet<(String, usize)> = HashSet::new();
for dep in left.union(&right) {
result.insert(dep.to_owned());
}
Ok(result)
}
Expression::Var(_) => Ok(HashSet::new()),
Expression::Ident(s) => {
let mut result: HashSet<String> = HashSet::new();
result.insert(s.to_owned());
let mut result: HashSet<(String, usize)> = HashSet::new();
let mut max_recursion: usize = 0;
let ident_exps = idents.as_ref().ok_or::<Error>(Error::MissingIdentMap)?;
let referred = ident_exps
.get(s)
.ok_or::<Error>(Error::MissingIdentAssignment)?;
let recursive = referred.ident_dependencies(idents)?;
for dep in recursive {
let (_, level) = dep;
result.insert(dep);
if level + 1 > max_recursion {
max_recursion = level + 1;
}
}
result.insert((s.to_owned(), max_recursion));
Ok(result)
}
}
@ -295,6 +348,12 @@ pub struct Condition { @@ -295,6 +348,12 @@ pub struct Condition {
right: Box<Expression>,
}
impl fmt::Display for Condition {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{} {} {}", self.left, self.kind, self.right)
}
}
impl Condition {
pub fn new(kind: char, left_exp: Expression, right_exp: Expression) -> Self {
let left = Box::new(left_exp);
@ -336,6 +395,19 @@ impl Condition { @@ -336,6 +395,19 @@ impl Condition {
)?;
Ok(max_id)
}
pub fn ident_dependencies(
&self,
idents: &Option<&HashMap<String, Expression>>,
) -> Result<HashSet<(String, usize)>, Error> {
let left_idents = self.left.ident_dependencies(idents)?;
let right_idents = self.right.ident_dependencies(idents)?;
let mut result: HashSet<(String, usize)> = HashSet::new();
for dep in left_idents.union(&right_idents) {
result.insert(dep.to_owned());
}
Ok(result)
}
}
#[derive(Debug)]
@ -345,6 +417,12 @@ pub struct JunctionData { @@ -345,6 +417,12 @@ pub struct JunctionData {
right: Box<Junction>,
}
impl fmt::Display for JunctionData {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{{{} {} {}}}", self.left, self.kind, self.right)
}
}
impl JunctionData {
pub fn new(kind: char, left_cond: Junction, right_cond: Junction) -> Self {
let left = Box::new(left_cond);
@ -386,6 +464,19 @@ impl JunctionData { @@ -386,6 +464,19 @@ impl JunctionData {
)?;
Ok(max_id)
}
pub fn ident_dependencies(
&self,
idents: &Option<&HashMap<String, Expression>>,
) -> Result<HashSet<(String, usize)>, Error> {
let left_idents = self.left.ident_dependencies(idents)?;
let right_idents = self.right.ident_dependencies(idents)?;
let mut result: HashSet<(String, usize)> = HashSet::new();
for dep in left_idents.union(&right_idents) {
result.insert(dep.to_owned());
}
Ok(result)
}
}
#[derive(Debug)]
@ -394,6 +485,15 @@ pub enum Junction { @@ -394,6 +485,15 @@ pub enum Junction {
Meta(JunctionData),
}
impl fmt::Display for Junction {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Junction::Singleton(condition) => condition.fmt(f),
Junction::Meta(meta) => meta.fmt(f),
}
}
}
impl Junction {
pub fn singleton(cond: Condition) -> Self {
Junction::Singleton(cond)
@ -421,6 +521,16 @@ impl Junction { @@ -421,6 +521,16 @@ impl Junction {
Junction::Singleton(cond) => cond.graph(output, id),
}
}
pub fn ident_dependencies(
&self,
idents: &Option<&HashMap<String, Expression>>,
) -> Result<HashSet<(String, usize)>, Error> {
match self {
Junction::Singleton(cond) => cond.ident_dependencies(idents),
Junction::Meta(meta) => meta.ident_dependencies(idents),
}
}
}
#[derive(Debug)]
@ -430,6 +540,12 @@ pub struct Boundary { @@ -430,6 +540,12 @@ pub struct Boundary {
pub max: Expression,
}
impl fmt::Display for Boundary {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{} ≤ {} ≤ {}", self.min, self.var, self.max)
}
}
impl Boundary {
pub fn new(
l: Expression,
@ -458,6 +574,19 @@ impl Boundary { @@ -458,6 +574,19 @@ impl Boundary {
}
Err(())
}
pub fn ident_dependencies(
&self,
idents: &Option<&HashMap<String, Expression>>,
) -> Result<HashSet<(String, usize)>, Error> {
let left_idents = self.min.ident_dependencies(idents)?;
let right_idents = self.max.ident_dependencies(idents)?;
let mut result: HashSet<(String, usize)> = HashSet::new();
for dep in left_idents.union(&right_idents) {
result.insert(dep.to_owned());
}
Ok(result)
}
}
pub type Boundaries = [Boundary; 3];

63
src/main.rs

@ -114,6 +114,14 @@ fn main() -> Result<(), error::Error> { @@ -114,6 +114,14 @@ fn main() -> Result<(), error::Error> {
.takes_value(false)
.multiple(false),
)
.arg(
Arg::with_name("remake")
.short("r")
.long("remake")
.help("Remake definition file from internal state")
.takes_value(false)
.multiple(false),
)
.arg(
Arg::with_name("test")
.short("t")
@ -320,6 +328,7 @@ fn main() -> Result<(), error::Error> { @@ -320,6 +328,7 @@ fn main() -> Result<(), error::Error> {
}
let graph = matches.is_present("graph");
let remake = matches.is_present("remake");
let test = matches.is_present("test");
let mut output_folder = ".";
@ -371,8 +380,7 @@ fn main() -> Result<(), error::Error> { @@ -371,8 +380,7 @@ fn main() -> Result<(), error::Error> {
.map(|n| n.parse::<u8>().unwrap())
.unwrap(),
None,
None,
None,
(None, None),
angleident,
None,
Some(labels),
@ -393,7 +401,9 @@ fn main() -> Result<(), error::Error> { @@ -393,7 +401,9 @@ fn main() -> Result<(), error::Error> {
angleident = None;
}
let star_factor = submatches.value_of("factor").map(|f| f.parse::<f64>().unwrap());
let star_factor = submatches
.value_of("factor")
.map(|f| f.parse::<f64>().unwrap());
output_folder = submatches.value_of("OUTPUT_DIR").unwrap_or(output_folder);
structure = star::generate::<String, f64>(
@ -402,8 +412,7 @@ fn main() -> Result<(), error::Error> { @@ -402,8 +412,7 @@ fn main() -> Result<(), error::Error> {
.map(|n| n.parse::<u8>().unwrap())
.unwrap(),
None,
None,
None,
(None, None),
angleident,
None,
star_factor,
@ -515,6 +524,50 @@ fn main() -> Result<(), error::Error> { @@ -515,6 +524,50 @@ fn main() -> Result<(), error::Error> {
writeln!(gv_file, "}}")?;
}
// Print remake
if remake {
let mut remake_file = fs::File::create(format! {"{}/remake.solid",output_folder})?;
writeln!(
remake_file,
"# Solid specifications remade by {} v{}, by {} */\n\n",
crate_name!(),
crate_version!(),
crate_authors!()
)?;
let lookup = Some(&idents);
// Print tree and boundary dependencies
let mut complete_deps = tree.ident_dependencies(&lookup)?;
for limit in &limits {
let limit_deps = limit.ident_dependencies(&lookup)?;
for dep in limit_deps {
complete_deps.insert(dep);
}
}
let mut vector_deps: Vec<(String, usize)> = complete_deps.into_iter().collect();
vector_deps.sort_unstable_by(|(_, i), (_, j)| i.cmp(j));
for dep in vector_deps {
let (name, _) = dep;
let definition = idents
.get(&name)
.ok_or::<Error>(Error::MissingIdentAssignment)?;
writeln!(remake_file, "define {} {}", name, definition)?;
}
writeln!(remake_file, "\n")?;
// Print limits
for limit in &limits {
writeln!(remake_file, "{}", limit)?;
}
writeln!(remake_file, "\n")?;
// Print tree
writeln!(remake_file, "{}", tree)?;
}
if test {
return Ok(());
}

6
src/ngon.rs

@ -6,8 +6,7 @@ use std::collections::HashMap; @@ -6,8 +6,7 @@ use std::collections::HashMap;
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>,
offset: (Option<T>, Option<T>),
angle_offset: Option<T>,
scale: Option<S>,
previous_labels: Option<HashMap<String, Expression>>,
@ -27,6 +26,8 @@ pub fn generate<T: Into<String> + Clone, S: Into<f64> + Copy>( @@ -27,6 +26,8 @@ pub fn generate<T: Into<String> + Clone, S: Into<f64> + Copy>(
let double_n: u16 = (n as u16) * 2;
let (x_offset, y_offset) = offset;
let mut min_x = f64::MAX;
let mut min_x_label = String::from("error");
let mut max_x = f64::MIN;
@ -74,6 +75,7 @@ pub fn generate<T: Into<String> + Clone, S: Into<f64> + Copy>( @@ -74,6 +75,7 @@ pub fn generate<T: Into<String> + Clone, S: Into<f64> + Copy>(
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()))

120
src/star.rs

@ -0,0 +1,120 @@ @@ -0,0 +1,120 @@
use crate::astree;
use crate::astree::{Expression, Junction};
use crate::error;
use crate::ngon;
use crate::triangle::any_triangle;
use std::collections::HashMap;
pub fn generate<T: Into<String> + Clone, S: Into<f64> + Copy>(
n: u8,
prefix_val: Option<T>,
offset: (Option<T>, Option<T>),
angle_offset: Option<T>,
scale: Option<S>,
star_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 = previous_labels.unwrap_or_default();
let (x_offset, y_offset) = offset;
let center_x;
let center_y;
if let Some(x_label) = x_offset {
center_x = x_label.into();
} else {
center_x = format!("@{}centerx", prefix);
labels.insert(center_x.clone(), Expression::float(0_f64));
}
if let Some(y_label) = y_offset {
center_y = y_label.into();
} else {
center_y = format!("@{}centery", prefix);
labels.insert(center_y.clone(), Expression::float(0_f64));
}
let new_angle_offset = angle_offset.map(|a| a.into());
let new_scale = scale.map(|s| s.into());
let inner_prefix = format!("{}inner", prefix);
let (new_labels, _, _) = ngon::generate(
n,
Some(inner_prefix.clone()),
(Some(center_x.clone()), Some(center_y.clone())),
new_angle_offset,
new_scale,
Some(labels),
)?;
let angle_offset_label = format!("@{}innernangle0", prefix);
let outer_prefix = format!("{}outer", prefix);
let outer_scale = star_scale.map(|s| s.into()).unwrap_or(2_f64) * new_scale.unwrap_or(1_f64);
let (definitive_labels, boundaries, _) = ngon::generate(
n,
Some(outer_prefix.clone()),
(Some(center_x.clone()), Some(center_y.clone())),
Some(angle_offset_label),
Some(outer_scale),
new_labels,
)?;
let mut input_labels = definitive_labels;
for i in 0..n {
let label_x_1 = format!("@{}x{}", inner_prefix, i);
let label_y_1 = format!("@{}y{}", inner_prefix, i);
let label_x_2 = format!("@{}x{}", outer_prefix, i);
let label_y_2 = format!("@{}y{}", outer_prefix, i);
let (definitive_labels, _, junction) = any_triangle(
center_x.clone(),
center_y.clone(),
label_x_1,
label_y_1,
label_x_2,
label_y_2,
input_labels,
)?;
input_labels = definitive_labels;
junctions.push(junction);
let label_x_1 = format!("@{}x{}", outer_prefix, i);
let label_y_1 = format!("@{}y{}", outer_prefix, i);
let label_x_2 = format!("@{}x{}", inner_prefix, (i + 1) % n);
let label_y_2 = format!("@{}y{}", inner_prefix, (i + 1) % n);
let (definitive_labels, _, junction) = any_triangle(
center_x.clone(),
center_y.clone(),
label_x_1,
label_y_1,
label_x_2,
label_y_2,
input_labels,
)?;
input_labels = definitive_labels;
junctions.push(junction);
}
while junctions.len() > 1 {
let left = junctions.remove(0);
let right = junctions.remove(0);
junctions.push(Junction::meta('⋁', left, right));
}
let the_junction = junctions.pop().unwrap();
Ok((input_labels, boundaries, the_junction))
}

274
src/triangle.rs

@ -0,0 +1,274 @@ @@ -0,0 +1,274 @@
use crate::astree;
use crate::astree::{Boundaries, Boundary, Condition, Expression, Junction};
use crate::error;
use std::collections::HashMap;
pub fn any_triangle<T: Into<String> + Clone>(
x_1: T,
y_1: T,
x_2: T,
y_2: T,
x_3: T,
y_3: T,
previous_labels: Option<HashMap<String, Expression>>,
) -> Result<astree::Structure, error::Error> {
let mut junctions = Vec::<Junction>::with_capacity(3);
let labels = previous_labels.unwrap_or_default();
let mut vars = HashMap::<char, f64>::new();
vars.insert('s', 1_f64);
let vars_eval = Some(&vars);
// Determine if clockwise
let idents = Some(&labels);
let clockwise_exp = Expression::operation(
'+',
Expression::operation(
'+',
Expression::operation(
'*',
Expression::operation(
'-',
Expression::ident(x_3.clone().into()),
Expression::ident(x_2.clone().into()),
),
Expression::operation(
'+',
Expression::ident(y_3.clone().into()),
Expression::ident(y_2.clone().into()),
),
),
Expression::operation(
'*',
Expression::operation(
'-',
Expression::ident(x_1.clone().into()),
Expression::ident(x_3.clone().into()),
),
Expression::operation(
'+',
Expression::ident(y_1.clone().into()),
Expression::ident(y_3.clone().into()),
),
),
),
Expression::operation(
'*',
Expression::operation(
'-',
Expression::ident(x_2.clone().into()),
Expression::ident(x_1.clone().into()),
),
Expression::operation(
'+',
Expression::ident(y_2.clone().into()),
Expression::ident(y_1.clone().into()),
),
),
);
let clockwise = clockwise_exp.eval(&idents, &vars_eval)? > 1e-10_f64;
let ident_x_1 = x_1.into();
let ident_y_1 = y_1.into();
let ident_x_2;
let ident_y_2;
let ident_x_3;
let ident_y_3;
if clockwise {
ident_x_2 = x_3.into();
ident_y_2 = y_3.into();
ident_x_3 = x_2.into();
ident_y_3 = y_2.into();
} else {
ident_x_2 = x_2.into();
ident_y_2 = y_2.into();
ident_x_3 = x_3.into();
ident_y_3 = y_3.into();
}
let mut min_x = f64::MAX;
let mut min_x_label = String::from("error");
let mut max_x = f64::MIN;
let mut max_x_label = String::from("error");
let mut min_y = f64::MAX;
let mut min_y_label = String::from("error");
let mut max_y = f64::MIN;
let mut max_y_label = String::from("error");
let x_1_val = Expression::ident(ident_x_1.clone()).eval(&idents, &vars_eval)?;
let x_2_val = Expression::ident(ident_x_2.clone()).eval(&idents, &vars_eval)?;
let x_3_val = Expression::ident(ident_x_3.clone()).eval(&idents, &vars_eval)?;
let y_1_val = Expression::ident(ident_y_1.clone()).eval(&idents, &vars_eval)?;
let y_2_val = Expression::ident(ident_y_2.clone()).eval(&idents, &vars_eval)?;
let y_3_val = Expression::ident(ident_y_3.clone()).eval(&idents, &vars_eval)?;
if x_1_val < min_x {
min_x = x_1_val;
min_x_label = ident_x_1.clone();
}
if x_2_val < min_x {
min_x = x_2_val;
min_x_label = ident_x_2.clone();
}
if x_3_val < min_x {
min_x_label = ident_x_3.clone();
}
if x_1_val > max_x {
max_x = x_1_val;
max_x_label = ident_x_1.clone();
}
if x_2_val > max_x {
max_x = x_2_val;
max_x_label = ident_x_2.clone();
}
if x_3_val > max_x {
max_x_label = ident_x_3.clone();
}
if y_1_val < min_y {
min_y = y_1_val;
min_y_label = ident_y_1.clone();
}
if y_2_val < min_y {
min_y = y_2_val;
min_y_label = ident_y_2.clone();
}
if y_3_val < min_y {
min_y_label = ident_y_3.clone();
}
if y_1_val > max_y {
max_y = y_1_val;
max_y_label = ident_y_1.clone();
}
if y_2_val > max_y {
max_y = y_2_val;
max_y_label = ident_y_2.clone();
}
if y_3_val > max_y {
max_y_label = ident_y_3.clone();
}
let normal_1_y = Expression::operation(
'-',
Expression::ident(ident_x_1.clone()),
Expression::ident(ident_x_2.clone()),
)
.eval(&idents, &vars_eval)?;
let normal_1_x = Expression::operation(
'-',
Expression::ident(ident_y_2.clone()),
Expression::ident(ident_y_1.clone()),
)
.eval(&idents, &vars_eval)?;
let normal_2_y = Expression::operation(
'-',
Expression::ident(ident_x_2.clone()),
Expression::ident(ident_x_3.clone()),
)
.eval(&idents, &vars_eval)?;
let normal_2_x = Expression::operation(
'-',
Expression::ident(ident_y_3.clone()),
Expression::ident(ident_y_2.clone()),
)
.eval(&idents, &vars_eval)?;
let normal_3_y = Expression::operation(
'-',
Expression::ident(ident_x_3.clone()),
Expression::ident(ident_x_1.clone()),
)
.eval(&idents, &vars_eval)?;
let normal_3_x = Expression::operation(
'-',
Expression::ident(ident_y_1.clone()),
Expression::ident(ident_y_3.clone()),
)
.eval(&idents, &vars_eval)?;
let j_exp = Expression::operation(
'+',
Expression::operation(
'*',
Expression::float(normal_1_x),
Expression::operation('-', Expression::var('x'), Expression::ident(ident_x_1)),
),
Expression::operation(
'*',
Expression::float(normal_1_y),
Expression::operation('-', Expression::var('y'), Expression::ident(ident_y_1)),
),
);
junctions.push(Junction::singleton(Condition::new(
'≤',
j_exp,
Expression::float(0),
)));
let j_exp = Expression::operation(
'+',
Expression::operation(
'*',
Expression::float(normal_2_x),
Expression::operation('-', Expression::var('x'), Expression::ident(ident_x_2)),
),
Expression::operation(
'*',
Expression::float(normal_2_y),
Expression::operation('-', Expression::var('y'), Expression::ident(ident_y_2)),
),
);
junctions.push(Junction::singleton(Condition::new(
'≤',
j_exp,
Expression::float(0),
)));
let j_exp = Expression::operation(
'+',
Expression::operation(
'*',
Expression::float(normal_3_x),
Expression::operation('-', Expression::var('x'), Expression::ident(ident_x_3)),
),
Expression::operation(
'*',
Expression::float(normal_3_y),
Expression::operation('-', Expression::var('y'), Expression::ident(ident_y_3)),
),
);
junctions.push(Junction::singleton(Condition::new(
'≤',
j_exp,
Expression::float(0),
)));
while junctions.len() > 1 {
let left = junctions.remove(0);
let right = junctions.remove(0);
junctions.push(Junction::meta('⋀', left, right));
}
let the_junction = junctions.pop().unwrap();
let boundaries: Boundaries = [
Boundary::new(Expression::float(0), '≤', 'z', '≤', Expression::float(0))?,
Boundary::new(
Expression::ident(min_x_label),
'≤',
'x',
'≤',
Expression::ident(max_x_label),
)?,
Boundary::new(
Expression::ident(min_y_label),
'≤',
'y',
'≤',
Expression::ident(max_y_label),
)?,
];
Ok((Some(labels), boundaries, the_junction))
}
Loading…
Cancel
Save