mirror of
https://github.com/rm-dr/daisy
synced 2025-08-04 18:50:54 -07:00
Fixed compound unit conversion
This commit is contained in:
@ -8,8 +8,8 @@ use super::Unit;
|
||||
use super::unit_db;
|
||||
|
||||
|
||||
#[derive(Hash)]
|
||||
#[derive(Debug)]
|
||||
#[derive(Hash)]
|
||||
#[derive(Copy, Clone)]
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub struct FreeUnit {
|
||||
@ -18,6 +18,25 @@ pub struct FreeUnit {
|
||||
}
|
||||
|
||||
|
||||
macro_rules! unpack_string {
|
||||
(
|
||||
$u:expr, $s:expr,
|
||||
$( $_:expr ),*
|
||||
) => { $s };
|
||||
}
|
||||
|
||||
impl ToString for FreeUnit {
|
||||
fn to_string(&self) -> String {
|
||||
|
||||
let s = unit_db!(self.base, unpack_string);
|
||||
let p = self.prefix.to_string();
|
||||
|
||||
format!("{p}{s}")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
macro_rules! unpack_base_factor {
|
||||
(
|
||||
$unit:expr,
|
||||
@ -90,6 +109,8 @@ impl FreeUnit {
|
||||
pub fn set_prefix(&mut self, prefix: Prefix) { self.prefix = prefix; }
|
||||
pub fn get_prefix(&self) -> Prefix { self.prefix }
|
||||
|
||||
/// Returns a quantity q, so that self * q
|
||||
/// gives a quantity in base units.
|
||||
pub fn to_base_factor(&self) -> Quantity {
|
||||
|
||||
let q = unit_db!(self.base, unpack_base_factor);
|
||||
@ -102,23 +123,17 @@ impl FreeUnit {
|
||||
|
||||
return q;
|
||||
}
|
||||
}
|
||||
|
||||
// Get this unit in terms of base units
|
||||
pub fn get_base(&self) -> Quantity {
|
||||
let q = unit_db!(self.base, unpack_base_factor);
|
||||
let mut q = q.unwrap_or(Quantity::new_rational_from_string("1").unwrap());
|
||||
|
||||
// Don't divide by self
|
||||
q.insert_unit(FreeUnit::from_base(self.base), Scalar::new_rational(1f64).unwrap());
|
||||
|
||||
macro_rules! unpack_string {
|
||||
(
|
||||
$u:expr, $s:expr,
|
||||
$( $_:expr ),*
|
||||
) => { $s };
|
||||
}
|
||||
|
||||
impl ToString for FreeUnit {
|
||||
fn to_string(&self) -> String {
|
||||
|
||||
let s = unit_db!(self.base, unpack_string);
|
||||
let p = self.prefix.to_string();
|
||||
|
||||
format!("{p}{s}")
|
||||
return q;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -97,12 +97,60 @@ impl Unit {
|
||||
return n;
|
||||
}
|
||||
|
||||
// True if base units are the same
|
||||
pub fn compatible_with(&self, other: &Unit) -> bool {
|
||||
let s = self.clone() * self.to_base_factor().unit;
|
||||
let o = other.clone() * other.to_base_factor().unit;
|
||||
|
||||
return o == s;
|
||||
}
|
||||
|
||||
// True if these two units have a common factor
|
||||
pub fn common_factor(&self, other: &Unit) -> Option<Quantity> {
|
||||
|
||||
if self.unitless() || other.unitless() { return None; }
|
||||
|
||||
|
||||
let mut failed = false;
|
||||
|
||||
// What to convert `other` to before multiplying
|
||||
let mut factor = Quantity::new_rational_from_string("1").unwrap();
|
||||
let mut flag;
|
||||
for (us, _) in self.get_val() {
|
||||
flag = false;
|
||||
for (uo, po) in other.get_val() {
|
||||
if {
|
||||
us.get_base().unit.compatible_with(&uo.get_base().unit)
|
||||
} {
|
||||
factor.insert_unit(us.clone(), po.clone());
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if !flag { failed = true }
|
||||
}
|
||||
|
||||
if !failed { return Some(factor);}
|
||||
|
||||
|
||||
let mut factor = Quantity::new_rational_from_string("1").unwrap();
|
||||
for (uo, po) in other.get_val() {
|
||||
flag = false;
|
||||
for (us, _) in self.get_val() {
|
||||
if {
|
||||
us.get_base().unit.compatible_with(&uo.get_base().unit)
|
||||
} {
|
||||
factor.insert_unit(us.clone(), po.clone());
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if !flag { return None; }
|
||||
}
|
||||
|
||||
return Some(factor);
|
||||
}
|
||||
|
||||
pub fn insert(&mut self, u: FreeUnit, p: Scalar) {
|
||||
let v = self.get_val_mut();
|
||||
match v.get_mut(&u) {
|
||||
|
Reference in New Issue
Block a user