Skip to content

Commit

Permalink
Merge pull request #2 from coillteoir/prism
Browse files Browse the repository at this point in the history
Implementing Simple Prism
  • Loading branch information
coillteoir authored May 3, 2024
2 parents e7d8b21 + ad42b93 commit 6cf03b2
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 55 deletions.
148 changes: 93 additions & 55 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,96 +1,134 @@
use std::f32::consts::PI;

#[derive(Clone)]
struct Point {
x: f32,
y: f32,
z: f32,
}

impl Point {
pub fn new(x: f32, y: f32, z: f32) -> Self {
Self { x, y, z }
}
}

fn main() {
println!("{}", compile("cuboid 2 3 4".to_string()))
println!("{}", compile("prism 1".to_string()).unwrap())
}

fn vertex_string(points: Vec<Point>) -> String {
points
.into_iter()
.map(|p| format!("v {0} {1} {2}", p.x, p.y, p.z))
.collect::<Vec<String>>()
.join("\n")
}

fn prism(side_len: f32) -> Result<String, String> {
let points = [
Point::new(0.000000, (PI/3.0).sin(), 0.000000),
Point::new(0.0, 0.000000, 0.0_f32.cos()),
Point::new((4.0 * PI/3.0).sin(), 0.000000, (2.0 * -PI/3.0).cos()),
Point::new((2.0 * PI/3.0).sin(), 0.000000, (2.0 * -PI/3.0).cos()),
];

Ok(format!(
r#"{0}
f -3 -2 -1
f -4 -2 -1
f -4 -3 -1
f -4 -2 -3
"#,
vertex_string(points.to_vec())
))
}

fn cuboid(sx: f32, sy: f32, sz: f32) -> String {
fn cuboid(sx: f32, sy: f32, sz: f32) -> Result<String, String> {
println!("GENERATING CUBOID");
if sx <= 0.0 || sy <= 0.0 || sz <= 0.0 {
return "could not generate cuboid, side length less than or equal to zero".to_string();
return Err(
"could not generate cuboid, side length less than or equal to zero".to_string(),
);
}
format!(
r#"v 0 {sy} {sz}
v 0 0 {sz}
v {sx} 0 {sz}
v {sx} {sy} {sz}
v 0 {sy} 0
v 0 0 0
v {sx} 0 0
v {sx} {sy} 0
let points = [
Point::new(0.0, sy, sz),
Point::new(0.0, 0.0, sz),
Point::new(sx, 0.0, sz),
Point::new(sx, sy, sz),
Point::new(0.0, sy, 0.0),
Point::new(0.0, 0.0, 0.0),
Point::new(sx, 0.0, 0.0),
Point::new(sx, sy, 0.0),
];
Ok(format!(
r#"{0}
f -8 -7 -6 -5
f -1 -2 -3 -4
f -5 -6 -2 -1
f -4 -8 -5 -1
f -4 -3 -7 -8
f -7 -3 -2 -6
"#
)
"#,
vertex_string(points.to_vec())
))
}

fn cube(x: f32, y: f32, z: f32, size: f32) -> String {
fn cube(size: f32) -> Result<String, String> {
println!("GENERATING CUBE");
if size <= 0.0 {
return "ERROR: cannot generate cube of size less than zero".to_string();
return Err("ERROR: cannot generate cube of size less than zero".to_string());
}
let size_x = size + x;
let size_y = size + y;
let size_z = size + z;
format!(
r#"v {x} {size_y} {size_z}
v {x} {y} {size_z}
v {size_x} {y} {size_z}
v {size_x} {size_y} {size_z}
v {x} {size_y} {z}
v {x} {y} {z}
v {size_x} {y} {z}
v {size_x} {size_y} {z}
f -8 -7 -6 -5
f -1 -2 -3 -4
f -5 -6 -2 -1
f -4 -8 -5 -1
f -4 -3 -7 -8
f -7 -3 -2 -6
"#
)
cuboid(size, size, size)
}

fn compile(data: String) -> String {
fn compile(data: String) -> Result<String, String> {
let mut result = String::from("");

let lines = data.split('\n');
for line in lines {
let tokens: Vec<&str> = line.split(' ').collect();
match tokens[0] {
"cube" => result.push_str(&cube(
0.0,
0.0,
0.0,
tokens[1].parse::<f32>().expect("invalid value given"),
)),
"cuboid" => result.push_str(&cuboid(
tokens[1].parse::<f32>().expect("non numeric value given"),
tokens[2].parse::<f32>().expect("non numeric value given"),
tokens[3].parse::<f32>().expect("non numeric value given"),
)),
"cube" => result
.push_str(&cube(tokens[1].parse::<f32>().expect("invalid value given")).unwrap()),
"cuboid" => result.push_str(
&cuboid(
tokens[1].parse::<f32>().expect("non numeric value given"),
tokens[2].parse::<f32>().expect("non numeric value given"),
tokens[3].parse::<f32>().expect("non numeric value given"),
)
.unwrap(),
),
"prism" => result.push_str(
&prism(tokens[1].parse::<f32>().expect("non numeric value given")).unwrap(),
),
&_ => println!("{} not supported", tokens[0]),
}
}
result
Ok(result)
}

#[cfg(test)]
mod tests {
use crate::compile;
use std::fs;

fn run_test(input_path: &str, result_path: &str) {
let input = fs::read_to_string(input_path).expect("could not load file");
let result = fs::read_to_string(result_path).expect("could not load file");
assert_eq!(compile(input), Ok(result));
}

#[test]
fn test_compile_cube() {
let input = fs::read_to_string("./tests/cube/main.kda").expect("could not load file");
let result = fs::read_to_string("./tests/cube/result.obj").expect("could not load file");
assert_eq!(compile(input), result);
run_test("./tests/cube/main.kda", "./tests/cube/result.obj");
}
#[test]
fn test_compile_cuboid() {
let input = fs::read_to_string("./tests/cuboid/main.kda").expect("could not load file");
let result = fs::read_to_string("./tests/cuboid/result.obj").expect("could not load file");
assert_eq!(compile(input), result);
run_test("./tests/cuboid/main.kda", "./tests/cuboid/result.obj");
}
#[test]
fn test_compile_prism() {
run_test("./tests/prism/main.kda", "./tests/prism/result.obj");
}
}
1 change: 1 addition & 0 deletions tests/prism/main.kda
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
prism 1
2 changes: 2 additions & 0 deletions tests/prism/result.mtl
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Blender 4.0.1 MTL File: 'None'
# www.blender.org
8 changes: 8 additions & 0 deletions tests/prism/result.obj
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
v 0 0.86602545 0
v 0 0 1
v -0.86602545 0 -0.50000006
v 0.8660254 0 -0.50000006
f -3 -2 -1
f -4 -2 -1
f -4 -3 -1
f -4 -2 -3

0 comments on commit 6cf03b2

Please sign in to comment.