   Trouble with simple 2D rope simulation
  My lecturer showed me how to implement simple rope physics in 30 minutes after one of his classes, and I went home, eager to give it a try. Unfortunately I couldn't quite remember the algorithm off the top of my head, but I think I'm pretty close.The simulation simulates what looks distinctly like a (simple) rope, however the problem I'm having is that it bounces all over the place and just looks like it's having a good ol' spaz. It's hard to describe, so I'll link you to a video of what I'm getting.For reference, here is my code;#include "SFML/Graphics.hpp"#include "cmath"#include "kf/kf_log.h"#include "kf/kf_vector.h"#include "qgf2d/system.h"#include <vector>using namespace std;using namespace qgf;using namespace kf;using namespace sf;void ConstrainMaxDist(kf::Vector2f &origin, kf::Vector2f &destination, UINT maxIterations, UINT dist);UINT screenWidth = 800;UINT screenHeight = 600;float timeScale = 1.0f;int main(){initDirectory();Log::getDefault().addCout();Log::getDefault().addFile("Rope Physics.log");kf_log("Rope Physics");RenderWindow window(VideoMode(screenWidth, screenHeight, 32), "Rope Physics");Image backgroundImage;if(!backgroundImage.LoadFromFile("data/space.jpg")){return EXIT_FAILURE;}Image shipImage;if(!shipImage.LoadFromFile("data/ships.png")){return EXIT_FAILURE;}Image ballImage;if(!ballImage.LoadFromFile("datas/pong/ball.png")){return EXIT_FAILURE;}Sprite backgroundSprite(backgroundImage);Sprite ship(shipImage);vector<Sprite*> Rope;for(int i = 0; i < 15; ++i){Rope.push_back(new Sprite(ballImage, sf::Vector2f(i * ballImage.GetWidth() + 50, 100)));Rope.back()->SetCenter(ballImage.GetWidth() / 2, ballImage.GetHeight() / 2);}float x = 400, y = 300;ship.SetSubRect(IntRect(91,0,128,53));ship.SetCenter(19,27);ship.SetPosition(x, y);while(window.IsOpened()){Event ev;while(window.GetEvent(ev)){if((ev.Type == Event::Closed) || ((ev.Type == Event::KeyPressed) && (ev.Key.Code == Key::Escape))){window.Close();break;}}float deltaT = window.GetFrameTime();if(window.GetInput().IsKeyDown(Key::Left)){x -= 200 * deltaT;}if(window.GetInput().IsKeyDown(Key::Right)){x += 200 * deltaT;}if(window.GetInput().IsKeyDown(Key::Up)){y -= 200 * deltaT;timeScale += 0.2 * deltaT;}if(window.GetInput().IsKeyDown(Key::Down)){y += 200 * deltaT;timeScale -= 0.2 * deltaT;}float mouseX, mouseY;mouseX = window.GetInput().GetMouseX();mouseY = window.GetInput().GetMouseY();ship.SetPosition(x, y);kf::Vector2f gravity(0, 1000 * deltaT * timeScale);kf::Vector2f Source, Destination;//Update rope physics.Rope.at(0)->SetPosition(mouseX, mouseY);for(UINT i = 1; i < Rope.size(); ++i){//Apply gravity. First element is anchored to the mouse so is not governed by gravity.Rope.at(i)->SetPosition(Rope.at(i)->GetPosition().x + gravity.x, Rope.at(i)->GetPosition().y + gravity.y);//Collide with the bottom of the screen.if(Rope.at(i)->GetPosition().y > screenHeight - (ballImage.GetHeight() / 2)){Rope.at(i)->SetPosition(Rope.at(i)->GetPosition().x, screenHeight - (ballImage.GetHeight() / 2));}}for(UINT i = 0; i < Rope.size() - 1; ++i){Source.x = Rope.at(i + 1)->GetPosition().x;Source.y = Rope.at(i + 1)->GetPosition().y;Destination.x = Rope.at(i)->GetPosition().x;Destination.y = Rope.at(i)->GetPosition().y;ConstrainMaxDist(Source, Destination, 10, ballImage.GetWidth());Rope.at(i + 1)->SetPosition(Destination.x, Destination.y);}const char msgA[14] = "Time Scale = ";;char msgB[20], msgC[100];sprintf(msgB, "%f", timeScale);sprintf(msgC, "%s%s", msgA, msgB);sf::String message;message.SetText(msgC);message.SetSize(30);message.SetPosition(20, 20);message.SetColor(Color::White);//Renderwindow.Clear();window.Draw(backgroundSprite);//window.Draw(ship);for(UINT i = 0; i < Rope.size(); ++i){window.Draw(*Rope.at(i));}window.Draw(message);window.Display();}while(!Rope.empty()){if(*Rope.rbegin()){delete (*Rope.rbegin());}Rope.pop_back();}return 0;}void ConstrainMaxDist(kf::Vector2f &origin, kf::Vector2f &destination, UINT maxIterations, UINT dist){kf::Vector2f middle;for(UINT i = 0; i < maxIterations; ++i){middle = (origin + destination) / 2;float length = kf::Vector2f(middle - destination).length();if(length < dist){destination = middle;}else if(length > dist){origin = middle;}else if(length == dist){//Constraint solved.break;}}}I'm fairly certain the fault lies in my algorithm - I believe that I should not be modifying the origin, and should intead be moving everything else relative to it, however I just can't figure out how to go about doing that without screwing up the simulation. Anything I'm missing here?[Edited by - _Sauce_ on June 27, 2009 8:27:35 PM]
  What algorithm is this supposed to be exactly? It looks like a kind of verlet integration, since it doesn't explicitly take velocity into account.(ps. please wrap your code in sorce and /source tags with brackets).   ;  Ah yes, that's what he called it! Verlet integration! :)Thanks, that alone should help alot :)   ;  Your're welcome! :-)Btw, in this thread there's a link to a nice little particle physics tutorial with verlet integration:http://www.gamedev.net/community/forums/topic.asp?topic_id=536055Cheers,Mike   