summaryrefslogtreecommitdiff
path: root/2d/softbody/softbody_1/damped.cpp
diff options
context:
space:
mode:
Diffstat (limited to '2d/softbody/softbody_1/damped.cpp')
-rw-r--r--2d/softbody/softbody_1/damped.cpp55
1 files changed, 38 insertions, 17 deletions
diff --git a/2d/softbody/softbody_1/damped.cpp b/2d/softbody/softbody_1/damped.cpp
index d623c06..0344bd0 100644
--- a/2d/softbody/softbody_1/damped.cpp
+++ b/2d/softbody/softbody_1/damped.cpp
@@ -25,6 +25,13 @@ namespace Damped {
void unload();
};
+ enum DampedSpringType {
+ None = 0,
+ Overdamped = 1,
+ Underdamped = 2,
+ Critical = 3
+ };
+
struct DampedSpring {
DampedSpringWeight* weight;
@@ -35,12 +42,14 @@ namespace Damped {
int32 numVertices = 0;
// Initialization variables
+ float32 initialDisplacement = 0.f;
float32 k = 4; // DampedSpring Constant, in N / m (Hooke's Law)
float32 c = 1.f; // Viscous damping coefficient (Damping force)
+
+ // Discovered during initialization
+ DampedSpringType type = DampedSpringType::None;
float32 R = 2.f;
float32 gamma = 6.2;
-
- // Constants calculated at load time
float32 discriminant = 0.f;
float32 omega1 = 0.f;
@@ -49,7 +58,7 @@ namespace Damped {
float32 timeElapsed = 0.f;
- void load(Renderer2d* renderer, DampedSpringWeight* inWieight, float32 length, float32 loopRadius);
+ void load(Renderer2d* renderer, DampedSpringWeight* inWieight, float32 length, float32 loopRadius, float32 initialDisplacement);
void update(float32 dtSeconds);
void render(Renderer2d* renderer);
void unload();
@@ -82,8 +91,8 @@ namespace Damped {
renderer.load(context);
- weight.load(&renderer, 32.f, Vector4 { 55.f, 235.f, 35.f, 255.f }, Vector4 { 235.f, 5.f, 235.f, 255.f });
- spring.load(&renderer, &weight, 250.f, 16.f);
+ weight.load(&renderer, initVariables.mass, Vector4 { 55.f, 235.f, 35.f, 255.f }, Vector4 { 235.f, 5.f, 235.f, 255.f });
+ spring.load(&renderer, &weight, initVariables.springLength, 16.f, initVariables.initialDisplacement);
mainLoop.run(update);
}
@@ -107,8 +116,9 @@ namespace Damped {
context->destroy();
}
- void DampedSpringWeight::load(Renderer2d* renderer, float32 inRadius, Vector4 startColor, Vector4 endColor) {
- radius = inRadius;
+ void DampedSpringWeight::load(Renderer2d* renderer, float32 inMass, Vector4 startColor, Vector4 endColor) {
+ mass = inMass;
+ radius = mass * 16.f;
const int32 numSegments = 96;
const float32 radiansPerSegment = (2.f * PI) / static_cast<float>(numSegments);
const int32 numVertices = numSegments * 3;
@@ -154,20 +164,28 @@ namespace Damped {
const float32 epsilon = 0.0001f;
- void DampedSpring::load(Renderer2d* renderer, DampedSpringWeight* inWeight, float32 length, float32 loopRadius) {
+ void DampedSpring::load(Renderer2d* renderer, DampedSpringWeight* inWeight, float32 length, float32 loopRadius, float32 initialDisplacement) {
+ initialDisplacement = initialDisplacement;
weight = inWeight;
discriminant = c * c - (4 * weight->mass * k);
- if (discriminant < epsilon && discriminant > -epsilon) { // Real repeated root: Overdamped motion
-
+ if (discriminant < epsilon && discriminant > -epsilon) { // Real repeated root (~ zero): Overdamped motion
+ printf("Overdamped motion.\n");
+ type = DampedSpringType::Overdamped;
}
- else if (discriminant > 0) { // Two real roots: Critically damped motion
-
+ else if (discriminant > 0) { // Two real roots (greater than zero): Critically damped motion
+ printf("Critically damped motion.\n");
+ type = DampedSpringType::Critical;
}
else { // Complex pair (less than zero): Underdamped motion
- omega1 = sqrtf(-discriminant) / (2.f * weight->mass); // Get the real part of the number
+ printf("Underdamped motion.\n");
+
+ type = DampedSpringType::Underdamped;
+ omega1 = sqrtf(-discriminant) / (2.f * weight->mass); // Note that we negate the discriminant to get the REAL positive part.
}
+
+
timeElapsed = 0.f;
const int32 verticesPerSegment = 6;
@@ -206,6 +224,8 @@ namespace Damped {
void DampedSpring::update(float32 dtSeconds) {
timeElapsed += dtSeconds;
+ float32 lastDisplacement = displacement;
+
if (discriminant < epsilon && discriminant > -epsilon) { // Real repeated root: Overdamped motion
}
@@ -217,10 +237,11 @@ namespace Damped {
displacement = R * pow(E, exponent) * (cosf(omega1 * timeElapsed - gamma));
}
+ float32 dx = displacement - lastDisplacement;
int32 vidx = 0;
for (int pidx = 0; pidx < numSegments; pidx++) {
- float32 y1Offset = displacement * (1.f - pidx / static_cast<float32>(numSegments));
- float32 y2Offset = displacement * (1.f - (pidx + 1) / static_cast<float32>(numSegments));
+ float32 y1Offset = dx * (1.f - pidx / static_cast<float32>(numSegments));
+ float32 y2Offset = dx * (1.f - (pidx + 1) / static_cast<float32>(numSegments));
vertices[vidx++].position.y += y1Offset;
vertices[vidx++].position.y += y2Offset;
vertices[vidx++].position.y += y1Offset;
@@ -228,8 +249,8 @@ namespace Damped {
vertices[vidx++].position.y += y2Offset;
vertices[vidx++].position.y += y2Offset;
}
-
- weight->shape.model = weight->shape.model.translateByVec2(Vector2(0, displacement));
+
+ weight->shape.model = weight->shape.model.translateByVec2(Vector2(0, dx));
}
void DampedSpring::render(Renderer2d* renderer) {