From ef4251f6644a2f0933dd6cf2b1ceea4ed683aef4 Mon Sep 17 00:00:00 2001 From: kookroach Date: Thu, 16 Nov 2023 19:27:13 +0100 Subject: [PATCH] clean up, add print method for springs, change Euler Function declaration, add demo, demo2 demo3 setup --- Simulations/MassSpringSystemSimulator.cpp | 190 +++++++++++++++------- Simulations/MassSpringSystemSimulator.h | 4 +- 2 files changed, 135 insertions(+), 59 deletions(-) diff --git a/Simulations/MassSpringSystemSimulator.cpp b/Simulations/MassSpringSystemSimulator.cpp index 0ea12ac..4ce7d5f 100644 --- a/Simulations/MassSpringSystemSimulator.cpp +++ b/Simulations/MassSpringSystemSimulator.cpp @@ -1,16 +1,12 @@ #include "MassSpringSystemSimulator.h" +#include MassSpringSystemSimulator::MassSpringSystemSimulator() { m_iTestCase = 0; m_fMass = 10; m_fStiffness = 40; - int m_iIntegrater = 0; - - auto first = addMassPoint(Vec3(0, 0, 0), Vec3(-1, 0, 0), true); - auto second = addMassPoint(Vec3(0, 2, 0), Vec3(1, 0, 0), true); - addSpring(first, second, 1.0); - m_fStiffness = 40; + m_iIntegrator = EULER; } const char* MassSpringSystemSimulator::getTestCasesStr() @@ -23,13 +19,14 @@ void MassSpringSystemSimulator::initUI(DrawingUtilitiesClass* DUC) this->DUC = DUC; switch (m_iTestCase) { - case 0:break; - case 1: - - break; - case 2: - break; - default:break; + case 0: + break; + case 1: + break; + case 2: + break; + default: + break; } } @@ -38,10 +35,11 @@ void MassSpringSystemSimulator::reset() m_mouse.x = m_mouse.y = 0; m_trackmouse.x = m_trackmouse.y = 0; m_oldtrackmouse.x = m_oldtrackmouse.y = 0; + + springs.clear(); + masspoints.clear(); } - - void MassSpringSystemSimulator::drawFrame(ID3D11DeviceContext* pd3dImmediateContext) { @@ -68,26 +66,91 @@ void MassSpringSystemSimulator::drawFrame(ID3D11DeviceContext* pd3dImmediateCont void MassSpringSystemSimulator::notifyCaseChanged(int testCase) { m_iTestCase = testCase; + system("cls"); + reset(); + switch (m_iTestCase) { - case 0: - cout << "Demo1 !\n"; + case 0: { + cout << "Demo 1 !\n"; + setMass(10); + setStiffness(40); -//simulateTimestep(1); + int first = addMassPoint(Vec3(0, 0, 0), Vec3(-1, 0, 0), true); + int second = addMassPoint(Vec3(0, 2, 0), Vec3(1, 0, 0), true); + + addSpring(first, second, 1); + cout << "\t -- INITIAL --\n"; + printSpring(springs.at(0)); + cout << "--------------------------------------------------" << std::endl; + + //calculate Euler for one step and print results + setIntegrator(EULER); + cout << "\n\n\t -- EULER RESULT --\n"; + simulateTimestep(1); + printSpring(springs.at(0)); + + cout << "--------------------------------------------------" << std::endl; + + reset(); + first = addMassPoint(Vec3(0, 0, 0), Vec3(-1, 0, 0), true); + second = addMassPoint(Vec3(0, 2, 0), Vec3(1, 0, 0), true); + + addSpring(first, second, 1); + + //calculate Midpoint for one step and print results + setIntegrator(MIDPOINT); + cout << "\n\n\t -- MIDPOINT RESULT --\n"; + simulateTimestep(0.005); + printSpring(springs.at(0)); + break; + } + + case 1: { + cout << "Demo 2 !\n"; + reset(); + int first = addMassPoint(Vec3(0, 0, 0), Vec3(-1, 0, 0), true); + int second = addMassPoint(Vec3(0, 2, 0), Vec3(1, 0, 0), true); + addSpring(first, second, 1.0); + + cout << "\t -- INITIAL --\n"; + printSpring(springs.at(0)); + + cout << "--------------------------------------------------" << std::endl; + + //calculate Euler for a timestep of 0.005 and print results + setIntegrator(EULER); + cout << "\n\n\t -- EULER RESULT--\n"; + simulateTimestep(0.005); + printSpring(springs.at(0)); break; - case 1: - cout << "Demo2 \n"; - //m_iNumSpheres = 100; - //m_fSphereSize = 0.05f; + } + + case 2: { + cout << "Demo 3 !\n"; + reset(); + int first = addMassPoint(Vec3(0, 0, 0), Vec3(-1, 0, 0), true); + int second = addMassPoint(Vec3(0, 2, 0), Vec3(1, 0, 0), true); + addSpring(first, second, 1.0); + + cout << "\t -- INITIAL --\n"; + printSpring(springs.at(0)); + + cout << "--------------------------------------------------" << std::endl; + + //calculate Midpoint for a timestep of 0.005 and print results + setIntegrator(MIDPOINT); + cout << "\n\n\t -- MIDPOINT RESULT --\n"; + simulateTimestep(0.005); + printSpring(springs.at(0)); break; - case 2: - cout << "Demo3 !\n"; - break; - case 3: + } + case 3: { cout << "Demo 4 !\n"; + break; + } default: - //cout << "Demo4 !\n"; break; } } @@ -115,28 +178,32 @@ void MassSpringSystemSimulator::externalForcesCalculations(float timeElapsed) } - - void MassSpringSystemSimulator::simulateTimestep(float timeStep) { //update current setup for each frame - switch (m_iTestCase) { - case 0: - //update the masspoint - cout << "Euler \n"; - - cout << "Midpoint\n"; - break; - case 1:cout << "demo 2 \n"; - break; - case 2:cout << "demo 3\n"; - break; - case 3: cout << "demo 4\n"; - break; - default: break; - } + for (size_t i = 0; i < springs.size(); i++) { + auto sp = springs.at(i); + if (!sp.isValid()) + { + springs.erase(springs.begin() + i); + continue; + } + auto mp1 = sp.mp1.lock(); + auto mp2 = sp.mp2.lock(); - Euler(0, 1, 0, timeStep); + + if (m_iIntegrator == EULER) { + + Euler(*mp1.get(), *mp2.get(), sp, timeStep); + } + else if (m_iIntegrator == MIDPOINT) { + //TODO: Add Midpoint + } + else if (m_iIntegrator == LEAPFROG) { + //TODO: Add Leapfrog + } + + } } void MassSpringSystemSimulator::onClick(int x, int y) @@ -234,28 +301,35 @@ Vec3 MassSpringSystemSimulator::calculateAcceleration(Vec3 force, float mass) return force / mass; } -void MassSpringSystemSimulator::Euler(int index1, int index2, int indexSpring, float timestep) +void MassSpringSystemSimulator::Euler(MassPoint& masspoint1, MassPoint& masspoint2, Spring& spring, float timestep) { //take old position and send to calculatePositionTimestepEuler - auto mp = masspoints.at(index1); - auto mp2 = masspoints.at(index2); - Vec3 PosVector = mp->position - mp2->position; + auto PosVector = masspoint1.position - masspoint2.position; auto lengthVector = sqrt(PosVector.x * PosVector.x + PosVector.y * PosVector.y + PosVector.z * PosVector.z); auto normalized = PosVector / lengthVector; // Actual Calculation // Force of spring is -k * (l - L) * normalizedVector [for P2 we can take -F1) - auto force = -m_fStiffness * (lengthVector - springs.at(0).initialLength) * normalized; + auto force = -m_fStiffness * (lengthVector - spring.initialLength) * normalized; auto foreP2 = -1 * force; - auto veloc = calcualteVelocityTimestepEuler(mp->velocity, timestep, calculateAcceleration(force, 10.)); - auto pos = calcualtePositionTimestepEuler(mp->position, timestep, veloc); + auto veloc = calcualteVelocityTimestepEuler(masspoint1.velocity, timestep, calculateAcceleration(force, 10.)); + auto pos = calcualtePositionTimestepEuler(masspoint1.position, timestep, veloc); - auto veloc2 = calcualteVelocityTimestepEuler(mp2->velocity, timestep, calculateAcceleration(foreP2, 10.)); - auto pos2 = calcualtePositionTimestepEuler(mp2->position, timestep, veloc2); + auto veloc2 = calcualteVelocityTimestepEuler(masspoint2.velocity, timestep, calculateAcceleration(foreP2, 10.)); + auto pos2 = calcualtePositionTimestepEuler(masspoint2.position, timestep, veloc2); // Update Positions and Velocity - mp->position = pos; - mp->velocity = veloc; - mp2->position = pos2; - mp2->velocity = veloc2; + masspoint1.position = pos; + masspoint1.velocity = veloc; + + masspoint2.position = pos2; + masspoint2.velocity = veloc2; +} + +void MassSpringSystemSimulator::printSpring(const Spring& spring) +{ + auto mp1 = spring.mp1.lock(); + auto mp2 = spring.mp2.lock(); + printf("Masspoint 1:\nPosition: %s \nVelocity: %s\n\n", mp1->position.toString().c_str(), mp1->velocity.toString().c_str()); + printf("Masspoint 2:\nPosition: %s \nVelocity: %s\n", mp2->position.toString().c_str(), mp2->velocity.toString().c_str()); } diff --git a/Simulations/MassSpringSystemSimulator.h b/Simulations/MassSpringSystemSimulator.h index d40aee9..520ed02 100644 --- a/Simulations/MassSpringSystemSimulator.h +++ b/Simulations/MassSpringSystemSimulator.h @@ -42,7 +42,9 @@ public: Vec3 calcualtePositionTimestepEuler(Vec3 oldPosition, float timestep, Vec3 veloctiy); Vec3 calcualteVelocityTimestepEuler(Vec3 oldVelocity, float timestep, Vec3 acceleration); Vec3 calculateAcceleration(Vec3 acceleration, float mass); - void Euler(int index1, int index2, int indexSpring, float timestep); + void Euler(MassPoint& masspoint1, MassPoint& masspoint2, Spring& spring, float timestep); + + void printSpring(const Spring& spring); // Do Not Change void setIntegrator(int integrator) {