Allegro.cc Forums » Programming Questions » Rope Physics

 Rope Physics
optimusp
Member #7,858
October 2006

This problem seems to be a doozy.

Does anyone know of any good rope physics tutorials (other than NeHe)?

I have the following code, but I'm not getting any swinging motion like a pendulum:

 1 #include 2 #include 3 bool up, down, left, right; 4 5 class rope{ 6 public: 7 class joint{ 8 public: 9 float x1,y1,x2,y2; 10 float velX,velY; 11 }joint[40]; 12 13 float seg_length; //length of segments between joints 14 float air_resistance; //air resistance [negating factor on gravity {9.8}] 15 float damping; //self-explanitory 16 float speed; //didn't know what else to name this 17 18 void deploy(); //initializes the rope 19 void update(bool, bool, bool, bool); //called every game-cycle 20 void draw(BITMAP *); 21 }rope[20]; 22 23 void rope::deploy() { 24 seg_length=5; 25 air_resistance=0.0; 26 damping=.10; 27 speed=0.2; 28 29 for(short i=0; i<40; i++) { 30 joint.x1=SCREEN_W/2; joint.y1=i*seg_length; 31 joint.x2=SCREEN_W/2; joint.y2=i*seg_length; 32 joint.velX=0; joint.velY=0; 33 } 34 }; 35 36 void rope::update(bool up, bool down, bool left, bool right) { 37 if (left) 38 { 39 joint[0].x1--; 40 } 41 if (right) 42 { 43 joint[0].x1++; 44 } 45 if (up) 46 { 47 joint[0].y1--; 48 } 49 if (down) 50 { 51 joint[0].y1++; 52 } 53 54 for(short i=0; i<40; i++) { 55 if (i != 0) 56 { 57 float vx1=joint[i-1].x1-joint.x1; //vector 1: diffrence between x's 58 float vy1=joint[i-1].y1-joint.y1; //vector 1: diffrence between y's 59 int vm1= (int)sqrt(ceil(vx1*vx1+vy1*vy1)); //vector 1: magnitude 60 int ve1= (int)vm1-(int)(seg_length/1); //vector 1: extention 61 62 float vx2=joint[i-1].x1-joint.x1; //vector 2: diffrence between x's 63 float vy2=joint[i-1].y1-joint.y1; //vector 2: diffrence between y's 64 int vm2= (int)sqrt(ceil(vx2*vx2+vy2*vy2)); //vector 2: magnitude 65 int ve2= (int)vm2- (int)seg_length; //vector 2: extention 66 67 float vx=(vx1/vm1*ve1)+(vx2/vm2*ve2); //x's reactant 68 float vy=(vy1/vm1*ve1)+(vy2/vm2*ve2)+9.8; //y's reactant 69 70 joint.velX=joint.velX*damping+(vx*speed); //set velocity x accordingly 71 joint.velY=joint.velY*damping+(vy*speed); //set velocity y accordingly 72 joint.x2=joint.x1+joint.velX; //buffer x 73 joint.y2=joint.y1+joint.velY; //buffer y 74 joint.x1=joint.x2; //copy buffer to physical 75 joint.y1=joint.y2; //copy buffer to physical 76 } 77 } 78 }; 79 80 void rope::draw(BITMAP *buffer) { 81 for(short i=0; i<40; i++) { 82 //draw joint and lines between 83 if (i == 0) 84 { 85 circlefill(buffer, (int)joint.x1, (int)joint.y1, 2, makecol(255,255,255)); 86 } else { 87 circlefill(buffer, (int)joint.x1, (int)joint.y1, 2, makecol(i*2,i*2,255)); 88 } 89 if (i != 0) 90 { 91 line(buffer, (int)joint.x1, (int)joint.y1,(int)joint[i-1].x1, (int)joint[i-1].y1, makecol(i*2,i*2,255)); 92 } 93 } 94 }; 95 96 void init(); 97 void deinit(); 98 99 int main() { 100 init(); 101 BITMAP *buffer = NULL; 102 buffer = create_bitmap(640,480); 103 104 105 rope[0].deploy(); 106 107 while (!key[KEY_ESC]) 108 { 109 if (key[KEY_U]) 110 { 111 //rope[0].update(); 112 } 113 if (key[KEY_D]) 114 { 115 rope[0].deploy(); 116 } 117 118 if (key[KEY_LEFT]) 119 { 120 left = true; 121 } 122 123 if (key[KEY_RIGHT]) 124 { 125 right = true; 126 } 127 128 if (key[KEY_UP]) 129 { 130 up = true; 131 } 132 133 if (key[KEY_DOWN]) 134 { 135 down = true; 136 } 137 138 rope[0].update(up, down, left, right); 139 rope[0].draw(buffer); 140 blit(buffer, screen, 0,0,0,0,640,480);//Draw the buffer to the screen 141 clear_bitmap(buffer); // Clear the contents of the buffer bitmap 142 left = false; 143 right = false; 144 up = false; 145 down = false; 146 } 147 148 deinit(); 149 return 0; 150 } 151 END_OF_MAIN() 152 153 void init() { 154 int depth, res; 155 allegro_init(); 156 depth = desktop_color_depth(); 157 if (depth == 0) depth = 32; 158 set_color_depth(depth); 159 res = set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0); 160 if (res != 0) { 161 allegro_message(allegro_error); 162 exit(-1); 163 } 164 165 install_timer(); 166 install_keyboard(); 167 install_mouse(); 168 /* add other initializations here */ 169 170 } 171 172 void deinit() { 173 clear_keybuf(); 174 /* add other deinitializations here */ 175 }

By the way, this code is an edited version from the code on this thread: