Skip to content

Commit 237234e

Browse files
author
James O'Cull
authored
Merge pull request #8 from thejpster/weight_and_mass
Split weight into mass and force, and add area.
2 parents 2f03d7c + 0ec4969 commit 237234e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+4019
-1908
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ target
22
Cargo.lock
33
*.bk
44
.vscode
5+
*.sublime-workspace

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "measurements"
3-
version = "0.5.0"
3+
version = "0.6.0"
44
authors = ["James O'Cull <[email protected]>",
55
"Jonathan Pallant <[email protected]>",
66
"Hannah McLaughlin <[email protected]>"]

clippy.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
doc-valid-idents = ["MHz", "THz", "GHz", "kHz"]

examples/engine.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
extern crate measurements;
2+
use measurements::{Power, AngularVelocity};
3+
4+
fn main() {
5+
let power = Power::from_ps(225.0);
6+
let peak_revs = AngularVelocity::from_rpm(6000.0);
7+
let torque = power / peak_revs;
8+
println!(
9+
"At {:.0} rpm, a {:.1} ({:.1} PS) engine, produces {:.1} ({:.1} lbf·ft)",
10+
peak_revs.as_rpm(),
11+
power,
12+
power.as_ps(),
13+
torque,
14+
torque.as_pound_foot()
15+
);
16+
}

examples/format_test.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
11
extern crate measurements;
2-
use measurements::Temperature;
3-
use measurements::Length;
4-
use measurements::Pressure;
5-
use measurements::Volume;
6-
use measurements::Weight;
7-
use measurements::Speed;
8-
use measurements::Acceleration;
9-
use measurements::Energy;
10-
use measurements::Power;
11-
use measurements::Data;
2+
use measurements::*;
123

134
fn main() {
145
for power in -12..12 {
15-
let val: f64 = 123.456 * (10f64.powf(power as f64));
6+
let val: f64 = 123.456 * (10f64.powf(f64::from(power)));
167
println!("10^{}...", power);
178
println!("Temp of {0:.3} outside", Temperature::from_kelvin(val));
189
println!("Distance of {0:.3}", Length::from_meters(val));
1910
println!("Pressure of {0:.3}", Pressure::from_millibars(val));
2011
println!("Volume of {0:.3}", Volume::from_litres(val));
21-
println!("Weight of {0:.3}", Weight::from_kilograms(val));
12+
println!("Mass of {0:.3}", Mass::from_kilograms(val));
2213
println!("Speed of {0:.3}", Speed::from_meters_per_second(val));
23-
println!("Acceleration of {0:.3}", Acceleration::from_meters_per_second_per_second(val));
14+
println!(
15+
"Acceleration of {0:.3}",
16+
Acceleration::from_meters_per_second_per_second(val)
17+
);
2418
println!("Energy of {0:.3}", Energy::from_joules(val));
2519
println!("Power of {0:.3}", Power::from_watts(val));
20+
println!("Force of {0:.3}", Force::from_newtons(val));
21+
println!("Force of {0:.3}", Torque::from_newton_metres(val));
22+
println!(
23+
"Force of {0:.3}",
24+
AngularVelocity::from_radians_per_second(val)
25+
);
2626
println!("Data size is {0:.3}", Data::from_octets(val));
2727
}
2828
}

examples/frequency.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
extern crate measurements;
2+
3+
fn main() {
4+
// Sinusiodal Oscilator moves at 5 Hz across 50 mm
5+
let f = measurements::Frequency::from_hertz(5.0);
6+
let d = measurements::Distance::from_millimeters(50.0);
7+
// Speed = PI * Frequency * Displacement
8+
// Speed = PI * Displacement / Period
9+
let v = ::std::f64::consts::PI * d / f.as_period();
10+
println!(
11+
"Maximum speed of a pendulum at {:.1} with max displacement {:.1} is {:.1}",
12+
f,
13+
d,
14+
v
15+
);
16+
}

src/acceleration.rs

Lines changed: 101 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
//! Types and constants for handling acceleration.
2+
13
use super::measurement::*;
2-
use super::Speed;
3-
use std::time::Duration;
4+
use super::length;
45

56
/// The `Acceleration` struct can be used to deal with Accelerations in a common way.
67
/// Common metric and imperial units are supported.
@@ -15,7 +16,7 @@ use std::time::Duration;
1516
/// let track = Length::from_miles(0.25);
1617
/// let finish = Speed::from_miles_per_hour(120.0);
1718
/// let time = Duration::new(10, 0);
18-
/// let accel = finish / time;
19+
/// let accel: Acceleration = finish / time;
1920
/// println!("You accelerated over {} at an average of {}", track, accel);
2021
/// ```
2122
#[derive(Copy, Clone, Debug)]
@@ -24,45 +25,41 @@ pub struct Acceleration {
2425
}
2526

2627
impl Acceleration {
28+
/// Create a new Acceleration from a floating point value in meters per second per second
2729
pub fn from_meters_per_second_per_second(meters_per_second_per_second: f64) -> Acceleration {
2830
Acceleration { meters_per_second_per_second: meters_per_second_per_second }
2931
}
3032

33+
/// Create a new Acceleration from a floating point value in metres per second per second
3134
pub fn from_metres_per_second_per_second(metres_per_second_per_second: f64) -> Acceleration {
3235
Acceleration::from_meters_per_second_per_second(metres_per_second_per_second)
3336
}
3437

38+
/// Create a new Acceleration from a floating point value in feet per second per second
39+
pub fn from_feet_per_second_per_second(feet_per_second_per_second: f64) -> Acceleration {
40+
Acceleration::from_metres_per_second_per_second(
41+
feet_per_second_per_second / length::METER_FEET_FACTOR,
42+
)
43+
}
44+
45+
/// Convert this Acceleration to a value in meters per second per second
3546
pub fn as_meters_per_second_per_second(&self) -> f64 {
3647
self.meters_per_second_per_second
3748
}
3849

50+
/// Convert this Acceleration to a value in metres per second per second
3951
pub fn as_metres_per_second_per_second(&self) -> f64 {
4052
self.as_meters_per_second_per_second()
4153
}
42-
}
4354

44-
/// Acceleration * Time = Speed
45-
impl ::std::ops::Mul<Duration> for Acceleration {
46-
type Output = Speed;
47-
48-
fn mul(self, rhs: Duration) -> Speed {
49-
// It would be useful if Duration had a method that did this...
50-
let seconds: f64 = rhs.as_secs() as f64 + ((rhs.subsec_nanos() as f64) * 1e-9);
51-
Speed::from_meters_per_second(self.as_meters_per_second_per_second() * seconds)
52-
}
53-
}
54-
55-
/// Time * Acceleration = Speed
56-
impl ::std::ops::Mul<Acceleration> for Duration {
57-
type Output = Speed;
58-
59-
fn mul(self, rhs: Acceleration) -> Speed {
60-
rhs * self
55+
/// Convert this Acceleration to a value in feet per second per second
56+
pub fn as_feet_per_second_per_second(&self) -> f64 {
57+
self.meters_per_second_per_second * length::METER_FEET_FACTOR
6158
}
6259
}
6360

6461
impl Measurement for Acceleration {
65-
fn get_base_units(&self) -> f64 {
62+
fn as_base_units(&self) -> f64 {
6663
self.meters_per_second_per_second
6764
}
6865

@@ -76,3 +73,85 @@ impl Measurement for Acceleration {
7673
}
7774

7875
implement_measurement! { Acceleration }
76+
77+
#[cfg(test)]
78+
mod test {
79+
80+
use super::*;
81+
use test_utils::assert_almost_eq;
82+
use std::time::Duration;
83+
use speed::Speed;
84+
85+
// Metric
86+
#[test]
87+
fn speed_over_time() {
88+
let s1 = Speed::from_meters_per_second(10.0);
89+
let t1 = Duration::new(5, 0);
90+
let i1 = s1 / t1;
91+
let r1 = i1.as_meters_per_second_per_second();
92+
assert_almost_eq(r1, 2.0);
93+
}
94+
95+
// Traits
96+
#[test]
97+
fn add() {
98+
let a = Acceleration::from_meters_per_second_per_second(2.0);
99+
let b = Acceleration::from_meters_per_second_per_second(4.0);
100+
let c = a + b;
101+
let d = b + a;
102+
assert_almost_eq(c.as_meters_per_second_per_second(), 6.0);
103+
assert_eq!(c, d);
104+
}
105+
106+
#[test]
107+
fn sub() {
108+
let a = Acceleration::from_meters_per_second_per_second(2.0);
109+
let b = Acceleration::from_meters_per_second_per_second(4.0);
110+
let c = a - b;
111+
assert_almost_eq(c.as_meters_per_second_per_second(), -2.0);
112+
}
113+
114+
#[test]
115+
fn mul() {
116+
let a = Acceleration::from_meters_per_second_per_second(3.0);
117+
let b = a * 2.0;
118+
let c = 2.0 * a;
119+
assert_almost_eq(b.as_meters_per_second_per_second(), 6.0);
120+
assert_eq!(b, c);
121+
}
122+
123+
#[test]
124+
fn div() {
125+
let a = Acceleration::from_meters_per_second_per_second(2.0);
126+
let b = Acceleration::from_meters_per_second_per_second(4.0);
127+
let c = a / b;
128+
let d = a / 2.0;
129+
assert_almost_eq(c, 0.5);
130+
assert_almost_eq(d.as_meters_per_second_per_second(), 1.0);
131+
}
132+
133+
#[test]
134+
fn eq() {
135+
let a = Acceleration::from_meters_per_second_per_second(2.0);
136+
let b = Acceleration::from_meters_per_second_per_second(2.0);
137+
assert_eq!(a == b, true);
138+
}
139+
140+
#[test]
141+
fn neq() {
142+
let a = Acceleration::from_meters_per_second_per_second(2.0);
143+
let b = Acceleration::from_meters_per_second_per_second(4.0);
144+
assert_eq!(a == b, false);
145+
}
146+
147+
#[test]
148+
fn cmp() {
149+
let a = Acceleration::from_meters_per_second_per_second(2.0);
150+
let b = Acceleration::from_meters_per_second_per_second(4.0);
151+
assert_eq!(a < b, true);
152+
assert_eq!(a <= b, true);
153+
assert_eq!(a > b, false);
154+
assert_eq!(a >= b, false);
155+
}
156+
157+
}

src/angle.rs

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
//! Types and constants for handling angles
2+
3+
use super::measurement::*;
4+
5+
/// The 'Angle' struct can be used to deal with angles in a common way.
6+
///
7+
/// # Example
8+
///
9+
/// ```
10+
/// use measurements::Angle;
11+
///
12+
/// let whole_cake = Angle::from_degrees(360.0);
13+
/// let pieces = 6.0;
14+
/// let slice = whole_cake / pieces;
15+
/// println!("Each slice will be {} degrees", slice.as_degrees());
16+
/// ```
17+
#[derive(Copy, Clone, Debug)]
18+
pub struct Angle {
19+
radians: f64,
20+
}
21+
22+
impl Angle {
23+
/// Create a new Angle from a floating point value in degrees
24+
pub fn from_degrees(degrees: f64) -> Self {
25+
Angle::from_radians(degrees.to_radians())
26+
}
27+
28+
/// Create a new Angle from a floating point value in radians
29+
pub fn from_radians(radians: f64) -> Self {
30+
Angle { radians: radians }
31+
}
32+
33+
/// Convert this Angle to a floating point value in degrees
34+
pub fn as_degrees(&self) -> f64 {
35+
self.radians.to_degrees()
36+
}
37+
38+
/// Convert this Angle to a floating point value in radians
39+
pub fn as_radians(&self) -> f64 {
40+
self.radians
41+
}
42+
43+
/// Calculate the cosine of this angle
44+
pub fn cos(&self) -> f64 {
45+
self.radians.cos()
46+
}
47+
48+
/// Calculate the sine of this angle
49+
pub fn sin(&self) -> f64 {
50+
self.radians.sin()
51+
}
52+
53+
/// Calculate the sine and cosine of this angle
54+
pub fn sin_cos(&self) -> (f64, f64) {
55+
self.radians.sin_cos()
56+
}
57+
58+
/// Calculate the tangent of this angle
59+
pub fn tan(&self) -> f64 {
60+
self.radians.tan()
61+
}
62+
63+
/// Calculate the arcsine of a number
64+
pub fn asin(num: f64) -> Self {
65+
Angle::from_radians(num.asin())
66+
}
67+
68+
/// Calculate the arccosine of a number
69+
pub fn acos(num: f64) -> Self {
70+
Angle::from_radians(num.acos())
71+
}
72+
73+
/// Calculate the arctangent of a number
74+
pub fn atan(num: f64) -> Self {
75+
Angle::from_radians(num.atan())
76+
}
77+
}
78+
79+
impl Measurement for Angle {
80+
fn as_base_units(&self) -> f64 {
81+
self.radians
82+
}
83+
84+
fn from_base_units(units: f64) -> Self {
85+
Self::from_radians(units)
86+
}
87+
88+
fn get_base_units_name(&self) -> &'static str {
89+
"rad"
90+
}
91+
}
92+
93+
implement_measurement! { Angle }
94+
95+
#[cfg(test)]
96+
mod test {
97+
use angle::*;
98+
use std::f64::consts::PI;
99+
use test_utils::assert_almost_eq;
100+
101+
#[test]
102+
fn radians() {
103+
let i1 = Angle::from_degrees(360.0);
104+
let r1 = i1.as_radians();
105+
let i2 = Angle::from_radians(PI);
106+
let r2 = i2.as_degrees();
107+
assert_almost_eq(r1, 2.0 * PI);
108+
assert_almost_eq(r2, 180.0);
109+
}
110+
}

0 commit comments

Comments
 (0)