data abstraction
fn add_complex(z1: &impl Complex, z2: &impl Complex) -> impl Complex {
make_from_real_imag(
z1.real_part() + z2.real_part(),
z1.imag_part() + z2.imag_part(),
)
}
fn sub_complex(z1: &impl Complex, z2: &impl Complex) -> impl Complex {
make_from_real_imag(
z1.real_part() - z2.real_part(),
z1.imag_part() - z2.imag_part(),
)
}
fn mul_complex(z1: &impl Complex, z2: &impl Complex) -> impl Complex {
make_from_mag_ang(z1.magnitude() * z1.magnitude(), z1.angle() + z2.angle())
}
fn div_complex(z1: &impl Complex, z2: &impl Complex) -> impl Complex {
make_from_mag_ang(z1.magnitude() / z1.magnitude(), z1.angle() - z2.angle())
}
#[derive(Debug)]
struct Rectangular {
x: f32,
y: f32,
}
#[derive(Debug)]
struct Polar {
r: f32,
a: f32,
}
trait Complex: Debug {
fn real_part(&self) -> f32;
fn imag_part(&self) -> f32;
fn magnitude(&self) -> f32;
fn angle(&self) -> f32;
}
fn make_from_real_imag(x: f32, y: f32) -> impl Complex {
Rectangular { x, y }
}
fn make_from_mag_ang(r: f32, a: f32) -> impl Complex {
Polar { r, a }
}
impl Complex for Rectangular {
fn real_part(&self) -> f32 {
self.x
}
fn imag_part(&self) -> f32 {
self.y
}
fn magnitude(&self) -> f32 {
(self.real_part().powi(2) + self.imag_part().powi(2)).sqrt()
}
fn angle(&self) -> f32 {
self.imag_part().atan2(self.real_part())
}
}
impl Complex for Polar {
fn real_part(&self) -> f32 {
self.magnitude() * self.angle().cos()
}
fn imag_part(&self) -> f32 {
self.magnitude() * self.angle().sin()
}
fn magnitude(&self) -> f32 {
self.r
}
fn angle(&self) -> f32 {
self.a
}
}
fn main() {
let i_rect = make_from_real_imag(3.5, 6.8);
let i_polar = make_from_mag_ang(34.10, 1.05);
let add = add_complex(&i_rect, &i_polar);
println!("{:#?}", add);
}