[][src]Trait vek::ops::Wrap

pub trait Wrap<Bound = Self>: Sized {
    fn wrapped(self, upper: Bound) -> Self;
fn wrapped_between(self, lower: Bound, upper: Bound) -> Self;
fn pingpong(self, upper: Bound) -> Self; fn wrap(val: Self, upper: Bound) -> Self { ... }
fn wrapped_2pi(self) -> Self
    where
        Bound: FloatConst + Add<Output = Bound>
, { ... }
fn wrap_2pi(val: Self) -> Self
    where
        Bound: FloatConst + Add<Output = Bound>
, { ... }
fn wrap_between(val: Self, lower: Bound, upper: Bound) -> Self
    where
        Self: Sub<Output = Self> + Add<Output = Self> + From<Bound>,
        Bound: Copy + Sub<Output = Bound> + PartialOrd
, { ... }
fn delta_angle(self, target: Self) -> Self
    where
        Self: From<Bound> + Sub<Output = Self> + PartialOrd,
        Bound: FloatConst + Add<Output = Bound>
, { ... }
fn delta_angle_degrees(self, target: Self) -> Self
    where
        Self: From<Bound> + Sub<Output = Self> + PartialOrd,
        Bound: From<u16>
, { ... } }

A value that can wrap itself around given bounds.

Required methods

fn wrapped(self, upper: Bound) -> Self

Returns this value, wrapped between zero and some upper bound (both inclusive).

The computation is self - (self/upper).floor() * upper.

This might look like the remainder (%) operator, but behaves differently with negative values.

If you're familiar with Unity, this is the Mathf.Repeat() function.

Panics

Panics if upper <= 0. Reasons include :

  • Some types may implement it as self.wrapped_between(zero, upper). A negative upper would violate the lower <= upper requirement in this case;
  • On unsigned integers, this just resolves to self % upper, and integer division by zero is forbidden. Testing for i==0 incurs unnecessary overhead.
  • Handling negative upper values would double the number of test cases and increases implementation complexity;
use vek::ops::Wrap;

assert_eq!((-5_i32).wrapped(3), 1);
assert_eq!((-4_i32).wrapped(3), 2);
assert_eq!((-3_i32).wrapped(3), 0);
assert_eq!((-2_i32).wrapped(3), 1);
assert_eq!((-1_i32).wrapped(3), 2);
assert_eq!(0_i32.wrapped(3), 0);
assert_eq!(1_i32.wrapped(3), 1);
assert_eq!(2_i32.wrapped(3), 2);
assert_eq!(3_i32.wrapped(3), 0);
assert_eq!(4_i32.wrapped(3), 1);
assert_eq!(5_i32.wrapped(3), 2);

fn wrapped_between(self, lower: Bound, upper: Bound) -> Self

Returns this value, wrapped between lower (inclusive) and upper (exclusive).

Panics

Panics if lower >= upper. Swap the values yourself if necessary.

Also panics if lower < 0 or upper <= 0. See wrapped() for a rationale. Forcing lower and upper to be positive allows implementations to be simpler and faster.

use vek::ops::Wrap;

assert_eq!((-4_i32).wrapped_between(2, 5), 2);
assert_eq!((-3_i32).wrapped_between(2, 5), 3);
assert_eq!((-2_i32).wrapped_between(2, 5), 4);
assert_eq!((-1_i32).wrapped_between(2, 5), 2);
assert_eq!(  0_i32 .wrapped_between(2, 5), 3);
assert_eq!(  1_i32 .wrapped_between(2, 5), 4);
assert_eq!(  2_i32 .wrapped_between(2, 5), 2);
assert_eq!(  3_i32 .wrapped_between(2, 5), 3);
assert_eq!(  4_i32 .wrapped_between(2, 5), 4);
assert_eq!(  5_i32 .wrapped_between(2, 5), 2);
assert_eq!(  6_i32 .wrapped_between(2, 5), 3);

fn pingpong(self, upper: Bound) -> Self

Wraps a value such that it goes back and forth from zero to upper (inclusive) as it increases.

Panics

Panics if upper <= 0. See wrapped() for a rationale.

use vek::ops::Wrap;

assert_eq!((-4_i32).pingpong(3), 2);
assert_eq!((-3_i32).pingpong(3), 3);
assert_eq!((-2_i32).pingpong(3), 2);
assert_eq!((-1_i32).pingpong(3), 1);
assert_eq!(  0_i32 .pingpong(3), 0);
assert_eq!(  1_i32 .pingpong(3), 1);
assert_eq!(  2_i32 .pingpong(3), 2);
assert_eq!(  3_i32 .pingpong(3), 3);
assert_eq!(  4_i32 .pingpong(3), 2);
assert_eq!(  5_i32 .pingpong(3), 1);
assert_eq!(  6_i32 .pingpong(3), 0);
assert_eq!(  7_i32 .pingpong(3), 1);
Loading content...

Provided methods

fn wrap(val: Self, upper: Bound) -> Self

Alias to wrapped() which doesn't take self.

Panics

Panics if upper <= 0. See wrapped() for a rationale.

fn wrapped_2pi(self) -> Self where
    Bound: FloatConst + Add<Output = Bound>, 

Returns this value, wrapped between zero and two times 𝛑 (inclusive).

This ought to be named wrapped_tau, but I assume people are more familiar with 𝛑, and 2pi is therefore more evocative.

fn wrap_2pi(val: Self) -> Self where
    Bound: FloatConst + Add<Output = Bound>, 

Alias to wrapped_2pi which doesn't take self.

This ought to be named wrap_tau, but I assume people are more familiar with 𝛑, and 2pi is therefore more evocative.

fn wrap_between(val: Self, lower: Bound, upper: Bound) -> Self where
    Self: Sub<Output = Self> + Add<Output = Self> + From<Bound>,
    Bound: Copy + Sub<Output = Bound> + PartialOrd

Alias to wrapped_between which doesn't take self.

Panics

Panics if lower is greater than upper. Swap the values yourself if necessary.

fn delta_angle(self, target: Self) -> Self where
    Self: From<Bound> + Sub<Output = Self> + PartialOrd,
    Bound: FloatConst + Add<Output = Bound>, 

Calculates the shortest difference between two given angles, in radians.

fn delta_angle_degrees(self, target: Self) -> Self where
    Self: From<Bound> + Sub<Output = Self> + PartialOrd,
    Bound: From<u16>, 

Calculates the shortest difference between two given angles, in degrees.

This exists because it's enough for Bound to implement From<u16>.

Loading content...

Implementations on Foreign Types

impl Wrap<f32> for f32[src]

impl Wrap<f64> for f64[src]

impl Wrap<u8> for u8[src]

impl Wrap<u16> for u16[src]

impl Wrap<u32> for u32[src]

impl Wrap<u64> for u64[src]

impl Wrap<usize> for usize[src]

impl Wrap<Wrapping<u8>> for Wrapping<u8>[src]

impl Wrap<Wrapping<u16>> for Wrapping<u16>[src]

impl Wrap<Wrapping<u32>> for Wrapping<u32>[src]

impl Wrap<Wrapping<u64>> for Wrapping<u64>[src]

impl Wrap<Wrapping<usize>> for Wrapping<usize>[src]

impl Wrap<i8> for i8[src]

impl Wrap<i16> for i16[src]

impl Wrap<i32> for i32[src]

impl Wrap<i64> for i64[src]

impl Wrap<isize> for isize[src]

impl Wrap<Wrapping<i8>> for Wrapping<i8>[src]

impl Wrap<Wrapping<i16>> for Wrapping<i16>[src]

impl Wrap<Wrapping<i32>> for Wrapping<i32>[src]

impl Wrap<Wrapping<i64>> for Wrapping<i64>[src]

impl Wrap<Wrapping<isize>> for Wrapping<isize>[src]

Loading content...

Implementors

impl<T: Wrap + Copy> Wrap<T> for vek::vec::repr_c::extent2::Extent2<T>[src]

impl<T: Wrap + Copy> Wrap<T> for vek::vec::repr_c::extent3::Extent3<T>[src]

impl<T: Wrap + Copy> Wrap<T> for vek::vec::repr_c::rgb::Rgb<T>[src]

impl<T: Wrap + Copy> Wrap<T> for vek::vec::repr_c::rgba::Rgba<T>[src]

impl<T: Wrap + Copy> Wrap<T> for vek::vec::repr_c::vec2::Vec2<T>[src]

impl<T: Wrap + Copy> Wrap<T> for vek::vec::repr_c::vec3::Vec3<T>[src]

impl<T: Wrap + Copy> Wrap<T> for vek::vec::repr_c::vec4::Vec4<T>[src]

impl<T: Wrap + Copy> Wrap<T> for vek::vec::repr_simd::extent2::Extent2<T>[src]

impl<T: Wrap + Copy> Wrap<T> for vek::vec::repr_simd::extent3::Extent3<T>[src]

impl<T: Wrap + Copy> Wrap<T> for vek::vec::repr_simd::rgb::Rgb<T>[src]

impl<T: Wrap + Copy> Wrap<T> for vek::vec::repr_simd::rgba::Rgba<T>[src]

impl<T: Wrap + Copy> Wrap<T> for vek::vec::repr_simd::vec2::Vec2<T>[src]

impl<T: Wrap + Copy> Wrap<T> for vek::vec::repr_simd::vec3::Vec3<T>[src]

impl<T: Wrap + Copy> Wrap<T> for vek::vec::repr_simd::vec4::Vec4<T>[src]

impl<T: Wrap> Wrap<Extent2<T>> for vek::vec::repr_c::extent2::Extent2<T>[src]

impl<T: Wrap> Wrap<Extent3<T>> for vek::vec::repr_c::extent3::Extent3<T>[src]

impl<T: Wrap> Wrap<Rgb<T>> for vek::vec::repr_c::rgb::Rgb<T>[src]

impl<T: Wrap> Wrap<Rgba<T>> for vek::vec::repr_c::rgba::Rgba<T>[src]

impl<T: Wrap> Wrap<Vec2<T>> for vek::vec::repr_c::vec2::Vec2<T>[src]

impl<T: Wrap> Wrap<Vec3<T>> for vek::vec::repr_c::vec3::Vec3<T>[src]

impl<T: Wrap> Wrap<Vec4<T>> for vek::vec::repr_c::vec4::Vec4<T>[src]

impl<T: Wrap> Wrap<Extent2<T>> for vek::vec::repr_simd::extent2::Extent2<T>[src]

impl<T: Wrap> Wrap<Extent3<T>> for vek::vec::repr_simd::extent3::Extent3<T>[src]

impl<T: Wrap> Wrap<Rgb<T>> for vek::vec::repr_simd::rgb::Rgb<T>[src]

impl<T: Wrap> Wrap<Rgba<T>> for vek::vec::repr_simd::rgba::Rgba<T>[src]

impl<T: Wrap> Wrap<Vec2<T>> for vek::vec::repr_simd::vec2::Vec2<T>[src]

impl<T: Wrap> Wrap<Vec3<T>> for vek::vec::repr_simd::vec3::Vec3<T>[src]

impl<T: Wrap> Wrap<Vec4<T>> for vek::vec::repr_simd::vec4::Vec4<T>[src]

Loading content...