Struct agb::fixnum::Vector2D

source ·
pub struct Vector2D<T>
where T: Number,
{ pub x: T, pub y: T, }
Expand description

A vector of two points: (x, y) represented by integers or fixed point numbers

Fields§

§x: T

The x coordinate

§y: T

The y coordinate

Implementations§

source§

impl<T> Vector2D<T>

source

pub fn abs(self) -> Vector2D<T>

Calculates the absolute value of the x and y components.

source§

impl<I, const N: usize> Vector2D<Num<I, N>>

source

pub fn trunc(self) -> Vector2D<I>

Truncates the x and y coordinate, see Num::trunc

let v1: Vector2D<Num<i32, 8>> = (num!(1.56), num!(-2.2)).into();
let v2: Vector2D<i32> = (1, -2).into();
assert_eq!(v1.trunc(), v2);
source

pub fn floor(self) -> Vector2D<I>

Floors the x and y coordinate, see Num::floor

let v1: Vector2D<Num<i32, 8>> = Vector2D::new(num!(1.56), num!(-2.2));
let v2: Vector2D<i32> = (1, -3).into();
assert_eq!(v1.floor(), v2);
Examples found in repository?
examples/windows.rs (line 78)
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
fn main(mut gba: agb::Gba) -> ! {
    let (gfx, mut vram) = gba.display.video.tiled0();

    let mut map = gfx.background(
        agb::display::Priority::P0,
        RegularBackgroundSize::Background32x32,
        TileFormat::FourBpp,
    );
    let mut window = gba.display.window.get();
    window
        .win_in(WinIn::Win0)
        .set_background_enable(map.background(), true)
        .set_position(&Rect::new((10, 10).into(), (64, 64).into()))
        .enable();

    window
        .win_out()
        .enable()
        .set_background_enable(map.background(), true)
        .set_blend_enable(true);

    example_logo::display_logo(&mut map, &mut vram);

    let mut blend = gba.display.blend.get();

    blend
        .set_background_enable(Layer::Top, map.background(), true)
        .set_backdrop_enable(Layer::Bottom, true)
        .set_blend_mode(BlendMode::Normal);

    let mut pos: Vector2D<FNum> = (10, 10).into();
    let mut velocity: Vector2D<FNum> = Vector2D::new(1.into(), 1.into());

    let mut blend_amount: Num<i32, 8> = num!(0.5);
    let mut blend_velocity: Num<i32, 8> = Num::new(1) / 128;

    let vblank = VBlank::get();

    loop {
        pos += velocity;

        if pos.x.floor() > WIDTH - 64 || pos.x.floor() < 0 {
            velocity.x *= -1;
        }

        if pos.y.floor() > HEIGHT - 64 || pos.y.floor() < 0 {
            velocity.y *= -1;
        }

        blend_amount += blend_velocity;
        if blend_amount > num!(0.75) || blend_amount < num!(0.25) {
            blend_velocity *= -1;
        }

        blend_amount = blend_amount.clamp(0.into(), 1.into());

        blend.set_blend_weight(Layer::Top, blend_amount.try_change_base().unwrap());

        window
            .win_in(WinIn::Win0)
            .set_position(&Rect::new(pos.floor(), (64, 64).into()));

        vblank.wait_for_vblank();
        window.commit();
        blend.commit();
    }
}
More examples
Hide additional examples
examples/dma_effect_circular_window.rs (line 89)
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
fn main(mut gba: agb::Gba) -> ! {
    let (gfx, mut vram) = gba.display.video.tiled0();

    let mut map = gfx.background(
        agb::display::Priority::P0,
        RegularBackgroundSize::Background32x32,
        TileFormat::FourBpp,
    );
    let mut window = gba.display.window.get();
    window
        .win_in(WinIn::Win0)
        .set_background_enable(map.background(), true)
        .set_position(&Rect::new((10, 10).into(), (64, 64).into()))
        .enable();

    let dmas = gba.dma.dma();

    example_logo::display_logo(&mut map, &mut vram);

    let mut pos: Vector2D<FNum> = (10, 10).into();
    let mut velocity: Vector2D<FNum> = Vector2D::new(1.into(), 1.into());

    let vblank = VBlank::get();

    let circle: Box<[_]> = (1..64i32)
        .map(|i| {
            let y = 32 - i;
            let x = (32 * 32 - y * y).isqrt();
            let x1 = 32 - x;
            let x2 = 32 + x;

            ((x1 as u16) << 8) | (x2 as u16)
        })
        .collect();

    let mut circle_poses = vec![0; 160];

    loop {
        pos += velocity;

        if pos.x.floor() > WIDTH - 64 || pos.x.floor() < 0 {
            velocity.x *= -1;
        }

        if pos.y.floor() > HEIGHT - 64 || pos.y.floor() < 0 {
            velocity.y *= -1;
        }

        let x_pos = pos.x.floor().max(0) as u16;
        let y_pos = pos.y.floor().max(0);
        let x_adjustment = x_pos << 8 | x_pos;
        for (i, value) in circle_poses.iter_mut().enumerate() {
            let i = i as i32;
            if i <= y_pos || i >= y_pos + 64 {
                *value = 0;
                continue;
            }

            *value = circle[(i - y_pos) as usize - 1] + x_adjustment;
        }

        window
            .win_in(WinIn::Win0)
            .set_position(&Rect::new(pos.floor(), (64, 65).into()));
        window.commit();

        let dma_controllable = window.win_in(WinIn::Win0).horizontal_position_dma();
        let _transfer = unsafe { dmas.dma0.hblank_transfer(&dma_controllable, &circle_poses) };

        vblank.wait_for_vblank();
    }
}
source

pub fn try_change_base<J, const M: usize>(self) -> Option<Vector2D<Num<J, M>>>
where J: FixedWidthUnsignedInteger + TryFrom<I>,

Attempts to change the base returning None if the numbers cannot be represented

source§

impl<const N: usize> Vector2D<Num<i32, N>>

source

pub fn magnitude_squared(self) -> Num<i32, N>

Calculates the magnitude squared, ie (xx + yy)

let v1: Vector2D<Num<i32, 8>> = (num!(3.), num!(4.)).into();
assert_eq!(v1.magnitude_squared(), 25.into());
source

pub fn manhattan_distance(self) -> Num<i32, N>

Calculates the manhattan distance, x.abs() + y.abs().

let v1: Vector2D<Num<i32, 8>> = (num!(3.), num!(4.)).into();
assert_eq!(v1.manhattan_distance(), 7.into());
source

pub fn magnitude(self) -> Num<i32, N>

Calculates the magnitude by square root

let v1: Vector2D<Num<i32, 8>> = (num!(3.), num!(4.)).into();
assert_eq!(v1.magnitude(), 5.into());
source

pub fn fast_magnitude(self) -> Num<i32, N>

Calculates the magnitude of a vector using the alpha max plus beta min algorithm this has a maximum error of less than 4% of the true magnitude, probably depending on the size of your fixed point approximation

let v1: Vector2D<Num<i32, 8>> = (num!(3.), num!(4.)).into();
assert!(v1.fast_magnitude() > num!(4.9) && v1.fast_magnitude() < num!(5.1));
source

pub fn normalise(self) -> Vector2D<Num<i32, N>>

Normalises the vector to magnitude of one by performing a square root, due to fixed point imprecision this magnitude may not be exactly one

let v1: Vector2D<Num<i32, 8>> = (num!(4.), num!(4.)).into();
assert_eq!(v1.normalise().magnitude(), 1.into());
source

pub fn fast_normalise(self) -> Vector2D<Num<i32, N>>

Normalises the vector to magnitude of one using Vector2D::fast_magnitude.

let v1: Vector2D<Num<i32, 8>> = (num!(4.), num!(4.)).into();
assert_eq!(v1.fast_normalise().magnitude(), 1.into());
source§

impl<T> Vector2D<T>
where T: Number,

source

pub fn change_base<U>(self) -> Vector2D<U>
where U: Number + From<T>,

Converts the representation of the vector to another type

let v1: Vector2D<i16> = Vector2D::new(1, 2);
let v2: Vector2D<i32> = v1.change_base();
source§

impl<I, const N: usize> Vector2D<Num<I, N>>

source

pub fn new_from_angle(angle: Num<I, N>) -> Vector2D<Num<I, N>>

Creates a unit vector from an angle, noting that the domain of the angle is [0, 1], see Num::cos and Num::sin.

let v: Vector2D<Num<i32, 8>> = Vector2D::new_from_angle(num!(0.0));
assert_eq!(v, (num!(1.0), num!(0.0)).into());
source§

impl<T> Vector2D<T>
where T: Number,

source

pub const fn new(x: T, y: T) -> Vector2D<T>

Created a vector from the given coordinates

let v = Vector2D::new(1, 2);
assert_eq!(v.x, 1);
assert_eq!(v.y, 2);
Examples found in repository?
examples/windows.rs (line 49)
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
fn main(mut gba: agb::Gba) -> ! {
    let (gfx, mut vram) = gba.display.video.tiled0();

    let mut map = gfx.background(
        agb::display::Priority::P0,
        RegularBackgroundSize::Background32x32,
        TileFormat::FourBpp,
    );
    let mut window = gba.display.window.get();
    window
        .win_in(WinIn::Win0)
        .set_background_enable(map.background(), true)
        .set_position(&Rect::new((10, 10).into(), (64, 64).into()))
        .enable();

    window
        .win_out()
        .enable()
        .set_background_enable(map.background(), true)
        .set_blend_enable(true);

    example_logo::display_logo(&mut map, &mut vram);

    let mut blend = gba.display.blend.get();

    blend
        .set_background_enable(Layer::Top, map.background(), true)
        .set_backdrop_enable(Layer::Bottom, true)
        .set_blend_mode(BlendMode::Normal);

    let mut pos: Vector2D<FNum> = (10, 10).into();
    let mut velocity: Vector2D<FNum> = Vector2D::new(1.into(), 1.into());

    let mut blend_amount: Num<i32, 8> = num!(0.5);
    let mut blend_velocity: Num<i32, 8> = Num::new(1) / 128;

    let vblank = VBlank::get();

    loop {
        pos += velocity;

        if pos.x.floor() > WIDTH - 64 || pos.x.floor() < 0 {
            velocity.x *= -1;
        }

        if pos.y.floor() > HEIGHT - 64 || pos.y.floor() < 0 {
            velocity.y *= -1;
        }

        blend_amount += blend_velocity;
        if blend_amount > num!(0.75) || blend_amount < num!(0.25) {
            blend_velocity *= -1;
        }

        blend_amount = blend_amount.clamp(0.into(), 1.into());

        blend.set_blend_weight(Layer::Top, blend_amount.try_change_base().unwrap());

        window
            .win_in(WinIn::Win0)
            .set_position(&Rect::new(pos.floor(), (64, 64).into()));

        vblank.wait_for_vblank();
        window.commit();
        blend.commit();
    }
}
More examples
Hide additional examples
examples/dma_effect_circular_window.rs (line 46)
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
fn main(mut gba: agb::Gba) -> ! {
    let (gfx, mut vram) = gba.display.video.tiled0();

    let mut map = gfx.background(
        agb::display::Priority::P0,
        RegularBackgroundSize::Background32x32,
        TileFormat::FourBpp,
    );
    let mut window = gba.display.window.get();
    window
        .win_in(WinIn::Win0)
        .set_background_enable(map.background(), true)
        .set_position(&Rect::new((10, 10).into(), (64, 64).into()))
        .enable();

    let dmas = gba.dma.dma();

    example_logo::display_logo(&mut map, &mut vram);

    let mut pos: Vector2D<FNum> = (10, 10).into();
    let mut velocity: Vector2D<FNum> = Vector2D::new(1.into(), 1.into());

    let vblank = VBlank::get();

    let circle: Box<[_]> = (1..64i32)
        .map(|i| {
            let y = 32 - i;
            let x = (32 * 32 - y * y).isqrt();
            let x1 = 32 - x;
            let x2 = 32 + x;

            ((x1 as u16) << 8) | (x2 as u16)
        })
        .collect();

    let mut circle_poses = vec![0; 160];

    loop {
        pos += velocity;

        if pos.x.floor() > WIDTH - 64 || pos.x.floor() < 0 {
            velocity.x *= -1;
        }

        if pos.y.floor() > HEIGHT - 64 || pos.y.floor() < 0 {
            velocity.y *= -1;
        }

        let x_pos = pos.x.floor().max(0) as u16;
        let y_pos = pos.y.floor().max(0);
        let x_adjustment = x_pos << 8 | x_pos;
        for (i, value) in circle_poses.iter_mut().enumerate() {
            let i = i as i32;
            if i <= y_pos || i >= y_pos + 64 {
                *value = 0;
                continue;
            }

            *value = circle[(i - y_pos) as usize - 1] + x_adjustment;
        }

        window
            .win_in(WinIn::Win0)
            .set_position(&Rect::new(pos.floor(), (64, 65).into()));
        window.commit();

        let dma_controllable = window.win_in(WinIn::Win0).horizontal_position_dma();
        let _transfer = unsafe { dmas.dma0.hblank_transfer(&dma_controllable, &circle_poses) };

        vblank.wait_for_vblank();
    }
}
source

pub fn get(self) -> (T, T)

Returns the tuple of the coordinates

let v = Vector2D::new(1, 2);
assert_eq!(v.get(), (1, 2));
source

pub fn hadamard(self, other: Vector2D<T>) -> Vector2D<T>

Calculates the hadamard product of two vectors

let v1 = Vector2D::new(2, 3);
let v2 = Vector2D::new(4, 5);

let r = v1.hadamard(v2);
assert_eq!(r, Vector2D::new(v1.x * v2.x, v1.y * v2.y));
source

pub fn swap(self) -> Vector2D<T>

Swaps the x and y coordinate

let v1 = Vector2D::new(2, 3);
assert_eq!(v1.swap(), Vector2D::new(3, 2));

Trait Implementations§

source§

impl<T> Add for Vector2D<T>
where T: Number,

§

type Output = Vector2D<T>

The resulting type after applying the + operator.
source§

fn add(self, rhs: Vector2D<T>) -> <Vector2D<T> as Add>::Output

Performs the + operation. Read more
source§

impl<T> AddAssign for Vector2D<T>
where T: Number,

source§

fn add_assign(&mut self, rhs: Vector2D<T>)

Performs the += operation. Read more
source§

impl<T> Clone for Vector2D<T>
where T: Clone + Number,

source§

fn clone(&self) -> Vector2D<T>

Returns a copy of the value. Read more
1.0.0§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<T> Debug for Vector2D<T>
where T: Debug + Number,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl<T> Default for Vector2D<T>
where T: Default + Number,

source§

fn default() -> Vector2D<T>

Returns the “default value” for a type. Read more
source§

impl<T, U> Div<U> for Vector2D<T>
where T: Number<Output = T> + Div<U>, U: Copy,

§

type Output = Vector2D<T>

The resulting type after applying the / operator.
source§

fn div(self, rhs: U) -> <Vector2D<T> as Div<U>>::Output

Performs the / operation. Read more
source§

impl<T, U> DivAssign<U> for Vector2D<T>
where T: Number<Output = T> + Div<U>, U: Copy,

source§

fn div_assign(&mut self, rhs: U)

Performs the /= operation. Read more
source§

impl<T, P> From<(P, P)> for Vector2D<T>
where T: Number, P: Number + Into<T>,

source§

fn from(f: (P, P)) -> Vector2D<T>

Converts to this type from the input type.
source§

impl<I, const N: usize> From<Vector2D<I>> for Vector2D<Num<I, N>>

source§

fn from(n: Vector2D<I>) -> Vector2D<Num<I, N>>

Converts to this type from the input type.
source§

impl<T> Hash for Vector2D<T>
where T: Hash + Number,

source§

fn hash<__H>(&self, state: &mut __H)
where __H: Hasher,

Feeds this value into the given [Hasher]. Read more
1.3.0§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given [Hasher]. Read more
source§

impl<T, U> Mul<U> for Vector2D<T>
where T: Number<Output = T> + Mul<U>, U: Copy,

§

type Output = Vector2D<T>

The resulting type after applying the * operator.
source§

fn mul(self, rhs: U) -> <Vector2D<T> as Mul<U>>::Output

Performs the * operation. Read more
source§

impl<T, U> MulAssign<U> for Vector2D<T>
where T: Number<Output = T> + Mul<U>, U: Copy,

source§

fn mul_assign(&mut self, rhs: U)

Performs the *= operation. Read more
source§

impl<T> Neg for Vector2D<T>
where T: Number + Neg<Output = T>,

§

type Output = Vector2D<T>

The resulting type after applying the - operator.
source§

fn neg(self) -> <Vector2D<T> as Neg>::Output

Performs the unary - operation. Read more
source§

impl<T> PartialEq for Vector2D<T>
where T: PartialEq + Number,

source§

fn eq(&self, other: &Vector2D<T>) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl<T> Sub for Vector2D<T>
where T: Number,

§

type Output = Vector2D<T>

The resulting type after applying the - operator.
source§

fn sub(self, rhs: Vector2D<T>) -> <Vector2D<T> as Sub>::Output

Performs the - operation. Read more
source§

impl<T> SubAssign for Vector2D<T>
where T: Number,

source§

fn sub_assign(&mut self, rhs: Vector2D<T>)

Performs the -= operation. Read more
source§

impl<T> Copy for Vector2D<T>
where T: Copy + Number,

source§

impl<T> Eq for Vector2D<T>
where T: Eq + Number,

source§

impl<T> StructuralPartialEq for Vector2D<T>
where T: Number,

Auto Trait Implementations§

§

impl<T> RefUnwindSafe for Vector2D<T>
where T: RefUnwindSafe,

§

impl<T> Send for Vector2D<T>
where T: Send,

§

impl<T> Sync for Vector2D<T>
where T: Sync,

§

impl<T> Unpin for Vector2D<T>
where T: Unpin,

§

impl<T> UnwindSafe for Vector2D<T>
where T: UnwindSafe,

Blanket Implementations§

§

impl<T> Any for T
where T: 'static + ?Sized,

§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> Borrow<T> for T
where T: ?Sized,

§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
§

impl<T> BorrowMut<T> for T
where T: ?Sized,

§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> From<T> for T

§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T, U> Into<U> for T
where U: From<T>,

§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of [From]<T> for U chooses to do.

§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.