use crate::geometrics::GeometricObject;
use crate::surfaces::{Point3D, Surface};
use rust_decimal::Decimal;
#[allow(dead_code)]
pub fn create_planar_surface(
x_start: Decimal,
x_end: Decimal,
y_start: Decimal,
y_end: Decimal,
normal: (Decimal, Decimal, Decimal),
d: Decimal,
) -> Surface {
let x_steps = 10;
let y_steps = 10;
let x_step_size = (x_end - x_start) / Decimal::from(x_steps);
let y_step_size = (y_end - y_start) / Decimal::from(y_steps);
let (a, b, c) = normal;
let mut points = Vec::new();
for i in 0..=x_steps {
for j in 0..=y_steps {
let x = x_start + x_step_size * Decimal::from(i);
let y = y_start + y_step_size * Decimal::from(j);
let z = -(a * x + b * y + d) / c;
points.push(Point3D::new(x, y, z));
}
}
Surface::from_vector(points.iter().collect())
}
#[allow(dead_code)]
pub fn create_constant_surface(
x_start: Decimal,
x_end: Decimal,
y_start: Decimal,
y_end: Decimal,
height: Decimal,
) -> Surface {
let x_steps = 10;
let y_steps = 10;
let x_step_size = (x_end - x_start) / Decimal::from(x_steps);
let y_step_size = (y_end - y_start) / Decimal::from(y_steps);
let mut points = Vec::new();
for i in 0..=x_steps {
for j in 0..=y_steps {
let x = x_start + x_step_size * Decimal::from(i);
let y = y_start + y_step_size * Decimal::from(j);
points.push(Point3D::new(x, y, height));
}
}
Surface::from_vector(points.iter().collect())
}
#[allow(dead_code)]
pub fn create_paraboloid_surface(
x_start: Decimal,
x_end: Decimal,
y_start: Decimal,
y_end: Decimal,
a: Decimal,
b: Decimal,
) -> Surface {
let x_steps = 10;
let y_steps = 10;
let x_step_size = (x_end - x_start) / Decimal::from(x_steps);
let y_step_size = (y_end - y_start) / Decimal::from(y_steps);
let mut points = Vec::new();
for i in 0..=x_steps {
for j in 0..=y_steps {
let x = x_start + x_step_size * Decimal::from(i);
let y = y_start + y_step_size * Decimal::from(j);
let z = a * x * x + b * y * y;
points.push(Point3D::new(x, y, z));
}
}
Surface::new(points.into_iter().collect())
}
#[cfg(test)]
mod tests_surfaces_utils {
use super::*;
use rust_decimal_macros::dec;
#[test]
fn test_create_constant_surface() {
let surface = create_constant_surface(dec!(0), dec!(10), dec!(0), dec!(10), dec!(5));
assert_eq!(surface.points.len(), 121);
assert!(surface.points.iter().all(|p| p.z == dec!(5)));
let x_coords: Vec<_> = surface.points.iter().map(|p| p.x).collect();
let y_coords: Vec<_> = surface.points.iter().map(|p| p.y).collect();
assert!(x_coords.contains(&dec!(0)));
assert!(x_coords.contains(&dec!(10)));
assert!(y_coords.contains(&dec!(0)));
assert!(y_coords.contains(&dec!(10)));
assert!(
surface
.points
.iter()
.any(|p| p.x == dec!(0) && p.y == dec!(0) && p.z == dec!(5))
);
assert!(
surface
.points
.iter()
.any(|p| p.x == dec!(10) && p.y == dec!(10) && p.z == dec!(5))
);
assert!(
surface
.points
.iter()
.any(|p| p.x == dec!(0) && p.y == dec!(10) && p.z == dec!(5))
);
}
#[test]
fn test_create_planar_surface() {
let surface = create_planar_surface(
dec!(0),
dec!(10),
dec!(0),
dec!(10),
(dec!(0), dec!(0), dec!(1)), dec!(5), );
assert_eq!(surface.points.len(), 121);
assert!(surface.points.iter().all(|p| p.z == dec!(-5)));
let x_coords: Vec<_> = surface.points.iter().map(|p| p.x).collect();
let y_coords: Vec<_> = surface.points.iter().map(|p| p.y).collect();
assert!(x_coords.contains(&dec!(0)));
assert!(x_coords.contains(&dec!(10)));
assert!(y_coords.contains(&dec!(0)));
assert!(y_coords.contains(&dec!(10)));
assert!(
surface
.points
.iter()
.any(|p| p.x == dec!(0) && p.y == dec!(0) && p.z == dec!(-5))
);
assert!(
surface
.points
.iter()
.any(|p| p.x == dec!(10) && p.y == dec!(10) && p.z == dec!(-5))
);
assert!(
surface
.points
.iter()
.any(|p| p.x == dec!(0) && p.y == dec!(10) && p.z == dec!(-5))
);
}
#[test]
fn test_create_paraboloid_surface() {
let surface = create_paraboloid_surface(
dec!(-1),
dec!(1),
dec!(-1),
dec!(1),
dec!(1), dec!(1), );
assert_eq!(surface.points.len(), 121);
let origin = surface
.points
.iter()
.find(|p| p.x == dec!(0) && p.y == dec!(0))
.unwrap();
assert_eq!(origin.z, dec!(0));
let corner = surface
.points
.iter()
.find(|p| p.x == dec!(1) && p.y == dec!(1))
.unwrap();
assert_eq!(corner.z, dec!(2));
let opposite_corner = surface
.points
.iter()
.find(|p| p.x == dec!(-1) && p.y == dec!(-1))
.unwrap();
assert_eq!(opposite_corner.z, dec!(2));
assert!(
surface
.points
.iter()
.any(|p| p.x == dec!(0) && p.y == dec!(0) && p.z == dec!(0))
);
assert!(
surface
.points
.iter()
.any(|p| p.x == dec!(1) && p.y == dec!(1) && p.z == dec!(2))
);
assert!(
surface
.points
.iter()
.any(|p| p.x == dec!(-1) && p.y == dec!(-1) && p.z == dec!(2))
);
}
}