Skip to content

Commit 82dbea2

Browse files
author
Patrick Rye
committed
Update to v1.1.8-beta
16 September 2015 Released version 1.1.8-Beta Change log: -Added: More collision methods (Inelastic, Elastic, Perfect Inelastic, and No Collisons) -Improved: Collision equations -Fixed: You can now properly fire a cannonball in all directions -Fixed: Balls that have velocity as NaN will be removed (I should have fixed the equations so this doesn't happen, but just is cause)
1 parent 8352ceb commit 82dbea2

File tree

7 files changed

+161
-53
lines changed

7 files changed

+161
-53
lines changed

ChangesLog.txt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
1+
16 September 2015
2+
Released version 1.1.8-Beta
3+
4+
Change log:
5+
-Added: More collision methods (Inelastic, Elastic, Perfect Inelastic, and No Collisons)
6+
-Improved: Collision equations
7+
-Fixed: You can now properly fire a cannonball in all directions
8+
-Fixed: Balls that have velocity as NaN will be removed
9+
(I should have fixed the equations so this doesn't happen, but just is cause)
10+
111
15 September 2015
2-
UNFINISHED Released version 1.1.7-Beta
12+
Released version 1.1.7-Beta
313

414
Change log:
515
-Added: Collisons

src/cannonball.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
#include "cannonball.h"
33
#include "screen.h"
44
/**********************************************************************************************************************************************/
5-
#define PI 3.1415926535897
6-
/**********************************************************************************************************************************************/
75
//Constants
86
const double Rad_Convert = PI / 180.0;
97
/**********************************************************************************************************************************************/
@@ -90,7 +88,7 @@ void clsCannonball::update(double newdeltat) {
9088

9189
double total_v;
9290
total_v = sqrt( pow(vel.x,2) + pow(vel.y,2) );
93-
if (total_v < Global::Physics::fMinVelocity) {
91+
if (total_v < Global::Physics::fMinVelocity || isnan(total_v) ) {
9492
blnstarted = false;
9593
if (Global::blnDebugMode) {printf("Ball moving too slow; killing it\n");}
9694
}
@@ -139,12 +137,16 @@ void clsCannonball::setVelocity(dblXY newvel) {
139137
vel.y = newvel.y;
140138
}
141139
/**********************************************************************************************************************************************/
142-
double clsCannonball::getmass() {
143-
return props.mass;
140+
PP clsCannonball::getPhysicalProps() {
141+
return props;
144142
}
145143
/**********************************************************************************************************************************************/
146144
void clsCannonball::setplace(LOC newplace) {
147145
dblLOC.x = newplace.x;
148146
dblLOC.y = newplace.y;
149147
}
150148
/**********************************************************************************************************************************************/
149+
void clsCannonball::setPhysicalProps(PP newprops) {
150+
props = newprops;
151+
}
152+
/**********************************************************************************************************************************************/

src/cannonball.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#include "global.h"
1010
#include "screen.h"
1111
/**********************************************************************************************************************************************/
12+
#define PI 3.1415926535897
13+
/**********************************************************************************************************************************************/
1214
struct stcDoubleValues {
1315
double x;
1416
double y;
@@ -28,17 +30,18 @@ class clsCannonball {
2830
public:
2931
/** Default constructor */
3032
clsCannonball();
31-
bool blnstarted;
3233
void setValues(double, LOC, double, double);
3334
LOC getplace(void);
3435
void setplace(LOC);
3536

36-
void enableDrag(void);
3737
void update(double);
3838
void setSDLScreen(SDL_Texture*, WINATT);
3939
dblXY getVelocity(void);
4040
void setVelocity(dblXY);
41-
double getmass(void);
41+
PP getPhysicalProps(void);
42+
void setPhysicalProps(PP);
43+
44+
bool blnstarted;
4245
private:
4346
bool blnDragEnabled;
4447

@@ -51,6 +54,7 @@ class clsCannonball {
5154
dblXY acc;
5255
PP props;
5356

57+
void enableDrag(void);
5458
double deltat;
5559
void show(void);
5660
void Drag_calcvalues(void);

src/global.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ typedef unsigned long ulong;
1111
//Global namespace
1212
namespace Global {
1313
extern const bool blnDebugMode;
14-
extern clsConfig Config;
14+
extern clsConfig Config; //Hold the config file globally so configure options can be referenced everywhere
1515
namespace Physics { //hold physics values in one place for future reference
1616
extern const uint uBallDensity;
1717
extern const float fGravity;
@@ -21,6 +21,7 @@ namespace Global {
2121
extern const float fVelocityScalar;
2222
extern const float fMinVelocity;
2323
extern const float fMomentumLoss;
24+
extern const uchar CollisionMethod;
2425
}
2526
}
2627
/**********************************************************************************************************************************************/

src/main.cpp

Lines changed: 123 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ bool checkCollide(BOX, BOX);
2424
void doCollision(uint, uint);
2525
BOX boxMaker(LOC);
2626
/**********************************************************************************************************************************************************************/
27+
enum Collisions { //The method of the collision (I just wanted to play around with some options.
28+
CollideElastic = 0, //This is the normal way things collide, they hit and bounce off, no energy is lost
29+
CollideInelastic, //balls collide and bounce off of each other losing some energy.
30+
CollidePerfectInelastic, //In this method the balls collide and then stick together
31+
CollideNone //No collisions
32+
};
33+
/**********************************************************************************************************************************************************************/
2734
namespace Global {
2835
#ifdef DEFINED_BUILD_MODE_PRIVATE
2936
const bool blnDebugMode = true;
@@ -38,14 +45,13 @@ namespace Global {
3845
const float fDensityAir = 1.2754; //Density of air
3946
const float fRecoil = -0.56;
4047
const float fVelocityScalar = 1; //Changing this effects the fire velocity
41-
const float fMinVelocity = 0.005; //If a ball has less velocity than the it will "die"
42-
const float fMomentumLoss = 1; //How much total momentum stays after a collisions
48+
const float fMinVelocity = 0.5; //If a ball has less velocity than the it will "die"
49+
const float fMomentumLoss = 0.76; //How much total momentum stays after a collisions
50+
const uchar CollisionMethod = CollideElastic;
4351
}
4452
}
4553
/**********************************************************************************************************************************************************************/
46-
/* TODO (GamerMan7799#1#): Figure out how to detect the edges of the images */
47-
/* TODO (GamerMan7799#1#): Get Highest height and Distance from fire at end of run. */
48-
/**********************************************************************************************************************************************************************/
54+
//This is the maximum number of cannonballs which can be "alive" at a time
4955
#define DEFINED_CANNONBALL_LIMIT 10
5056
/**********************************************************************************************************************************************************************/
5157
clsCannonball Cannonballs[DEFINED_CANNONBALL_LIMIT];
@@ -69,7 +75,8 @@ int main(int argc, char *argv[]) {
6975
LOC OldMouse, CurrentMouse;
7076
SDL_Event event;
7177
do {
72-
CannonWindow.clearscreen();
78+
CannonWindow.clearscreen(); //Clear the screen so new stuff can be drawn
79+
7380
//poll events
7481
if (SDL_PollEvent( &event ) != 0) {
7582
if ( event.type == SDL_QUIT ) {quit = true;}
@@ -91,13 +98,16 @@ int main(int argc, char *argv[]) {
9198
if (holding) {CannonWindow.drawline(CurrentMouse, OldMouse);}
9299
//Update every ball
93100
tempdeltat = Tick.getTimeDifference();
94-
for (uint i = 0; i < DEFINED_CANNONBALL_LIMIT; i++) {
95-
if (Cannonballs[i].blnstarted) {
101+
102+
for (uint i = 0; i < DEFINED_CANNONBALL_LIMIT; i++) { //Loop through each cannonball
103+
if (Cannonballs[i].blnstarted) { //only update cannonball if it is "alive"
96104
Cannonballs[i].update(tempdeltat);
97-
checkForCollisons(i);
105+
//Check for collisions if no collide is not on
106+
if (Global::Physics::CollisionMethod != CollideNone) {checkForCollisons(i);}
98107
} //end if started
99108
} //end for loop
100-
CannonWindow.update();
109+
110+
CannonWindow.update(); //Update the screen
101111
} while (!quit);
102112
return 0;
103113
}
@@ -107,20 +117,23 @@ void addNewCannonball(LOC mouseC, LOC mouseO ) {
107117
double fire_v;
108118
double angle;
109119

120+
//Because y increasing is going down according to SDL we first negative the velocity
110121
fire_v = -1 * sqrt( pow(mouseC.x - mouseO.x, 2) + pow(mouseC.y - mouseO.y, 2) );
111122
fire_v /= (double) Global::Physics::fVelocityScalar;
112123

124+
//if the mouse if pointing straight up or straight down make the angle 90
125+
//Other calculate the angle with atan.
113126
if (mouseC.x == mouseO.x) {
114127
if (mouseC.y > mouseO.y) {angle = -90.0;}
115128
else if (mouseC.y < mouseO.y) {angle = 90.0;}
116129
else {angle = 0;}
117130
} else {
118131
angle = (double)-1.0 * atan( (mouseC.y - mouseO.y) / (mouseC.x - mouseO.x) );
119-
angle *= (double)(180/3.1415926535);
120-
if (mouseC.x < mouseO.x) {angle *= (double)-1.0;}
132+
if (mouseC.x < mouseO.x) {angle += (double)PI;}
133+
angle *= (double)(180/PI);
121134
} //end if x = x
122135

123-
//mod mouse start
136+
//mod mouse start, once again because the top left is 0,0 to SDL
124137
mouseO.y = tempwin.height - mouseO.y;
125138

126139
//loop through array to find next available cannonball slot
@@ -159,32 +172,110 @@ bool checkCollide(BOX A, BOX B) { //checks if two objects (made with the BOXES c
159172
/**********************************************************************************************************************************************************************/
160173
void doCollision(uint numA, uint numB) {
161174
dblXY Avel, Bvel, NewVel;
162-
double Amass, Bmass;
175+
PP Aprops, Bprops;
176+
163177
Avel = Cannonballs[numA].getVelocity();
164178
Bvel = Cannonballs[numB].getVelocity();
165-
Amass = Cannonballs[numA].getmass();
166-
Bmass = Cannonballs[numB].getmass();
179+
Aprops = Cannonballs[numA].getPhysicalProps();
180+
Bprops = Cannonballs[numB].getPhysicalProps();
181+
182+
double Aangle, Bangle, ContactAngle;
183+
double Atotal_v, Btotal_v;
167184

168-
double totalMomX = Amass * Avel.x - Bmass * Bvel.x;
169-
double totalMomY = Amass * Avel.y - Bmass * Bvel.y;
170-
totalMomX *= (double)Global::Physics::fMomentumLoss;
171-
totalMomY *= (double)Global::Physics::fMomentumLoss;
185+
dblXY TotalAMomentum, TotalBMomentum;
172186

173-
//I know that this is not a true Momentum equation
174-
//I'm just trying to get something up to test things out.
175-
NewVel.x = totalMomX / (Amass + Bmass);
176-
NewVel.y = totalMomY / (Amass + Bmass);
187+
if ( Global::Physics::CollisionMethod != CollidePerfectInelastic ) {
188+
//The equations for Perfect Inelastic is much simpler than if not
189+
//so I am handling those a bit differently to speed up that method.
190+
191+
//Equations used can be found and explained here: https://en.wikipedia.org/wiki/Elastic_collision
192+
Atotal_v = sqrt( pow(Avel.x,2) + pow(Avel.y,2) );
193+
Btotal_v = sqrt( pow(Bvel.x,2) + pow(Bvel.y,2) );
194+
195+
//get the angle for both A and B
196+
if (Avel.x != 0.0) {Aangle = atan(Avel.y/Avel.x);}
197+
else {
198+
if (Avel.y > 0.0) {Aangle = PI / 2.0;}
199+
else if (Avel.y < 0.0) {Aangle = - PI / 2.0;}
200+
else {Aangle = 0.0;}
201+
}
202+
203+
if (Bvel.x != 0.0) {Bangle = atan(Bvel.y/Bvel.x);}
204+
else {
205+
if (Bvel.y > 0.0) {Bangle = PI / 2.0;}
206+
else if (Bvel.y < 0.0) {Bangle = - PI / 2.0;}
207+
else {Bangle = 0.0;}
208+
}
209+
210+
//Adjust the angle to be the right one.
211+
//Since atan will only yield a number between -PI/2 and PI/2 we
212+
//have to adjust it if xvel is negative.
213+
if (Avel.x < 0.0) {Aangle += PI;}
214+
if (Bvel.x < 0.0) {Bangle += PI;}
215+
ContactAngle = Aangle + Bangle;
216+
217+
TotalAMomentum.x = Atotal_v * cos(Aangle - ContactAngle) * (Aprops.mass - Bprops.mass);
218+
TotalAMomentum.x += 2.0 * Bprops.mass * Btotal_v * cos(Bangle - ContactAngle);
219+
TotalAMomentum.x /= (Aprops.mass + Bprops.mass);
220+
//x and y formulas are the same until this point
221+
TotalAMomentum.y = TotalAMomentum.x;
222+
TotalAMomentum.x *= cos(ContactAngle);
223+
TotalAMomentum.y *= sin(ContactAngle);
224+
TotalAMomentum.x += Atotal_v * sin(Aangle - ContactAngle) * cos(ContactAngle + (PI/2.0) );
225+
TotalAMomentum.y += Atotal_v * cos(Aangle - ContactAngle) * cos(ContactAngle + (PI/2.0) );
226+
227+
//Now do B
228+
TotalBMomentum.x = Btotal_v * cos(Bangle - ContactAngle) * (Bprops.mass - Aprops.mass);
229+
TotalBMomentum.x += 2.0 * Aprops.mass * Atotal_v * cos(Aangle - ContactAngle);
230+
TotalBMomentum.x /= (Aprops.mass + Bprops.mass);
231+
//x and y formulas are the same until this point
232+
TotalBMomentum.y = TotalBMomentum.x;
233+
TotalBMomentum.x *= cos(ContactAngle);
234+
TotalBMomentum.y *= sin(ContactAngle);
235+
TotalBMomentum.x += Btotal_v * sin(Bangle - ContactAngle) * cos(ContactAngle + (PI/2.0) );
236+
TotalBMomentum.y += Btotal_v * cos(Bangle - ContactAngle) * cos(ContactAngle + (PI/2.0) );
237+
} else {
238+
TotalAMomentum.x = Aprops.mass * Avel.x + Bprops.mass * Bvel.x;
239+
TotalAMomentum.y = Aprops.mass * Avel.y + Bprops.mass * Bvel.y;
240+
} //end if Perfect Inelastic or not
177241

178-
Cannonballs[numA].setVelocity(NewVel);
179-
NewVel.y *= -1;
180-
NewVel.x *= -1;
181-
Cannonballs[numB].setVelocity(NewVel);
242+
switch (Global::Physics::CollisionMethod) { //figure out what to do based on the collision method
243+
case CollidePerfectInelastic:
244+
//The balls collide and stick together
245+
//Get the new mass.
246+
Aprops.mass += Bprops.mass;
247+
//Now we have to calculate the new radius, volume, and area so that drag will reflect the new size
248+
//we are of course assuming that density stays the same.
249+
Aprops.volume = (Aprops.mass / (double)Global::Physics::uBallDensity);
250+
//cbrt = cube root
251+
Aprops.radius = cbrt( (double) (3.0*Aprops.volume) / (double) (4.0*PI) );
252+
Aprops.area = (double) (2.0 * PI * pow(Aprops.radius, 2) );
253+
//Now calculate the new velocity
254+
Avel.x = TotalAMomentum.x / Aprops.mass;
255+
Avel.y = TotalAMomentum.y / Aprops.mass;
256+
//now "kill" cannonball B and update ball A
257+
Cannonballs[numB].blnstarted = false;
258+
Cannonballs[numA].setPhysicalProps(Aprops);
259+
Cannonballs[numA].setVelocity(Avel);
260+
break;
261+
case CollideInelastic:
262+
//uses the same equations as below but some energy is lost.
263+
TotalAMomentum.x *= (double)Global::Physics::fMomentumLoss;
264+
TotalAMomentum.y *= (double)Global::Physics::fMomentumLoss;
265+
TotalBMomentum.x *= (double)Global::Physics::fMomentumLoss;
266+
TotalBMomentum.y *= (double)Global::Physics::fMomentumLoss;
182267

268+
case CollideElastic:
269+
//The balls collide and bounce away from each other
183270

184-
/*LOC Aplace = Cannonballs[numA].getplace();
185-
Aplace.x ++;
186-
Aplace.y --;
187-
Cannonballs[numA].setplace(Aplace);*/
271+
//All of the heavy lifting is handled above.
272+
Cannonballs[numA].setVelocity(TotalAMomentum);
273+
Cannonballs[numB].setVelocity(TotalBMomentum);
274+
break;
275+
default: //the catch all and CollideNone
276+
//Nothing Happens!
277+
break;
278+
} //end switch collide method
188279
}
189280
/**********************************************************************************************************************************************************************/
190281
BOX boxMaker(LOC place) {

src/tick.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ void clsTick::startTimer(void) {
1414
/**********************************************************************************************************************************************/
1515
double clsTick::getTimeDifference(void) {
1616
double temp_time = (double)(((double)clock() - (double)lngTimerStart) / (double)CLOCKS_PER_SEC);
17-
if (Global::blnDebugMode) {
17+
/*if (Global::blnDebugMode) {
1818
FILE* something = fopen("time-log.log","a");
1919
fprintf(something,"%f\n",temp_time);
2020
fclose(something);
21-
}
21+
}*/
2222
startTimer();
2323
return temp_time;
2424
}
@@ -27,7 +27,7 @@ void clsTick::wait(void) {
2727
/* Code taken from http://c-for-dummies.com/blog/?p=69 */
2828
ulong pause;
2929
clock_t now, then;
30-
pause = 5 * (CLOCKS_PER_SEC/1000); //pause equals 1 millisecond
30+
pause = (CLOCKS_PER_SEC/1000); //pause equals 1 millisecond
3131
now = then = clock();
3232
while ( (ulong)(now - then) < pause) {now = clock();}
3333
}

src/version.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#define __VERSION_HEADER__
33

44
//Date Version Types
5-
#define DEFINED_VER_DATE "15"
5+
#define DEFINED_VER_DATE "16"
66
#define DEFINED_VER_MONTH "09"
77
#define DEFINED_VER_YEAR "2015"
88
#define DEFINED_VER_UBUNTU_VERSION_STYLE "15.09"
@@ -14,17 +14,17 @@
1414
//Standard Version Type
1515
#define DEFINED_VER_MAJOR 1
1616
#define DEFINED_VER_MINOR 1
17-
#define DEFINED_VER_BUILD 7
18-
#define DEFINED_VER_REVISION 6
17+
#define DEFINED_VER_BUILD 8
18+
#define DEFINED_VER_REVISION 1
1919

2020
//Miscellaneous Version Types
21-
#define DEFINED_VER_BUILDS_COUNT 160
22-
#define DEFINED_VER_RC_FILEVERSION 1,1,7,6
23-
#define DEFINED_VER_RC_FILEVERSION_STRING "1, 1, 7, 6\0"
24-
#define DEFINED_VER_FULLVERSION_STRING "1.1.7.6"
21+
#define DEFINED_VER_BUILDS_COUNT 0
22+
#define DEFINED_VER_RC_FILEVERSION 1,1,8,1
23+
#define DEFINED_VER_RC_FILEVERSION_STRING "1, 1, 8, 1\0"
24+
#define DEFINED_VER_FULLVERSION_STRING "1.1.8.1"
2525

2626
//These values are to keep track of your versioning state, don't modify them.
27-
#define DEFINED_VER_BUILD_HISTORY 4
27+
#define DEFINED_VER_BUILD_HISTORY 1
2828

2929

3030
#endif //__VERSION_HEADER__

0 commit comments

Comments
 (0)