Bangle
The bangle crate provides strongly-typed floating point angles,
specified in radians, degrees, rotations, or percentages,
with efficient and ergonomic conversion between units.
Both f32 and f64 numeric types are supported,
with f32 being the implicit default.
All conversions, for each unit and numeric type,
are covered by tests, and the library is fully no_std compatible.
bangle is especially intended for situations where local code clarity
may be enhanced by specifying or modifying an angle in units other than radians.
Creating an Angle
The core type is simply called Angle, and it has a dedicated constructor
named for each supported unit type:
use Angle;
use PI;
let degrees = degrees;
let radians = radians;
let rotations = rotations;
let percentage = percentage;
Converting between types
Once you have an Angle, you can convert it to any other type
via similarly named functions:
let degrees = degrees;
let radians = degrees.as_radians;
let rotations = degrees.as_rotations;
let percentage = degrees.as_percentage;
Accessing the numeric value
The value of an Angle is stored in the public value member:
let mut degrees = degrees;
assert_eq!;
degrees.value = 180.0;
assert_eq!;
degrees.value *= 2.0;
assert_eq!;
Adding and subtracting
You can add and subtract angles of different types, and the result will be an angle of whatever type is on the lefthand side of the operation:
let degrees = degrees;
let radians = radians;
let rotations = rotations;
let percentage = percentage;
let full_circle_in_degrees = degrees + radians + rotations + percentage;
assert_ulps_eq!;
Multiplying and dividing
You can also multiply and divide angles by floating point numbers:
let mut degrees = degrees;
degrees *= 4.0;
assert_ulps_eq!;
degrees /= 2.0;
assert_ulps_eq!;
Function arguments
If you want to ensure that a function receives an Angle of a particular type,
you can specify that type explicitly:
let angle = radians;
assert_ulps_eq!;
Or use one of the crate's type aliases:
use AngleInRadians;
let angle = radians;
assert_ulps_eq!;
Alternatively, you could allow callers to provide other angle units,
or raw floating point numbers, by using the Into trait:
let radians = radians;
let degrees = degrees;
assert_ulps_eq!;
assert_ulps_eq!;
assert_ulps_eq!;
As a final option, you could make a function completely generic:
let radians = radians;
let degrees = degrees;
assert_ulps_eq!;
assert_ulps_eq!;
High resolution (64-bit) angles
By default, Bangle uses f32 numbers for storing angle values.
If your use case requires higher precision,
you can use f64 numbers by overriding the appropriate generic argument:
let angle_a = radians;
let angle_b = radians;
assert_ulps_eq!;
Note that, in most cases, you don't need to do anything unusual when creating an Angle
to be passed into such functions - Rust will typically infer the use of f64 numbers automatically.
Running the tests
Bangle includes a full suite of tests, which (according to Tarpaulin) provides 100% coverage of all library code.
(To verify this, install Tarpaulin, use cargo tarpaulin -o html within Bangle's crate directory to run all tests,
and examine the HTML output file in the Bangle crate's root directory.)
You can also run all tests via the cargo test command,
or use cargo-nextest (recommended) to run the main test suite via the command cargo nextest run,
and then use cargo test --doc to test the examples in this documentation.
In conclusion
If you find this library useful, and you're curious to know what else I might be building or doing, you might enjoy visiting my website, where you'll find content dating back all the way to the late 90s.