Trait InnerSpace

Source
pub trait InnerSpace: VectorSpace + MetricSpace<Metric = Self::Scalar> {
    // Required method
    fn dot(self, other: Self) -> Self::Scalar;

    // Provided methods
    fn is_perpendicular(self, other: Self) -> bool
       where Self::Scalar: UlpsEq { ... }
    fn magnitude2(self) -> Self::Scalar { ... }
    fn angle(self, other: Self) -> Rad<Self::Scalar>
       where Self::Scalar: BaseFloat { ... }
    fn project_on(self, other: Self) -> Self { ... }
    fn magnitude(self) -> Self::Scalar
       where Self::Scalar: Float { ... }
    fn normalize(self) -> Self
       where Self::Scalar: Float { ... }
    fn normalize_to(self, magnitude: Self::Scalar) -> Self
       where Self::Scalar: Float { ... }
}
Expand description

Vectors that also have a dot (or inner) product.

The dot product allows for the definition of other useful operations, like finding the magnitude of a vector or normalizing it.

Examples include vectors and quaternions.

Required Methods§

Source

fn dot(self, other: Self) -> Self::Scalar

Vector dot (or inner) product.

Provided Methods§

Source

fn is_perpendicular(self, other: Self) -> bool
where Self::Scalar: UlpsEq,

Returns true if the vector is perpendicular (at right angles) to the other vector.

Source

fn magnitude2(self) -> Self::Scalar

Returns the squared magnitude.

This does not perform an expensive square root operation like in InnerSpace::magnitude method, and so can be used to compare magnitudes more efficiently.

Source

fn angle(self, other: Self) -> Rad<Self::Scalar>
where Self::Scalar: BaseFloat,

Returns the angle between two vectors in radians.

Source

fn project_on(self, other: Self) -> Self

Returns the vector projection of the current inner space projected onto the supplied argument.

Source

fn magnitude(self) -> Self::Scalar
where Self::Scalar: Float,

The distance from the tail to the tip of the vector.

Examples found in repository?
examples/breakout.rs (line 250)
234fn check_player_little_ball_collision(context: &mut Context, player_entity: Entity, little_ball_entity: Entity, random_factor: f32) {
235    let mut little_ball_transform: ComponentRefMut<'_, Transform> = context.world.get_entity_component_mut::<Transform>(&little_ball_entity).unwrap();
236    let mut little_ball_velocity: ComponentRefMut<'_, Velocity> = context.world.get_entity_component_mut::<Velocity>(&little_ball_entity).unwrap();
237    let little_ball_collision: ComponentRef<'_, Collision> = context.world.get_entity_component::<Collision>(&little_ball_entity).unwrap();
238
239    let player_collision: ComponentRef<'_, Collision> = context.world.get_entity_component::<Collision>(&player_entity).unwrap();
240
241    if Collision::check(CollisionAlgorithm::Aabb, &player_collision, &little_ball_collision) {
242        let relative_collision_position: Vector2<f32> = little_ball_collision.collider.position - player_collision.collider.position;
243        
244        let rebound_direction: Vector2<f32> = if relative_collision_position.y > 0.0 {
245            Vector2::new(relative_collision_position.x, 1.0)
246        } else {
247            Vector2::new(relative_collision_position.x, -1.0)
248        };
249        let rebound_vector: Vector2<f32> = (rebound_direction + Vector2::new(random_factor, 0.0)).normalize();
250        let little_ball_new_velocity: Vector2<f32> = rebound_vector * little_ball_velocity.to_vec().magnitude();
251
252        little_ball_velocity.x = little_ball_new_velocity.x; little_ball_velocity.y = little_ball_new_velocity.y;
253        little_ball_transform.position.y += rebound_direction.y * 0.02;
254    }
255}
256
257fn check_little_ball_borders_collision(context: &mut Context, little_ball_entity: Entity, random_factor: f32) {
258    let mut border_query: Query = Query::new(&context.world).with::<Border>();
259    let borders_entities: Vec<Entity> = border_query.entities_with_components().unwrap();
260
261    let mut little_ball_transform: ComponentRefMut<'_, Transform> = context.world.get_entity_component_mut::<Transform>(&little_ball_entity).unwrap();
262    let mut little_ball_velocity: ComponentRefMut<'_, Velocity> = context.world.get_entity_component_mut::<Velocity>(&little_ball_entity).unwrap();
263    let little_ball_collision: ComponentRef<'_, Collision> = context.world.get_entity_component::<Collision>(&little_ball_entity).unwrap();
264
265    for border in &borders_entities {
266        let border_collision: ComponentRef<'_, Collision> = context.world.get_entity_component::<Collision>(border).unwrap();
267
268        if Collision::check(CollisionAlgorithm::Aabb, &little_ball_collision, &border_collision) {
269            if border_collision.collider.position.x > 0.0 {
270                let little_ball_new_velocity: Vector2<f32> =
271                    Vector2::new(-1.0 + random_factor, little_ball_velocity.y.signum()).normalize() * little_ball_velocity.to_vec().magnitude();
272
273                little_ball_velocity.x = little_ball_new_velocity.x; little_ball_velocity.y = little_ball_new_velocity.y;
274                little_ball_transform.position.x -= 0.1;
275            } else if border_collision.collider.position.x < 0.0 {
276                let little_ball_new_velocity: Vector2<f32> =
277                    Vector2::new(1.0 + random_factor, little_ball_velocity.y.signum()).normalize() * little_ball_velocity.to_vec().magnitude();
278
279                little_ball_velocity.x = little_ball_new_velocity.x; little_ball_velocity.y = little_ball_new_velocity.y;
280                little_ball_transform.position.x += 0.1;
281            }
282        }
283    }
284}
285
286fn check_litte_ball_targets_collision(context: &mut Context, little_ball_entity: Entity, random_factor: f32) {
287    let mut targets_query: Query = Query::new(&context.world).with::<Target>();
288    let targets_entities: Vec<Entity> = targets_query.entities_with_components().unwrap();
289
290    let mut little_ball_transform: ComponentRefMut<'_, Transform> = context.world.get_entity_component_mut::<Transform>(&little_ball_entity).unwrap();
291    let mut little_ball_velocity: ComponentRefMut<'_, Velocity> = context.world.get_entity_component_mut::<Velocity>(&little_ball_entity).unwrap();
292    let little_ball_collision: ComponentRef<'_, Collision> = context.world.get_entity_component::<Collision>(&little_ball_entity).unwrap();
293
294    for target in &targets_entities {
295        let target_collision: ComponentRef<'_, Collision> = context.world.get_entity_component::<Collision>(target).unwrap();
296
297        if Collision::check(CollisionAlgorithm::Aabb, &little_ball_collision, &target_collision) {
298            let little_ball_new_velocity: Vector2<f32> =
299                Vector2::new(little_ball_velocity.x.signum(), -1.0 + random_factor).normalize() * little_ball_velocity.to_vec().magnitude();
300
301            little_ball_velocity.x = little_ball_new_velocity.x; little_ball_velocity.y = little_ball_new_velocity.y;
302            little_ball_transform.position.y -= 0.1;
303            context.commands.despawn(target.clone());
304        }
305    }
306}
More examples
Hide additional examples
examples/pong.rs (line 242)
220fn check_rackets_ball_collision(context: &mut Context, pong_ball: &Entity, random_factor: f32) {
221    let mut racket_query: Query = Query::new(&context.world).with::<Racket>();
222    let rackets: Vec<Entity> = racket_query.entities_with_components().unwrap();
223    let mut game_audio: ResourceRefMut<'_, GameAudio> = context.world.get_resource_mut::<GameAudio>().unwrap();
224
225    for racket in &rackets {
226        let racket_collision: ComponentRef<'_, Collision> = context.world.get_entity_component::<Collision>(racket).unwrap();
227        let racket_transform: ComponentRef<'_, Transform> = context.world.get_entity_component::<Transform>(racket).unwrap();
228
229        let pong_ball_collision: ComponentRef<'_, Collision> = context.world.get_entity_component::<Collision>(&pong_ball).unwrap();
230        let mut pong_ball_transform: ComponentRefMut<'_, Transform> = context.world.get_entity_component_mut::<Transform>(&pong_ball).unwrap();
231        let mut pong_ball_velocity: ComponentRefMut<'_, Velocity> = context.world.get_entity_component_mut::<Velocity>(&pong_ball).unwrap();
232
233        if Collision::check(CollisionAlgorithm::Aabb, &racket_collision, &pong_ball_collision) {
234            game_audio.0.play_static_sound("racket_hit".to_string()).ok();
235
236            let relative_collision_point: f32 = pong_ball_transform.position.y - racket_transform.position.y;
237            let rebound_angle: f32 = relative_collision_point * 1.0 + random_factor;
238
239            let pong_ball_new_velocity: Vector2<f32>;
240
241            if racket_transform.position.x > 0.0 {
242                pong_ball_new_velocity = Vector2::new(-1.0, rebound_angle).normalize() * pong_ball_velocity.to_vec().magnitude();
243                pong_ball_velocity.x = pong_ball_new_velocity.x; pong_ball_velocity.y = pong_ball_new_velocity.y;
244                pong_ball_transform.position.x -= 0.1;
245            } else if racket_transform.position.x < 0.0 {
246                pong_ball_new_velocity = Vector2::new(1.0, rebound_angle).normalize() * pong_ball_velocity.to_vec().magnitude();
247                pong_ball_velocity.x = pong_ball_new_velocity.x; pong_ball_velocity.y = pong_ball_new_velocity.y;
248                pong_ball_transform.position.x += 0.1;
249            }
250            let new_position: Vector2<f32> = Vector2::new(pong_ball_transform.position.x, pong_ball_transform.position.y);
251            pong_ball_transform.set_position(&context.render_state, new_position);
252        }
253    }
254}
255
256fn check_borders_ball_collision(context: &mut Context, pong_ball: &Entity, random_factor: f32) {
257    let mut border_query: Query = Query::new(&context.world).with::<Border>();
258    let borders: Vec<Entity> = border_query.entities_with_components().unwrap();
259
260    for border in &borders {
261        let border_collision: ComponentRef<'_, Collision> = context.world.get_entity_component::<Collision>(border).unwrap();
262        let border_transform: ComponentRef<'_, Transform> = context.world.get_entity_component::<Transform>(border).unwrap();
263
264        let pong_ball_collision: ComponentRef<'_, Collision> = context.world.get_entity_component::<Collision>(&pong_ball).unwrap();
265        let mut pong_ball_velocity: ComponentRefMut<'_, Velocity> = context.world.get_entity_component_mut::<Velocity>(&pong_ball).unwrap();
266        let mut pong_ball_transform: ComponentRefMut<'_, Transform> = context.world.get_entity_component_mut::<Transform>(&pong_ball).unwrap();
267
268        let pong_ball_new_velocity: Vector2<f32>;
269
270        if Collision::check(CollisionAlgorithm::Aabb, &border_collision, &pong_ball_collision) {
271            if border_transform.position.y > 0.0 {
272                pong_ball_new_velocity = Vector2::new(pong_ball_velocity.x.signum(), -1.0 + random_factor).normalize() * pong_ball_velocity.to_vec().magnitude();
273                pong_ball_velocity.x = pong_ball_new_velocity.x; pong_ball_velocity.y = pong_ball_new_velocity.y;
274                pong_ball_transform.position.y -= 0.1;
275            } else if border_transform.position.y < 0.0 {
276                pong_ball_new_velocity = Vector2::new(pong_ball_velocity.x.signum(), 1.0 + random_factor).normalize() * pong_ball_velocity.to_vec().magnitude();
277                pong_ball_velocity.x = pong_ball_new_velocity.x; pong_ball_velocity.y = pong_ball_new_velocity.y;
278                pong_ball_transform.position.y += 0.1;
279            }
280            let new_position: Vector2<f32> = Vector2::new(pong_ball_transform.position.x, pong_ball_transform.position.y);
281            pong_ball_transform.set_position(&context.render_state, new_position);
282        }
283    }
284}
Source

fn normalize(self) -> Self
where Self::Scalar: Float,

Returns a vector with the same direction, but with a magnitude of 1.

Examples found in repository?
examples/breakout.rs (line 249)
234fn check_player_little_ball_collision(context: &mut Context, player_entity: Entity, little_ball_entity: Entity, random_factor: f32) {
235    let mut little_ball_transform: ComponentRefMut<'_, Transform> = context.world.get_entity_component_mut::<Transform>(&little_ball_entity).unwrap();
236    let mut little_ball_velocity: ComponentRefMut<'_, Velocity> = context.world.get_entity_component_mut::<Velocity>(&little_ball_entity).unwrap();
237    let little_ball_collision: ComponentRef<'_, Collision> = context.world.get_entity_component::<Collision>(&little_ball_entity).unwrap();
238
239    let player_collision: ComponentRef<'_, Collision> = context.world.get_entity_component::<Collision>(&player_entity).unwrap();
240
241    if Collision::check(CollisionAlgorithm::Aabb, &player_collision, &little_ball_collision) {
242        let relative_collision_position: Vector2<f32> = little_ball_collision.collider.position - player_collision.collider.position;
243        
244        let rebound_direction: Vector2<f32> = if relative_collision_position.y > 0.0 {
245            Vector2::new(relative_collision_position.x, 1.0)
246        } else {
247            Vector2::new(relative_collision_position.x, -1.0)
248        };
249        let rebound_vector: Vector2<f32> = (rebound_direction + Vector2::new(random_factor, 0.0)).normalize();
250        let little_ball_new_velocity: Vector2<f32> = rebound_vector * little_ball_velocity.to_vec().magnitude();
251
252        little_ball_velocity.x = little_ball_new_velocity.x; little_ball_velocity.y = little_ball_new_velocity.y;
253        little_ball_transform.position.y += rebound_direction.y * 0.02;
254    }
255}
256
257fn check_little_ball_borders_collision(context: &mut Context, little_ball_entity: Entity, random_factor: f32) {
258    let mut border_query: Query = Query::new(&context.world).with::<Border>();
259    let borders_entities: Vec<Entity> = border_query.entities_with_components().unwrap();
260
261    let mut little_ball_transform: ComponentRefMut<'_, Transform> = context.world.get_entity_component_mut::<Transform>(&little_ball_entity).unwrap();
262    let mut little_ball_velocity: ComponentRefMut<'_, Velocity> = context.world.get_entity_component_mut::<Velocity>(&little_ball_entity).unwrap();
263    let little_ball_collision: ComponentRef<'_, Collision> = context.world.get_entity_component::<Collision>(&little_ball_entity).unwrap();
264
265    for border in &borders_entities {
266        let border_collision: ComponentRef<'_, Collision> = context.world.get_entity_component::<Collision>(border).unwrap();
267
268        if Collision::check(CollisionAlgorithm::Aabb, &little_ball_collision, &border_collision) {
269            if border_collision.collider.position.x > 0.0 {
270                let little_ball_new_velocity: Vector2<f32> =
271                    Vector2::new(-1.0 + random_factor, little_ball_velocity.y.signum()).normalize() * little_ball_velocity.to_vec().magnitude();
272
273                little_ball_velocity.x = little_ball_new_velocity.x; little_ball_velocity.y = little_ball_new_velocity.y;
274                little_ball_transform.position.x -= 0.1;
275            } else if border_collision.collider.position.x < 0.0 {
276                let little_ball_new_velocity: Vector2<f32> =
277                    Vector2::new(1.0 + random_factor, little_ball_velocity.y.signum()).normalize() * little_ball_velocity.to_vec().magnitude();
278
279                little_ball_velocity.x = little_ball_new_velocity.x; little_ball_velocity.y = little_ball_new_velocity.y;
280                little_ball_transform.position.x += 0.1;
281            }
282        }
283    }
284}
285
286fn check_litte_ball_targets_collision(context: &mut Context, little_ball_entity: Entity, random_factor: f32) {
287    let mut targets_query: Query = Query::new(&context.world).with::<Target>();
288    let targets_entities: Vec<Entity> = targets_query.entities_with_components().unwrap();
289
290    let mut little_ball_transform: ComponentRefMut<'_, Transform> = context.world.get_entity_component_mut::<Transform>(&little_ball_entity).unwrap();
291    let mut little_ball_velocity: ComponentRefMut<'_, Velocity> = context.world.get_entity_component_mut::<Velocity>(&little_ball_entity).unwrap();
292    let little_ball_collision: ComponentRef<'_, Collision> = context.world.get_entity_component::<Collision>(&little_ball_entity).unwrap();
293
294    for target in &targets_entities {
295        let target_collision: ComponentRef<'_, Collision> = context.world.get_entity_component::<Collision>(target).unwrap();
296
297        if Collision::check(CollisionAlgorithm::Aabb, &little_ball_collision, &target_collision) {
298            let little_ball_new_velocity: Vector2<f32> =
299                Vector2::new(little_ball_velocity.x.signum(), -1.0 + random_factor).normalize() * little_ball_velocity.to_vec().magnitude();
300
301            little_ball_velocity.x = little_ball_new_velocity.x; little_ball_velocity.y = little_ball_new_velocity.y;
302            little_ball_transform.position.y -= 0.1;
303            context.commands.despawn(target.clone());
304        }
305    }
306}
More examples
Hide additional examples
examples/pong.rs (line 242)
220fn check_rackets_ball_collision(context: &mut Context, pong_ball: &Entity, random_factor: f32) {
221    let mut racket_query: Query = Query::new(&context.world).with::<Racket>();
222    let rackets: Vec<Entity> = racket_query.entities_with_components().unwrap();
223    let mut game_audio: ResourceRefMut<'_, GameAudio> = context.world.get_resource_mut::<GameAudio>().unwrap();
224
225    for racket in &rackets {
226        let racket_collision: ComponentRef<'_, Collision> = context.world.get_entity_component::<Collision>(racket).unwrap();
227        let racket_transform: ComponentRef<'_, Transform> = context.world.get_entity_component::<Transform>(racket).unwrap();
228
229        let pong_ball_collision: ComponentRef<'_, Collision> = context.world.get_entity_component::<Collision>(&pong_ball).unwrap();
230        let mut pong_ball_transform: ComponentRefMut<'_, Transform> = context.world.get_entity_component_mut::<Transform>(&pong_ball).unwrap();
231        let mut pong_ball_velocity: ComponentRefMut<'_, Velocity> = context.world.get_entity_component_mut::<Velocity>(&pong_ball).unwrap();
232
233        if Collision::check(CollisionAlgorithm::Aabb, &racket_collision, &pong_ball_collision) {
234            game_audio.0.play_static_sound("racket_hit".to_string()).ok();
235
236            let relative_collision_point: f32 = pong_ball_transform.position.y - racket_transform.position.y;
237            let rebound_angle: f32 = relative_collision_point * 1.0 + random_factor;
238
239            let pong_ball_new_velocity: Vector2<f32>;
240
241            if racket_transform.position.x > 0.0 {
242                pong_ball_new_velocity = Vector2::new(-1.0, rebound_angle).normalize() * pong_ball_velocity.to_vec().magnitude();
243                pong_ball_velocity.x = pong_ball_new_velocity.x; pong_ball_velocity.y = pong_ball_new_velocity.y;
244                pong_ball_transform.position.x -= 0.1;
245            } else if racket_transform.position.x < 0.0 {
246                pong_ball_new_velocity = Vector2::new(1.0, rebound_angle).normalize() * pong_ball_velocity.to_vec().magnitude();
247                pong_ball_velocity.x = pong_ball_new_velocity.x; pong_ball_velocity.y = pong_ball_new_velocity.y;
248                pong_ball_transform.position.x += 0.1;
249            }
250            let new_position: Vector2<f32> = Vector2::new(pong_ball_transform.position.x, pong_ball_transform.position.y);
251            pong_ball_transform.set_position(&context.render_state, new_position);
252        }
253    }
254}
255
256fn check_borders_ball_collision(context: &mut Context, pong_ball: &Entity, random_factor: f32) {
257    let mut border_query: Query = Query::new(&context.world).with::<Border>();
258    let borders: Vec<Entity> = border_query.entities_with_components().unwrap();
259
260    for border in &borders {
261        let border_collision: ComponentRef<'_, Collision> = context.world.get_entity_component::<Collision>(border).unwrap();
262        let border_transform: ComponentRef<'_, Transform> = context.world.get_entity_component::<Transform>(border).unwrap();
263
264        let pong_ball_collision: ComponentRef<'_, Collision> = context.world.get_entity_component::<Collision>(&pong_ball).unwrap();
265        let mut pong_ball_velocity: ComponentRefMut<'_, Velocity> = context.world.get_entity_component_mut::<Velocity>(&pong_ball).unwrap();
266        let mut pong_ball_transform: ComponentRefMut<'_, Transform> = context.world.get_entity_component_mut::<Transform>(&pong_ball).unwrap();
267
268        let pong_ball_new_velocity: Vector2<f32>;
269
270        if Collision::check(CollisionAlgorithm::Aabb, &border_collision, &pong_ball_collision) {
271            if border_transform.position.y > 0.0 {
272                pong_ball_new_velocity = Vector2::new(pong_ball_velocity.x.signum(), -1.0 + random_factor).normalize() * pong_ball_velocity.to_vec().magnitude();
273                pong_ball_velocity.x = pong_ball_new_velocity.x; pong_ball_velocity.y = pong_ball_new_velocity.y;
274                pong_ball_transform.position.y -= 0.1;
275            } else if border_transform.position.y < 0.0 {
276                pong_ball_new_velocity = Vector2::new(pong_ball_velocity.x.signum(), 1.0 + random_factor).normalize() * pong_ball_velocity.to_vec().magnitude();
277                pong_ball_velocity.x = pong_ball_new_velocity.x; pong_ball_velocity.y = pong_ball_new_velocity.y;
278                pong_ball_transform.position.y += 0.1;
279            }
280            let new_position: Vector2<f32> = Vector2::new(pong_ball_transform.position.x, pong_ball_transform.position.y);
281            pong_ball_transform.set_position(&context.render_state, new_position);
282        }
283    }
284}
Source

fn normalize_to(self, magnitude: Self::Scalar) -> Self
where Self::Scalar: Float,

Returns a vector with the same direction and a given magnitude.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§

Source§

impl<S> InnerSpace for Quaternion<S>
where S: BaseFloat,

Source§

impl<S> InnerSpace for Vector1<S>
where S: BaseNum,

Source§

impl<S> InnerSpace for Vector2<S>
where S: BaseNum,

Source§

impl<S> InnerSpace for Vector3<S>
where S: BaseNum,

Source§

impl<S> InnerSpace for Vector4<S>
where S: BaseNum,