# quaternion-wrapper
[](https://crates.io/crates/quaternion-wrapper)
[](https://docs.rs/quaternion-wrapper)


This is a wrapper for the
[quaternion-core](https://crates.io/crates/quaternion-core)
crate.
Provides quaternion operations and interconversion with several attitude representations.
Operator overloading allows implementation similar to mathematical expressions.
## Usage
Add this to your `Cargo.toml`:
```toml
[dependencies]
quaternion-wrapper = "0.3"
```
For use in a `no_std` environment:
```toml
[dependencies.quaternion-wrapper]
version = "0.3"
default-features = false
features = ["libm"]
```
## Operator Overloading
Operator overloading allows operations between `QuaternionWrapper`, `Vector3Wrapper`, and `ScalarWrapper`.
The supported operations are listed in the table below:
| __QuaternionWrapper__ | `+`, `-`, `*`, `+=`, `-=`, `*=` | `+`, `-`, `*` | `+`, `-`, `*`, `/` |
| __Vector3Wrapper__ | `+`, `-`, `*` | `+`, `-`, `*`, `+=`, `-=` | `+`, `-`, `*`, `/` |
| __ScalarWrapper__ | `+`, `-`, `*` | `+`, `-`, `*` | `+`, `-`, `*`, `/`, `+=`, `-=`, `*=`, `/=` |
To prevent implementation errors by users, the operation with `T` (`f32` or `f64`) is
intentionally not implemented.
That is, `ScalarWrapper<f64> * QuaternionWrapper<f64>` can be calculated,
but `f64 * QuaternionWrapper<f64>` cannot.
## Features
### fma
When this feature is enabled, the
[mul_add](https://docs.rs/num-traits/0.2.15/num_traits/float/trait.Float.html#tymethod.mul_add)
method will be used internally as much as possible.
That is, `(s * a) + b` will be expanded as `s.mul_add(a, b)` at compile time.
This crate uses the `mul_add` method mainly to improve calculation speed, but if the CPU does
not support the `FMA` (Fused Multiply-Add) instruction or if the `libm` feature is
enabled, then the calculation is performed by the software implementation.
In this case, it may be rather slower than if the `fma` feature is not enabled.
### libm
If you set `default-features=false` (do not import `std`), you must enable this feature.
In this case, mathematical functions (e.g. `sin`, `cos`, `sqrt` ...) are provided by
[libm](https://crates.io/crates/libm) crate.
### norm-sqrt
By default, the `a.norm()` method is implemented in such a way that overflow and
underflow are less likely to occur than with `dot(a, a).sqrt()`. However, if extremely
large values are not input and underflow is not that much of a concern,
`dot(a, a).sqrt()` is sufficient (and `dot(a, a).sqrt()` is faster than the default implementation in most cases).
## Example
`src/main.rs`:
```rust
use quaternion_wrapper::{QuaternionWrapper, Vector3Wrapper};
const PI: f64 = std::f64::consts::PI;
const EPSILON: f64 = 1e-12;
fn main() {
// Generates a quaternion representing the
// rotation of π/2[rad] around the y-axis.
let q = QuaternionWrapper::from_axis_angle([0.0, 1.0, 0.0], PI/2.0);
// Point
let v = Vector3Wrapper([2.0, 2.0, 0.0]);
let result = (q * v * q.conj()).get_vector_part();
//let result = q.point_rotation(v); // <--- It could be written like this
// Check if the calculation is correct.
let true_val = Vector3Wrapper([0.0, 2.0, -2.0]);
let diff: [f64; 3] = (true_val - result).unwrap();
for val in diff {
assert!(val.abs() < EPSILON);
}
}
```
## License
Licensed under either of
[Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0)
or
[MIT License](https://opensource.org/licenses/MIT)
at your option.
### Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall
be dual licensed as above, without any additional terms or conditions.