Ball physics library for OCE360 HW#4

Files at this revision

API Documentation at this revision

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
--- 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
--- 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