Skip to content

Commit

Permalink
Merge pull request #196 from adamreichold/add-solid-angle
Browse files Browse the repository at this point in the history
Add support for solid angles mostly based on what we do for angles.
  • Loading branch information
iliekturtles authored Jul 21, 2020
2 parents 3f92425 + 9187763 commit 5dca5a6
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 18 deletions.
28 changes: 14 additions & 14 deletions src/si/angle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,37 +29,37 @@ quantity! {
}
}

#[cfg(all(feature = "std", feature = "f32"))]
#[cfg(feature = "f32")]
impl Angle<::si::SI<f32>, f32> {
/// A half turn, i.e. an angle with a value of π as measured in radians
pub const HALF_TURN: Self = Self {
dimension: std::marker::PhantomData,
units: std::marker::PhantomData,
value: std::f32::consts::PI,
dimension: ::lib::marker::PhantomData,
units: ::lib::marker::PhantomData,
value: ::lib::f32::consts::PI,
};

/// A full turn, i.e. an angle with a value of 2π as measured in radians
pub const FULL_TURN: Self = Self {
dimension: std::marker::PhantomData,
units: std::marker::PhantomData,
value: 2. * std::f32::consts::PI,
dimension: ::lib::marker::PhantomData,
units: ::lib::marker::PhantomData,
value: 2. * ::lib::f32::consts::PI,
};
}

#[cfg(all(feature = "std", feature = "f64"))]
#[cfg(feature = "f64")]
impl Angle<::si::SI<f64>, f64> {
/// A half turn, i.e. an angle with a value of π as measured in radians
pub const HALF_TURN: Self = Self {
dimension: std::marker::PhantomData,
units: std::marker::PhantomData,
value: std::f64::consts::PI,
dimension: ::lib::marker::PhantomData,
units: ::lib::marker::PhantomData,
value: ::lib::f64::consts::PI,
};

/// A full turn, i.e. an angle with a value of 2π as measured in radians
pub const FULL_TURN: Self = Self {
dimension: std::marker::PhantomData,
units: std::marker::PhantomData,
value: 2. * std::f64::consts::PI,
dimension: ::lib::marker::PhantomData,
units: ::lib::marker::PhantomData,
value: 2. * ::lib::f64::consts::PI,
};
}

Expand Down
24 changes: 20 additions & 4 deletions src/si/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ system! {
pressure::Pressure,
ratio::Ratio,
specific_heat_capacity::SpecificHeatCapacity,
solid_angle::SolidAngle,
temperature_interval::TemperatureInterval,
thermal_conductivity::ThermalConductivity,
thermodynamic_temperature::ThermodynamicTemperature,
Expand Down Expand Up @@ -118,7 +119,7 @@ pub mod marker {
use si::{Dimension, Quantity, Units};
use Kind;

/// AngleKind is a `Kind` for separating angular quantities from their identically dimensioned
/// `AngleKind` is a `Kind` for separating angular quantities from their identically dimensioned
/// non-angular quantity counterparts. Conversions to and from `AngleKind` quantities are
/// supported through implementations of the `From` trait.
///
Expand All @@ -131,9 +132,22 @@ pub mod marker {
/// ```
pub trait AngleKind: ::Kind {}

/// InformationKind is a `Kind` for separating information quantities from their identically
/// dimensioned non-information quantity counterparts. Conversions to and from
/// `InformationKind` quantities are supported through implementations of the `From` trait.
/// `SolidAngleKind` is a `Kind` for separating quantities of solid angles from other
/// identically dimensioned quantities. Conversions to and from `SolidAngleKind` quantities are
/// supported through implementations of the `From` trait.
///
#[cfg_attr(feature = "f32", doc = " ```rust")]
#[cfg_attr(not(feature = "f32"), doc = " ```rust,ignore")]
/// # use uom::si::f32::*;
/// # use uom::si::solid_angle::steradian;
/// let a: SolidAngle = SolidAngle::new::<steradian>(1.0);
/// let r: Ratio = a.into();
/// ```
pub trait SolidAngleKind: ::Kind {}

/// `InformationKind` is a `Kind` for separating information quantities from their identically
/// dimensioned non-information quantity counterparts. Conversions to and from `InformationKind`
/// quantities are supported through implementations of the `From` trait.
///
#[cfg_attr(feature = "f32", doc = " ```rust")]
#[cfg_attr(not(feature = "f32"), doc = " ```rust,ignore")]
Expand Down Expand Up @@ -299,6 +313,8 @@ pub mod marker {

impl_from!(AngleKind, Kind);
impl_from!(Kind, AngleKind);
impl_from!(SolidAngleKind, Kind);
impl_from!(Kind, SolidAngleKind);
impl_from!(InformationKind, Kind);
impl_from!(Kind, InformationKind);
impl_from!(ConstituentConcentrationKind, Kind);
Expand Down
114 changes: 114 additions & 0 deletions src/si/solid_angle.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
//! Solid angle (dimensionless quantity).
quantity! {
/// Solid angle (dimensionless quantity).
quantity: SolidAngle; "solid angle";
/// Dimension of solid angle, 1 (dimensionless).
dimension: ISQ<
Z0, // length
Z0, // mass
Z0, // time
Z0, // electric current
Z0, // thermodynamic temperature
Z0, // amount of substance
Z0>; // luminous intensity
kind: dyn (::si::marker::SolidAngleKind);
units {
/// SI derived unit of solid angle is steradians. It is the solid angle subtended at the
/// center of a unit sphere by a unit area on its surface.
@steradian: 1.0_E0; "sr", "steradian", "steradians";
@spat: 1.256_637_061_435_917_3_E1; "sp", "spat", "spats";
@square_degree: 3.046_174_197_867_086_E-4; "°²", "square degree", "square degrees";
@square_minute: 8.461_594_994_075_238_9_E-8; "′²", "square minute", "square minutes";
@square_second: 2.350_443_053_909_788_6_E-11; "″²", "square second", "square seconds";
}
}

#[cfg(feature = "f32")]
impl SolidAngle<::si::SI<f32>, f32> {
/// The solid angle subtended by a sphere at its center, i.e. with a value 4π as measured in
/// steradians.
pub const SPHERE: Self = Self {
dimension: ::lib::marker::PhantomData,
units: ::lib::marker::PhantomData,
value: 4. * ::lib::f32::consts::PI,
};
}

#[cfg(feature = "f64")]
impl SolidAngle<::si::SI<f64>, f64> {
/// The solid angle subtended by a sphere at its center, i.e. with a value 4π as measured in
/// steradians.
pub const SPHERE: Self = Self {
dimension: ::lib::marker::PhantomData,
units: ::lib::marker::PhantomData,
value: 4. * ::lib::f64::consts::PI,
};
}

mod convert {
use super::*;

impl<U, V> ::lib::convert::From<V> for SolidAngle<U, V>
where
U: ::si::Units<V> + ?Sized,
V: ::num::Num + ::Conversion<V>,
{
fn from(t: V) -> Self {
SolidAngle {
dimension: ::lib::marker::PhantomData,
units: ::lib::marker::PhantomData,
value: t,
}
}
}

storage_types! {
use super::*;

impl<U> ::lib::convert::From<SolidAngle<U, V>> for V
where
U: ::si::Units<V> + ?Sized,
V: ::num::Num + ::Conversion<V>,
{
fn from(t: SolidAngle<U, V>) -> Self {
t.value
}
}
}
}

#[cfg(test)]
mod tests {
storage_types! {
use ::lib::f64::consts::PI;
use num::{FromPrimitive, One};
use si::solid_angle as sa;
use si::quantities::*;
use tests::Test;

#[test]
fn from() {
let r1: SolidAngle<V> = SolidAngle::<V>::from(V::one());
let r2: SolidAngle<V> = V::one().into();
let _: V = V::from(r1);
let _: V = r2.into();
}

#[test]
fn check_units() {
Test::assert_eq(&SolidAngle::new::<sa::steradian>(V::from_f64(4.0 * PI).unwrap()),
&SolidAngle::new::<sa::spat>(V::one()));
Test::assert_approx_eq(
&SolidAngle::new::<sa::square_degree>(V::from_f64(360.0 * 360.0 / PI).unwrap()),
&SolidAngle::new::<sa::spat>(V::one()));
Test::assert_approx_eq(
&SolidAngle::new::<sa::square_minute>(V::from_f64(60.0 * 60.0).unwrap()),
&SolidAngle::new::<sa::square_degree>(V::one()));
Test::assert_approx_eq(
&SolidAngle::new::<sa::square_second>(
V::from_f64((60.0 * 60.0) * (60.0 * 60.0)).unwrap()),
&SolidAngle::new::<sa::square_degree>(V::one()));
}
}
}

0 comments on commit 5dca5a6

Please sign in to comment.