pub trait CircleCircumference {
fn h_circle_circumference(&self) -> f64;
}
impl<T> CircleCircumference for T
where
T: Copy + Into<f64>,
{
fn h_circle_circumference(&self) -> f64 {
2.0 * std::f64::consts::PI * (*self).into()
}
}
pub trait CircleArea {
fn h_circle_area(&self) -> f64;
}
impl<T> CircleArea for T
where
T: Copy + Into<f64>,
{
fn h_circle_area(&self) -> f64 {
let r = (*self).into();
std::f64::consts::PI * r * r
}
}
pub fn h_pythagorean_theorem<A, B>(a: A, b: B) -> f64
where
A: Copy + Into<f64>,
B: Copy + Into<f64>,
{
let a_f = a.into();
let b_f = b.into();
(a_f.powf(2.0) + b_f.powf(2.0)).sqrt()
}
pub fn h_reverse_pythagorean_theorem<K, H>(x: K, h: H) -> f64
where
K: Copy + Into<f64>,
H: Copy + Into<f64>,
{
let xfc: f64 = x.into().powf(2.0);
let hfc: f64 = h.into().powf(2.0);
(hfc - xfc).powf(0.5)
}
pub fn h_find_equal_legs_from_hypotenuse<H>(h: H) -> f64
where
H: Copy + Into<f64>,
{
let hfc: f64 = h.into().powf(2.0);
(hfc / 2.0).sqrt()
}
pub fn h_short_from_long_leg_30_60_90<T>(long_leg: T) -> f64
where
T: Copy + Into<f64>,
{
long_leg.into() / (3.0f64).sqrt()
}
pub trait SphereVolume {
fn h_sphere_volume(&self) -> f64;
}
impl<T> SphereVolume for T
where
T: Copy + Into<f64>,
{
fn h_sphere_volume(&self) -> f64 {
let r: f64 = (*self).into();
(4.0 / 3.0) * std::f64::consts::PI * r * r * r
}
}
pub trait SphereSurfaceArea {
fn h_sphere_surface_area(&self) -> f64;
}
impl<T> SphereSurfaceArea for T
where
T: Copy + Into<f64>,
{
fn h_sphere_surface_area(&self) -> f64 {
let r: f64 = (*self).into();
4.0 * std::f64::consts::PI * r * r
}
}
pub trait CylinderVolume<H> {
fn h_cylinder_volume(&self, height: H) -> f64;
}
impl<R, H> CylinderVolume<H> for R
where
R: Copy + Into<f64>,
H: Copy + Into<f64>,
{
fn h_cylinder_volume(&self, height: H) -> f64 {
let r: f64 = (*self).into();
let h: f64 = height.into();
std::f64::consts::PI * r * r * h
}
}
pub trait CylinderSurfaceArea<H> {
fn h_cylinder_surface_area(&self, height: H) -> f64;
}
impl<R, H> CylinderSurfaceArea<H> for R
where
R: Copy + Into<f64>,
H: Copy + Into<f64>,
{
fn h_cylinder_surface_area(&self, height: H) -> f64 {
let r: f64 = (*self).into();
let h: f64 = height.into();
2.0 * std::f64::consts::PI * r * r + 2.0 * std::f64::consts::PI * r * h
}
}
pub trait CubeVolume {
fn h_cube_volume(&self) -> f64;
}
impl<S> CubeVolume for S
where
S: Copy + Into<f64>,
{
fn h_cube_volume(&self) -> f64 {
let side: f64 = (*self).into();
side * side * side
}
}
pub trait CubeSurfaceArea {
fn h_cube_surface_area(&self) -> f64;
}
impl<S> CubeSurfaceArea for S
where
S: Copy + Into<f64>,
{
fn h_cube_surface_area(&self) -> f64 {
let side: f64 = (*self).into();
6.0 * side * side
}
}
pub fn h_cone_volume<R, H>(radius: R, height: H) -> f64
where
R: Copy + Into<f64>,
H: Copy + Into<f64>,
{
let r: f64 = radius.into();
let h: f64 = height.into();
(1.0 / 3.0) * std::f64::consts::PI * r * r * h
}
pub fn h_cone_surface_area<R, H>(radius: R, height: H) -> f64
where
R: Copy + Into<f64>,
H: Copy + Into<f64>,
{
let r: f64 = radius.into();
let h: f64 = height.into();
let slant_height: f64 = (r * r + h * h).sqrt();
std::f64::consts::PI * r * (r + slant_height)
}
pub fn h_rectangular_prism_volume<L, W, H>(length: L, width: W, height: H) -> f64
where
L: Copy + Into<f64>,
W: Copy + Into<f64>,
H: Copy + Into<f64>,
{
let length: f64 = length.into();
let width: f64 = width.into();
let height: f64 = height.into();
length * width * height
}
pub fn h_rectangular_prism_surface_area<L, W, H>(length: L, width: W, height: H) -> f64
where
L: Copy + Into<f64>,
W: Copy + Into<f64>,
H: Copy + Into<f64>,
{
let length: f64 = length.into();
let width: f64 = width.into();
let height: f64 = height.into();
2.0 * (length * width + length * height + width * height)
}
pub fn h_pyramid_volume<B, H>(base_area: B, height: H) -> f64
where
B: Copy + Into<f64>,
H: Copy + Into<f64>,
{
let base_area: f64 = base_area.into();
let height: f64 = height.into();
(1.0 / 3.0) * base_area * height
}
pub fn h_square_pyramid_surface_area<B, H>(base_area: B, height: H) -> f64
where
B: Copy + Into<f64>,
H: Copy + Into<f64>,
{
let base_area: f64 = base_area.into();
let height: f64 = height.into();
let slant_height: f64 = (height * height + (base_area / 4.0).sqrt() * (base_area / 4.0).sqrt()).sqrt();
base_area + 2.0 * (base_area / 4.0).sqrt() * slant_height
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_circle_circumference() {
assert!((5.0.h_circle_circumference() - 31.41592653589793).abs() < 1e-10);
}
#[test]
fn test_circle_area() {
assert!((5.0.h_circle_area() - 78.53981633974483).abs() < 1e-10);
}
#[test]
fn test_pythagorean_theorem() {
assert_eq!(h_pythagorean_theorem(3.0, 4.0), 5.0);
}
#[test]
fn test_reverse_pythagorean_theorem() {
assert!((h_reverse_pythagorean_theorem(3.0, 5.0) - 4.0).abs() < 1e-10);
}
#[test]
fn test_find_equal_legs_from_hypotenuse() {
assert!((h_find_equal_legs_from_hypotenuse(5.0) - 3.5355339059327378).abs() < 1e-10);
}
#[test]
fn test_short_from_long_leg_30_60_90() {
assert!((h_short_from_long_leg_30_60_90(5.0) - 2.886751345948129).abs() < 1e-10);
}
#[test]
fn test_sphere_volume() {
assert!((5.0.h_sphere_volume() - 523.5987755982989).abs() < 1e-10);
}
#[test]
fn test_sphere_surface_area() {
assert!((5.0.h_sphere_surface_area() - 314.1592653589793).abs() < 1e-10);
}
#[test]
fn test_cylinder_volume() {
assert!((5.0.h_cylinder_volume(10.0) - 785.3981633974483).abs() < 1e-10);
}
#[test]
fn test_cylinder_surface_area() {
assert!((5.0.h_cylinder_surface_area(10.0) - 471.23889803846896).abs() < 1e-10);
}
#[test]
fn test_cube_volume() {
assert_eq!(5.0.h_cube_volume(), 125.0);
}
#[test]
fn test_cube_surface_area() {
assert_eq!(5.0.h_cube_surface_area(), 150.0);
}
#[test]
fn test_cone_volume() {
assert!((h_cone_volume(5.0, 10.0) - 261.79938779914943).abs() < 1e-10);
}
#[test]
fn test_cone_surface_area() {
assert!((h_cone_surface_area(5.0, 10.0) - 254.160184615763).abs() < 1e-10);
}
#[test]
fn test_rectangular_prism_volume() {
assert_eq!(h_rectangular_prism_volume(2.0, 3.0, 4.0), 24.0);
}
#[test]
fn test_rectangular_prism_surface_area() {
assert_eq!(h_rectangular_prism_surface_area(2.0, 3.0, 4.0), 52.0);
}
#[test]
fn test_pyramid_volume() {
assert!((h_pyramid_volume(10.0, 5.0) - 16.666666666666668).abs() < 1e-10);
}
#[test]
fn test_square_pyramid_surface_area() {
let result = h_square_pyramid_surface_area(16.0, 5.0);
assert!(result > 0.0);
}
}