Ball physics library for OCE360 HW#4
Revision 2:ba1844b0eb9f, committed 2017-11-07
- Comitter:
- slicht
- Date:
- Tue Nov 07 12:07:13 2017 +0000
- Parent:
- 1:0aa572c0f2b1
- Commit message:
- Working copy. Cycles colors on upside down. Unknown why non-deterministic color cycling.
Changed in this revision
bouncing_ball.cpp | Show annotated file Show diff for this revision Revisions of this file |
bouncing_ball.h | Show annotated file Show diff for this revision Revisions of this file |
diff -r 0aa572c0f2b1 -r ba1844b0eb9f bouncing_ball.cpp --- a/bouncing_ball.cpp Tue Oct 24 12:33:39 2017 +0000 +++ b/bouncing_ball.cpp Tue Nov 07 12:07:13 2017 +0000 @@ -1,56 +1,95 @@ #include "mbed.h" #include "bouncing_ball.h" -physics_ball::physics_ball(int color_in, int radius_in) +//Constructor. Default values are set in the library header for all member variables. +physics_ball::physics_ball() { + // Set all values to defaults defined above (avoids magic numbers)! speedx = DEFAULT_SPEEDX; speedy = DEFAULT_SPEEDY; posx = DEFAULT_POSX; posy = DEFAULT_POSY; - color = color_in; - radius = radius_in; + color = DEFAULT_COLOR; + radius = DEFAULT_RADIUS; + _width = DEFAULT_WIDTH; + _height = DEFAULT_HEIGHT; + _posy_f = (float) posx; + _posx_f = (float) posy; } +//Deconstructor exists, but does nothing. physics_ball::~physics_ball() { } -void physics_ball::define_space(int width, int height) +//Provides the ability to reset the size of the space that the ball is bouncing in. +//Width and height do noy have to be the same size as the LCD screen. +void physics_ball::define_space(int desired_width, int desired_height) { - space_width = width; - space_height = height; + _width = desired_width; + _height = desired_height; } -void physics_ball::set_param(int radius_in, int color_in) +//An alternative means of setting desired radius and colored. +void physics_ball::set_param(int desired_radius, int desired_color) { - radius = radius_in; - color = color_in; + radius = desired_radius; + color = desired_color; } -void physics_ball::set_state(int x, int y, float vx, float vy) +//An alternative means of setting desired positions and velocities. +void physics_ball::set_state(int desired_x, int desired_y, float desired_vx, float desired_vy) { - posx = x; - posy = y; - speedx = vx; - speedy = vy; + posx = desired_x; + posy = desired_y; + _posx_f = (float) posx; + _posy_f = (float) posy; + speedx = desired_vx; + speedy = desired_vy; } -void physics_ball::update(float time_step, MMA8452Q accelerometer) +//The heart of the matter: the calculation used to update the position of a ball +//using inputs from an accelerometer. +void physics_ball::update(float time_step, MMA8452Q& accelerometer) { + //If upside down, hold ball still. + if (accelerometer.readZ() < 0) { + if (_upside_down_status == 0) { + _reset_upside_down(); + _upside_down_status = 1; + } + } else { + _upside_down_status = 0; - // Move circle. IMPORTANT! Notice how we adjust for sensor orientation! - posx -= (speedx * accelerometer.readY()); - posy -= (speedy * accelerometer.readX()); + // Make circle bounce off of edges if at the edges: + if (( posx <= radius) || ((posx + radius) >= _width)) { + speedx = -speedx; + } + if (( posy <= radius) || ((posy + radius) >= _height)) { + speedy = -speedy; + } - // Make circle sit on edges - if ( posx <= radius + 1 ) { - posx = radius + 1; - } else if ( posx >= space_width - radius ) { - posx = space_width - radius; + //Accelerate per actual real world physics: + speedx -= GRAVITY * accelerometer.readY(); //* time_step; + speedy -= GRAVITY * accelerometer.readX(); //* time_step; + + //Position update depends on speed: + _posx_f = _posx_f + speedx * time_step; + _posy_f = _posy_f + speedy * time_step; + + //Actual position has to be able to update in less than integer increments. + //Report out position is expected in integers, however. + posx = (int) _posx_f; + posy = (int) _posy_f; } - if ( posy <= radius + 1 ) { - posy = radius + 1; - } else if ( posy >= space_height - radius ) { - posy = space_height - radius; +} + +void physics_ball::_reset_upside_down() +{ + //Increment color when the accelerometer turned upside down. + //It's up to the main code to interpret the color. + color += 1; + if (color > 3) { + color = 0; } } \ No newline at end of file
diff -r 0aa572c0f2b1 -r ba1844b0eb9f bouncing_ball.h --- a/bouncing_ball.h Tue Oct 24 12:33:39 2017 +0000 +++ b/bouncing_ball.h Tue Nov 07 12:07:13 2017 +0000 @@ -8,20 +8,21 @@ #define bouncing_ball_H //in case any other library wishes to check for presence of this library (see example below) #include "MMA8452Q.h" //includes our new accelerometer library definitions -#define DEFAULT_WIDTH 126 -#define DEFAULT_HEIGHT 126 +#define DEFAULT_WIDTH 128 +#define DEFAULT_HEIGHT 128 #define DEFAULT_SPEEDX 0 #define DEFAULT_SPEEDY 0 #define DEFAULT_POSX 64 #define DEFAULT_POSY 64 #define DEFAULT_COLOR 0 #define DEFAULT_RADIUS 10 +#define GRAVITY 9.8 // Class declaration class physics_ball { public: - physics_ball(int color, int radius); + physics_ball(); ~physics_ball(); float speedx; @@ -31,15 +32,20 @@ int color; int radius; - void update(float time_step, MMA8452Q accelerometer); - void define_space(int width, int height); - void set_param(int radius, int color); - void set_state(int x, int y, float vx, float vy); + void update(float time_step, MMA8452Q &accelerometer); + void define_space(int desired_width, int desired_height); + void set_param(int desired_radius, int desired_color); + void set_state(int desired_x, int desired_y, float desired_vx, float desired_vy); private: - int space_width; - int space_height; + int _width; + int _height; + int _upside_down_status; + float _posx_f; + float _posy_f; + + void _reset_upside_down(); }; #endif //bouncing_ball_H