pub mod constants {
pub const PI: f64 = std::f64::consts::PI;
pub const TAU: f64 = std::f64::consts::TAU;
pub const E: f64 = std::f64::consts::E;
}
#[derive(Debug)]
pub enum GeometryError {
NegativeValue,
ZeroValue,
InvalidAngle,
InvalidInput(String),
}
pub mod area {
use super::{constants::PI, GeometryError};
pub fn circle(radius: f64) -> Result<f64, GeometryError> {
if radius <= 0.0 {
return Err(GeometryError::NegativeValue);
}
Ok(PI * radius * radius)
}
pub fn triangle(height: f64, width: f64) -> Result<f64, GeometryError> {
if height <= 0.0 || width <= 0.0 {
return Err(GeometryError::NegativeValue);
}
Ok(0.5 * height * width)
}
pub fn square(length: f64) -> Result<f64, GeometryError> {
if length <= 0.0 {
return Err(GeometryError::NegativeValue);
}
Ok(length * length)
}
pub fn rectangle(height: f64, width: f64) -> Result<f64, GeometryError> {
if height <= 0.0 || width <= 0.0 {
return Err(GeometryError::NegativeValue);
}
Ok(height * width)
}
pub fn trapezoid(base1: f64, base2: f64, height: f64) -> Result<f64, GeometryError> {
if base1 <= 0.0 || base2 <= 0.0 || height <= 0.0 {
return Err(GeometryError::NegativeValue);
}
Ok(0.5 * (base1 + base2) * height)
}
pub fn parallelogram(base: f64, height: f64) -> Result<f64, GeometryError> {
if base <= 0.0 || height <= 0.0 {
return Err(GeometryError::NegativeValue);
}
Ok(base * height)
}
pub fn ellipse(major_axis: f64, minor_axis: f64) -> Result<f64, GeometryError> {
if major_axis <= 0.0 || minor_axis <= 0.0 {
return Err(GeometryError::NegativeValue);
}
Ok(PI * major_axis * minor_axis)
}
pub fn sector(radius: f64, angle: f64) -> Result<f64, GeometryError> {
if radius <= 0.0 {
return Err(GeometryError::NegativeValue);
}
if angle <= 0.0 || angle > 360.0 {
return Err(GeometryError::InvalidAngle);
}
Ok(0.5 * radius * radius * angle * PI / 180.0)
}
pub fn rhombus(diagonal1: f64, diagonal2: f64) -> Result<f64, GeometryError> {
if diagonal1 <= 0.0 || diagonal2 <= 0.0 {
return Err(GeometryError::NegativeValue);
}
Ok(0.5 * diagonal1 * diagonal2)
}
pub fn kite(diagonal1: f64, diagonal2: f64) -> Result<f64, GeometryError> {
if diagonal1 <= 0.0 || diagonal2 <= 0.0 {
return Err(GeometryError::NegativeValue);
}
Ok(0.5 * diagonal1 * diagonal2)
}
pub fn regular_polygon(perimeter: f64, apothem: f64) -> Result<f64, GeometryError> {
if perimeter <= 0.0 || apothem <= 0.0 {
return Err(GeometryError::NegativeValue);
}
Ok(0.5 * perimeter * apothem)
}
pub fn annulus(outer_radius: f64, inner_radius: f64) -> Result<f64, GeometryError> {
if outer_radius <= 0.0 || inner_radius <= 0.0 {
return Err(GeometryError::NegativeValue);
}
if inner_radius >= outer_radius {
return Err(GeometryError::InvalidInput(
"Inner radius must be smaller than outer radius".to_string(),
));
}
Ok(PI * (outer_radius * outer_radius - inner_radius * inner_radius))
}
pub fn pentagon(side_length: f64) -> Result<f64, GeometryError> {
if side_length <= 0.0 {
return Err(GeometryError::NegativeValue);
}
Ok(0.25 * (5.0 * (5.0 + 2.0 * (5.0_f64).sqrt())).sqrt() * side_length * side_length)
}
pub fn hexagon(side_length: f64) -> Result<f64, GeometryError> {
if side_length <= 0.0 {
return Err(GeometryError::NegativeValue);
}
Ok(3.0 * 3.0_f64.sqrt() * side_length * side_length / 2.0)
}
pub fn polygon(sides: u32, side_length: f64) -> Result<f64, GeometryError> {
if sides < 3 {
return Err(GeometryError::InvalidInput(
"Polygon must have at least 3 sides".to_string(),
));
}
if side_length <= 0.0 {
return Err(GeometryError::NegativeValue);
}
let n = sides as f64;
Ok(n * side_length * side_length / (4.0 * (PI / n).tan()))
}
pub fn circular_segment(radius: f64, angle_degrees: f64) -> Result<f64, GeometryError> {
if radius <= 0.0 {
return Err(GeometryError::NegativeValue);
}
if angle_degrees <= 0.0 || angle_degrees > 360.0 {
return Err(GeometryError::InvalidAngle);
}
let angle_rad = angle_degrees * PI / 180.0;
Ok(0.5 * radius * radius * (angle_rad - angle_rad.sin()))
}
}
pub mod perimeter {
use super::{constants::PI, GeometryError};
pub fn circle(radius: f64) -> Result<f64, GeometryError> {
if radius <= 0.0 {
return Err(GeometryError::NegativeValue);
}
Ok(2.0 * PI * radius)
}
pub fn rectangle(length: f64, width: f64) -> Result<f64, GeometryError> {
if length <= 0.0 || width <= 0.0 {
return Err(GeometryError::NegativeValue);
}
Ok(2.0 * (length + width))
}
pub fn triangle(a: f64, b: f64, c: f64) -> Result<f64, GeometryError> {
if a <= 0.0 || b <= 0.0 || c <= 0.0 {
return Err(GeometryError::NegativeValue);
}
if a + b <= c || b + c <= a || a + c <= b {
return Err(GeometryError::InvalidInput(
"Invalid triangle sides".to_string(),
));
}
Ok(a + b + c)
}
pub fn regular_polygon(sides: u32, side_length: f64) -> Result<f64, GeometryError> {
if sides < 3 {
return Err(GeometryError::InvalidInput(
"Polygon must have at least 3 sides".to_string(),
));
}
if side_length <= 0.0 {
return Err(GeometryError::NegativeValue);
}
Ok(sides as f64 * side_length)
}
}
pub mod surface_area {
use super::{constants::PI, GeometryError};
pub fn cube(side: f64) -> Result<f64, GeometryError> {
if side <= 0.0 {
return Err(GeometryError::NegativeValue);
}
Ok(6.0 * side * side)
}
pub fn sphere(radius: f64) -> Result<f64, GeometryError> {
if radius <= 0.0 {
return Err(GeometryError::NegativeValue);
}
Ok(4.0 * PI * radius * radius)
}
pub fn cylinder(radius: f64, height: f64) -> Result<f64, GeometryError> {
if radius <= 0.0 || height <= 0.0 {
return Err(GeometryError::NegativeValue);
}
Ok(2.0 * PI * radius * (radius + height))
}
pub fn cone(radius: f64, height: f64) -> Result<f64, GeometryError> {
if radius <= 0.0 || height <= 0.0 {
return Err(GeometryError::NegativeValue);
}
let slant_height = (radius * radius + height * height).sqrt();
Ok(PI * radius * (radius + slant_height))
}
}
pub mod volume {
use super::{constants::PI, GeometryError};
pub fn cube(side: f64) -> Result<f64, GeometryError> {
if side <= 0.0 {
return Err(GeometryError::NegativeValue);
}
Ok(side * side * side)
}
pub fn sphere(radius: f64) -> Result<f64, GeometryError> {
if radius <= 0.0 {
return Err(GeometryError::NegativeValue);
}
Ok(4.0 / 3.0 * PI * radius * radius * radius)
}
pub fn cylinder(radius: f64, height: f64) -> Result<f64, GeometryError> {
if radius <= 0.0 || height <= 0.0 {
return Err(GeometryError::NegativeValue);
}
Ok(PI * radius * radius * height)
}
pub fn cone(radius: f64, height: f64) -> Result<f64, GeometryError> {
if radius <= 0.0 || height <= 0.0 {
return Err(GeometryError::NegativeValue);
}
Ok(PI * radius * radius * height / 3.0)
}
pub fn rectangular_prism(length: f64, width: f64, height: f64) -> Result<f64, GeometryError> {
if length <= 0.0 || width <= 0.0 || height <= 0.0 {
return Err(GeometryError::NegativeValue);
}
Ok(length * width * height)
}
}