Skip to content

Commit a0871ad

Browse files
author
Patrick Rye
committed
Update to v1.2.1
## [1.2.1] - 2017-03-06 ### Updated * Added offset to random fire so it should be possible to have a 0 mass any more * Changed the scaling factors for alpha and time to size. Done so the difference between 0.25 s and 10 s isn't as massive (was > 500, now 16 ish). ## [1.2.0] - 2017-02-27 ### Added * Buoyancy force * Magnus effect ### Updated * Drag equation * System is force based instead of acceleation
1 parent 0337e04 commit a0871ad

File tree

7 files changed

+210
-88
lines changed

7 files changed

+210
-88
lines changed

ChangesLog.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,28 @@
33
All notable changes to this project will be documented here.
44
This project adheres to [Semantic Versioning](http://semver.org/)
55

6+
## [1.2.1] - 2017-03-06
7+
### Updated
8+
* Added offset to random fire so it should be possible to have a 0 mass any more
9+
* Changed the scaling factors for alpha and time to size. Done so the difference between 0.25 s and 10 s isn't as massive (was > 500, now 16 ish).
10+
11+
12+
## [1.2.0] - 2017-02-27
13+
### Added
14+
* Buoyancy force
15+
* Magnus effect
16+
17+
### Updated
18+
* Drag equation
19+
* System is force based instead of acceleation
20+
21+
622
## [1.1.2] - 2017-02-24
723
### Added
824
* "f" key now causes random balls to be fired off in different directions.
925

1026
### Updated
1127
* Various Code improvements
12-
* Collision detection is now per pixel based.
1328
* Cannonball location is now based on its center point
1429
* Changed some of the scaling factors
1530
* Changed how collisions with the edges are handled.

src/cannonball.cpp

Lines changed: 124 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -20,34 +20,31 @@ clsCannonball::clsCannonball() {
2020
blndragenabled_ = false;
2121
blnstarted_ = false;
2222
blncheckphysics_ = true;
23-
deltat_ = (1.00 / 60.00) ;
24-
acc_.x = 0.00;
25-
acc_.y = global::physics::kGravity;
23+
deltat_ = (1.00 / 60.00);
24+
forces_ = {0,0};
25+
acc_ = {0.00, global::physics::kGravity};
26+
spin_ = 1.0;
2627

2728
props_.radius = 5.0; //in meters
2829
props_.density = global::physics::kBallDensity; //density of steel in kg/m^3
2930

30-
place_.x = 0;
31-
place_.y = 0;
31+
place_ = {0,0};
3232
dblLOC_.x = (double) place_.x;
3333
dblLOC_.y = (double) place_.y;
3434

35-
vel_.x = 0;
36-
vel_.y = 0;
35+
vel_ = {0,0};
3736

3837
srand (time(NULL));
3938

40-
color_.Red = rand() % 255;
41-
color_.Green = rand() % 255;
42-
color_.Blue = rand() % 255;
39+
color_ = {(Uint8)rand() % 255,(Uint8)rand() % 255,(Uint8)rand() % 255};
4340

4441
if(global::config.values.blnDrawPathOnScreen) {
4542
// Reserve element spots equal to the number of max
4643
// locations we are going to keep track of
4744
path_.reserve(global::config.values.uintMaxNumPastPoints);
4845

4946
// fill the new vector with "empty" values
50-
for(uchar i = 0; i < global::config.values.uintMaxNumPastPoints; ++i) {
47+
for(int i = 0; i < global::config.values.uintMaxNumPastPoints; ++i) {
5148
path_.push_back({0,0});
5249
} // end for max past points
5350
if (global::blnDebugMode) { printf("Path values initialized.\n"); }
@@ -91,37 +88,41 @@ void clsCannonball::dragUpdateAcc(void) {
9188
///
9289
/////////////////////////////////////////////////
9390

94-
acc_.x = 0.0;
95-
acc_.y = global::physics::kGravity;
9691
if (vel_.x != 0.0 && vel_.y != 0.0 && props_.mass != 0.0) {
9792
double flow_velocity = sqrt(pow(vel_.x,2) + pow(vel_.y,2));
98-
double drag_force = (double) (0.5 * global::physics::kDensityAir *
99-
flow_velocity * global::physics::kDragCofficient
100-
* props_.area);
101-
double drag_acc = (double) (drag_force / props_.mass);
93+
double Re = (global::physics::kDensityAir * props_.radius * 2 * flow_velocity);
94+
Re /= global::physics::kAirDynViscosity;
95+
double drag_force;
96+
97+
if (Re < 1) {
98+
// use Stokes' Law for drag
99+
drag_force = 6.0 * M_PI * global::physics::kAirDynViscosity *
100+
props_.radius * flow_velocity;
101+
} else {
102+
// use newton drag
103+
104+
drag_force = (double) (0.5 * global::physics::kDensityAir *
105+
pow(flow_velocity,2) * global::physics::kDragCofficient
106+
* props_.area);
107+
} // end if re < 1
108+
109+
// convert force to acceleration
102110
double angle;
103111

104-
angle = (vel_.x != 0.0) ? atan(vel_.y / vel_.x) : M_PI / 2.0;
112+
angle = (vel_.x != 0.0) ? atan(vel_.y / vel_.x) : M_PI / 2;
105113
angle += vel_.x < 0.0 ? M_PI : 0.0;
106114

107-
acc_.x += drag_acc * cos (angle);
108-
acc_.y += drag_acc * sin (angle);
109-
//Please recall fGravity is negative
110-
double friction = (double)global::physics::kKineticFriction *
111-
(double)global::physics::kGravity * props_.mass;
112-
updateCollisionBox();
113-
//Update acc for Friction values
114-
if ( collisionbox_.bottom < screen_place_.h ||
115-
collisionbox_.top > screen::screenatt.height ) {
116-
//Ball is in contact with floor or ceiling update x acc
117-
acc_.x += friction * (vel_.x < 0.0 ? -1.0 : 1.0);
118-
}
119-
120-
if ( collisionbox_.left < (screen_place_.w /2 ) ||
121-
collisionbox_.right > screen::screenatt.width ) {
122-
// Ball is in contact with the wall update y acc.
123-
acc_.y += friction * (vel_.y < 0.0 ? -1.0 : 1.0);
124-
}
115+
// update force values
116+
forces_.x -= drag_force * cos (angle);
117+
forces_.y -= drag_force * sin (angle);
118+
119+
120+
// Calculate Buoyancy
121+
double force_buoyancy;
122+
force_buoyancy = global::physics::kDensityAir * props_.volume *
123+
-1 * global::physics::kGravity;
124+
125+
forces_.y += force_buoyancy;
125126
} //end if things equal 0
126127
}
127128
/*****************************************************************************/
@@ -143,38 +144,52 @@ void clsCannonball::update(double newdeltat) {
143144
blncheckphysics_ = true; // enable on update
144145
deltat_ = newdeltat;
145146

146-
if (blndragenabled_) { dragUpdateAcc(); }
147+
// reset the forces so strange things don't happen
148+
forces_ = {0.0, props_.mass * global::physics::kGravity};
149+
150+
if (blndragenabled_) {
151+
doMagnusEffect();
152+
dragUpdateAcc();
153+
}
154+
doFriction();
155+
156+
acc_.x = forces_.x / props_.mass;
157+
acc_.y = forces_.y / props_.mass;
147158

148159
vel_.x = (vel_.x + acc_.x * deltat_);
149160
vel_.y = (vel_.y + acc_.y * deltat_);
150161

151162
// get new velocities if collision with edges
163+
164+
double coefres = (global::config.values.uchrCollisionMethod == CollideInelastic) ?
165+
global::physics::kCoefficientRestitution : 1.0;
166+
167+
152168
/* TODO (GamerMan7799#2#): Make this stuff simpler */
153169
if (collisionbox_.left < screen_place_.w / 2) {
154-
vel_.x *= -1 * global::physics::kCoefficientRestitution;
155-
vel_.y *= global::physics::kCoefficientRestitution;
156-
dblLOC_.x++;
170+
vel_.x *= -1 * coefres;
171+
vel_.y *= coefres;
172+
dblLOC_.x = screen_place_.w;
157173
}
158174

159175
if (collisionbox_.right > (screen::screenatt.width)) {
160-
vel_.x *= -1 * global::physics::kCoefficientRestitution;
161-
vel_.y *= global::physics::kCoefficientRestitution;
162-
dblLOC_.x--;
176+
vel_.x *= -1 * coefres;
177+
vel_.y *= coefres;
178+
dblLOC_.x = screen::screenatt.width - screen_place_.w / 2;
163179
}
164180

165181
if (collisionbox_.bottom > (screen::screenatt.height)) {
166-
vel_.x *= global::physics::kCoefficientRestitution;
167-
vel_.y *= -1 * global::physics::kCoefficientRestitution;
168-
dblLOC_.y++;
182+
vel_.x *= coefres;
183+
vel_.y *= -1 * coefres;
184+
dblLOC_.y = screen_place_.h / 2;
169185
}
170186

171187
if (collisionbox_.top < 0 ) {
172-
vel_.x *= global::physics::kCoefficientRestitution;
173-
vel_.y *= -1 * global::physics::kCoefficientRestitution;
174-
dblLOC_.y--;
188+
vel_.x *= coefres;
189+
vel_.y *= -1 * coefres;
190+
dblLOC_.y = (screen::screenatt.height) - screen_place_.h / 2;
175191
}
176192

177-
178193
dblLOC_.x = dblLOC_.x + vel_.x * deltat_ /*+ 0.5 * acc_.x * pow(deltat_,2)*/;
179194
dblLOC_.y = dblLOC_.y + vel_.y * deltat_ /*+ 0.5 * acc_.y * pow(deltat_,2)*/;
180195

@@ -262,6 +277,9 @@ void clsCannonball::setValues(double r, LOC init_place,
262277

263278
acc_ = {0.00, global::physics::kGravity};
264279

280+
spin_ = (rand() % 1000 - 500) / 500;
281+
282+
265283
place_ = init_place;
266284
dblLOC_ = { (double) place_.x,
267285
(double) place_.y };
@@ -271,6 +289,8 @@ void clsCannonball::setValues(double r, LOC init_place,
271289
blnstarted_ = true;
272290

273291
dragCalcValues();
292+
293+
forces_ = {0.00, global::physics::kGravity * props_.mass};
274294
blndragenabled_ = global::config.values.blnDragMode;
275295
}
276296
/*****************************************************************************/
@@ -350,7 +370,7 @@ void clsCannonball::drawPath(LOC newplace) {
350370
//Now draw the path
351371
SDL_Rect dst;
352372
dst.w = dst.h = 1;
353-
for (uint i = 0; i < global::config.values.uintMaxNumPastPoints; ++i) {
373+
for (uint i = 0; i < path_.size(); ++i) {
354374
dst.y = screen::screenatt.height - (path_[i].y);
355375
dst.x = (path_[i].x);
356376
SDL_RenderCopy(screen::screenatt.ren, screen::screenatt.pixel, NULL, &dst);
@@ -370,4 +390,57 @@ void clsCannonball::updateCollisionBox() {
370390
collisionbox_.right = collisionbox_.left + screen_place_.w;
371391
}
372392
/*****************************************************************************/
393+
void clsCannonball::doFriction() {
394+
/////////////////////////////////////////////////
395+
/// @brief Updates values based on friction
396+
/////////////////////////////////////////////////
397+
398+
// normal force is mass * gravity - buoyancy (if drag is enabled)
399+
double normal_force = (-1) * props_.mass * global::physics::kGravity;
400+
double buoyancy = (-1) * global::physics::kDensityAir *
401+
global::physics::kGravity *
402+
props_.volume;
403+
if (blndragenabled_) { normal_force -= buoyancy; }
404+
405+
double friction = (double)global::physics::kKineticFriction *
406+
normal_force;
407+
updateCollisionBox();
408+
//Update acc for Friction values
409+
if ( collisionbox_.bottom < screen_place_.h ||
410+
collisionbox_.top > screen::screenatt.height ) {
411+
//Ball is in contact with floor or ceiling update x acc
412+
forces_.x += friction * (vel_.x < 0.0 ? -1.0 : 1.0);
413+
} // end if touching top/bottom
414+
415+
416+
// Since there really isn't a normal force when the ball contacts
417+
// the edges, this section is commented out.
418+
/*
419+
if ( collisionbox_.left < (screen_place_.w /2 ) ||
420+
collisionbox_.right > screen::screenatt.width ) {
421+
// Ball is in contact with the wall update y acc.
422+
forces_.y += friction * (vel_.y < 0.0 ? -1.0 : 1.0);
423+
// add normal force
424+
forces_.x += normal_force * (collisionbox_.right > screen::screenatt.width) ?
425+
1.0 : -1.0;
426+
} // end if touching side edges */
427+
}
428+
/*****************************************************************************/
429+
void clsCannonball::doMagnusEffect() {
430+
/////////////////////////////////////////////////
431+
/// @brief Calculates the Magnus Effect caused by the ball's spin
432+
/////////////////////////////////////////////////
433+
434+
double magnus_force = pow(M_PI,2) * pow(props_.radius,3) *
435+
global::physics::kDensityAir;
373436

437+
forces_.x -= magnus_force * vel_.y * spin_;
438+
forces_.y += magnus_force * vel_.x * spin_;
439+
}
440+
/*****************************************************************************/
441+
void clsCannonball::addForce(dblXY newforces) {
442+
443+
forces_.x += newforces.x;
444+
forces_.y += newforces.y;
445+
}
446+
/*****************************************************************************/

src/cannonball.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ typedef struct stcDoubleValues dblXY;
4646
typedef struct stcPhysicalProperties PP;
4747
typedef struct stcBox BOX;
4848
typedef struct stcColor clr;
49+
typedef struct stcXYZVector XYZ;
4950

5051
typedef std::vector<LOC> VPath;
5152
/*****************************************************************************/
@@ -72,6 +73,7 @@ class clsCannonball {
7273
bool blncheckphysics_; /**< If physics should be checked. It is disabled if the ball collides,
7374
so that when looping through all of the balls, it doesn't mark
7475
the same collision twice */
76+
void addForce(dblXY);
7577
private:
7678

7779
uint ballID_; /**< The ball ID which is basically just its number in the array */
@@ -91,11 +93,16 @@ class clsCannonball {
9193
based on how much time has past since the last update to keep
9294
the movements looking realistic. See clsTick::getTimeDifference */
9395

96+
dblXY forces_; /**< Forces on the ball in x and y */
97+
double spin_; /**< The angular velocity of the ball (in rad/s) for the Magnus Effect */
98+
9499
void show(void);
95100
void drawPath(LOC);
96101
void dragCalcValues(void);
97102
void dragUpdateAcc(void);
103+
void doFriction(void);
98104
void updateCollisionBox(void);
105+
void doMagnusEffect(void);
99106
};
100107
/*****************************************************************************/
101108
#endif // __CANNONBALL_HEADER__

src/config.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,14 @@ void clsConfig::make(void) {
7777
configFile_ = fopen(FileName_,"w");
7878
printf("Config File will now be created!\n");
7979

80-
fprintf(configFile_,"Config File for the Cannon.exe\n");
80+
fprintf(configFile_,"Config File for the Physics-Simulation.exe\n");
8181
fprintf(configFile_,"%s\n",DEFINED_VER_FULLVERSION_STRING);
8282
//Write the config file with the defaults above
8383
//this way I only have to change the defaults in one place
8484
fprintf(configFile_,"Screen Width: %u\n",values.uintScreenWidth);
8585
fprintf(configFile_,"Screen Height: %u\n",values.uintScreenHeight);
8686
fprintf(configFile_,"Log Ball's path: %u\n", (values.blnLogging ? 1 : 0) ) ;
87-
fprintf(configFile_,"Enable Drag Mode (experimental): %u\n",
87+
fprintf(configFile_,"Enable Drag Mode: %u\n",
8888
(values.blnDragMode ? 1 : 0) );
8989
fprintf(configFile_,"Draw Ball path on screen: %u\n",
9090
(values.blnDrawPathOnScreen ? 1 : 0) );
@@ -128,7 +128,7 @@ void clsConfig::load(void) {
128128
values.blnLogging = (intTempBool == 1);
129129

130130
fgets(chrTempString,50,configFile_);
131-
intValuesScanned = sscanf(chrTempString, "%*s %*s %*s %*s %d",&intTempBool);
131+
intValuesScanned = sscanf(chrTempString, "%*s %*s %*s %d",&intTempBool);
132132
if (intValuesScanned < 1) { printf("ERROR!"); intTempBool = 0; }
133133
if(global::blnDebugMode) { printf("Enable Drag \t %d\n",intTempBool); }
134134
values.blnDragMode = (intTempBool == 1);
@@ -221,6 +221,7 @@ void clsConfig::Check(void) {
221221
printf("Config file found; loading values\n");
222222
fgets(chrTempString,50,configFile_);
223223
fgets(chrTempString,50,configFile_);
224+
//printf("%s\n",chrTempString);
224225
chrConfigVerison = verisonCheck(chrTempString);
225226

226227
if (chrConfigVerison == 'N') {

src/global.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ namespace global {
2727
extern const float kMinVelocity;
2828
extern const float kCoefficientRestitution;
2929
extern uchar collisionmethod;
30+
extern const double kAirDynViscosity;
3031
}
3132

3233
namespace equations {

0 commit comments

Comments
 (0)