Skip to content

Commit

Permalink
Vector Module (#102)
Browse files Browse the repository at this point in the history
  • Loading branch information
mcdenhoed authored and johnthagen committed Mar 25, 2017
1 parent 3093ed7 commit 0c7c3cb
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 149 deletions.
3 changes: 2 additions & 1 deletion src/game/models/asteroid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ use piston_window::{Context, polygon, Size, Transformed, UpdateArgs};
use rand;

use super::super::color;
use super::{Collidable, Drawable, PI_MULT_2, Positioned, Updateable, Vector};
use super::{Collidable, Drawable, PI_MULT_2, Positioned, Updateable};
use super::vector::Vector;

/// The number of segments in an asteroid's shape is currently set at compile-time.
const NUM_SEGMENTS: usize = 20;
Expand Down
3 changes: 2 additions & 1 deletion src/game/models/bullet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ use opengl_graphics::GlGraphics;
use piston_window::{Context, ellipse, Size, Transformed, types, UpdateArgs};

use super::super::color;
use super::{Collidable, Drawable, Positioned, Updateable, Vector};
use super::{Collidable, Drawable, Positioned, Updateable};
use super::vector::Vector;

pub struct Bullet {
pos: Vector,
Expand Down
152 changes: 6 additions & 146 deletions src/game/models/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,156 +2,16 @@

use std::f64;
use std::f64::consts::PI;
use std::ops::{Add, AddAssign, Rem, RemAssign, Sub, SubAssign, Div, DivAssign};

use opengl_graphics::GlGraphics;
use piston_window::{Context, UpdateArgs, Size};
use rand;
use piston_window::{Context, UpdateArgs};

pub mod player;
pub mod bullet;
pub mod asteroid;
pub mod bullet;
pub mod player;
mod vector;

pub const PI_MULT_2: f64 = 2.0 * PI;

/// Models an (x, y) coordinate value (such as position or velocity).
#[derive(Copy, Clone, Default)]
pub struct Vector {
x: f64,
y: f64,
}

impl Vector {
fn new_rand(x_min: f64, y_min: f64, x_max: f64, y_max: f64) -> Self {
Vector {
x: rand::random::<f64>() * (x_max - x_min) + x_min,
y: rand::random::<f64>() * (y_max - y_min) + y_min,
}
}
fn angle_to_vector(self, other: Vector) -> f64 {
let diff = other - self;
let mut angle_to_point = (diff.y / diff.x).atan();
if diff.y < 0.0 {
angle_to_point += PI;
if diff.x > 0.0 {
angle_to_point += PI;
}
} else if diff.x < 0.0 {
angle_to_point += PI;
}
angle_to_point
}
}

impl Add for Vector {
type Output = Self;

fn add(self, other: Self) -> Self {
Vector {
x: self.x + other.x,
y: self.y + other.y,
}
}
}

impl AddAssign for Vector {
fn add_assign(&mut self, other: Self) {
*self = *self + other;
}
}

impl Sub for Vector {
type Output = Self;

fn sub(self, other: Self) -> Self {
Vector {
x: self.x - other.x,
y: self.y - other.y,
}
}
}

impl SubAssign for Vector {
fn sub_assign(&mut self, other: Self) {
*self = *self - other;
}
}

impl Rem for Vector {
type Output = Self;

fn rem(self, other: Self) -> Self {
Vector {
x: self.x % other.x,
y: self.y % other.y,
}
}
}

impl RemAssign for Vector {
fn rem_assign(&mut self, other: Self) {
*self = *self % other;
}
}

impl Div<Vector> for Vector {
type Output = Self;

fn div(self, other: Self) -> Self {
if other.x == 0.0 || other.y == 0.0 {
Vector { x: 0.0, y: 0.0 }
} else {
Vector {
x: self.x / other.x,
y: self.y / other.y,
}
}
}
}

impl Div<f64> for Vector {
type Output = Self;

fn div(self, other: f64) -> Self {
self /
Vector {
x: other,
y: other,
}
}
}

impl DivAssign<Vector> for Vector {
fn div_assign(&mut self, other: Self) {
*self = *self / other;
}
}

impl DivAssign<f64> for Vector {
fn div_assign(&mut self, other: f64) {
*self = *self / other;
}
}

/// Define how a two dimensional `Size` can be converted to a two dimensional `Vector`.
/// Width is defined as the x unit and height is defined as the y unit.
impl From<Size> for Vector {
fn from(size: Size) -> Self {
Vector {
x: size.width as f64,
y: size.height as f64,
}
}
}

impl From<[f64; 2]> for Vector {
fn from(list: [f64; 2]) -> Self {
Vector {
x: list[0],
y: list[1],
}
}
}
const PI_MULT_2: f64 = 2.0 * PI;

/// Trait implemented by types that can be drawn to a window.
pub trait Drawable {
Expand All @@ -175,7 +35,7 @@ pub trait Positioned {
self.pos().y
}

fn pos(&self) -> Vector;
fn pos(&self) -> vector::Vector;
}

/// Defines how types can expose how they can check for collisions with each other.
Expand Down
3 changes: 2 additions & 1 deletion src/game/models/player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ use opengl_graphics::GlGraphics;
use piston_window::{Context, polygon, Size, Transformed, types, UpdateArgs};

use super::super::color;
use super::{Collidable, Drawable, PI_MULT_2, Positioned, Updateable, Vector};
use super::{Collidable, Drawable, PI_MULT_2, Positioned, Updateable};
use super::vector::Vector;

pub struct Player {
pub pos: Vector,
Expand Down
144 changes: 144 additions & 0 deletions src/game/models/vector.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
use std::f64::consts::PI;
use std::ops::{Add, AddAssign, Rem, RemAssign, Sub, SubAssign, Div, DivAssign};

use piston_window::Size;
use rand;

/// Models an (x, y) coordinate value (such as position or velocity).
#[derive(Copy, Clone, Default)]
pub struct Vector {
pub x: f64,
pub y: f64,
}

impl Vector {
pub fn new_rand(x_min: f64, y_min: f64, x_max: f64, y_max: f64) -> Self {
Vector {
x: rand::random::<f64>() * (x_max - x_min) + x_min,
y: rand::random::<f64>() * (y_max - y_min) + y_min,
}
}
pub fn angle_to_vector(self, other: Vector) -> f64 {
let diff = other - self;
let mut angle_to_point = (diff.y / diff.x).atan();
if diff.y < 0.0 {
angle_to_point += PI;
if diff.x > 0.0 {
angle_to_point += PI;
}
} else if diff.x < 0.0 {
angle_to_point += PI;
}
angle_to_point
}
}

impl Add for Vector {
type Output = Self;

fn add(self, other: Self) -> Self {
Vector {
x: self.x + other.x,
y: self.y + other.y,
}
}
}

impl AddAssign for Vector {
fn add_assign(&mut self, other: Self) {
*self = *self + other;
}
}

impl Sub for Vector {
type Output = Self;

fn sub(self, other: Self) -> Self {
Vector {
x: self.x - other.x,
y: self.y - other.y,
}
}
}

impl SubAssign for Vector {
fn sub_assign(&mut self, other: Self) {
*self = *self - other;
}
}

impl Rem for Vector {
type Output = Self;

fn rem(self, other: Self) -> Self {
Vector {
x: self.x % other.x,
y: self.y % other.y,
}
}
}

impl RemAssign for Vector {
fn rem_assign(&mut self, other: Self) {
*self = *self % other;
}
}

impl Div<Vector> for Vector {
type Output = Self;

fn div(self, other: Self) -> Self {
if other.x == 0.0 || other.y == 0.0 {
Vector { x: 0.0, y: 0.0 }
} else {
Vector {
x: self.x / other.x,
y: self.y / other.y,
}
}
}
}

impl Div<f64> for Vector {
type Output = Self;

fn div(self, other: f64) -> Self {
self /
Vector {
x: other,
y: other,
}
}
}

impl DivAssign<Vector> for Vector {
fn div_assign(&mut self, other: Self) {
*self = *self / other;
}
}

impl DivAssign<f64> for Vector {
fn div_assign(&mut self, other: f64) {
*self = *self / other;
}
}

/// Define how a two dimensional `Size` can be converted to a two dimensional `Vector`.
/// Width is defined as the x unit and height is defined as the y unit.
impl From<Size> for Vector {
fn from(size: Size) -> Self {
Vector {
x: size.width as f64,
y: size.height as f64,
}
}
}

impl From<[f64; 2]> for Vector {
fn from(list: [f64; 2]) -> Self {
Vector {
x: list[0],
y: list[1],
}
}
}

0 comments on commit 0c7c3cb

Please sign in to comment.