1Modeling the World as a Mesh of SpringsMike [email protected] State Universitymjb – November 4, 2014Oregon State UniversityComputer Graphicsmeshofsprings.pptxSolving for Motion where there is a Spring0()springFky D+y, +Fmjb – November 4, 2014Oregon State UniversityComputer GraphicsWeight0()FWkyDvt tmm 2Modeling a String as a Group of Masses Connected by Springs+Y+y0“Lumped Masses”+y1mjb – November 4, 2014Oregon State UniversityComputer Graphics+y2Computing Forces in 1Di-1+yi-1Generalize by using indices:110()ii i iFkY Y D ii-1+yimjb – November 4, 2014Oregon State UniversityComputer GraphicsgFMassGravity110()ii i iFkY Y D i+1+yi+13Computing Forces in 2Di-1110()ii iiFkD D +Y+Xi1ˆiiV1ˆiiV11, 1 1 11cosiiiix ii ii iiiixxFF FD X:Y:11, 1 1 11siniiiix ii ii iiiiyyFF FD mjb – November 4, 2014Oregon State UniversityComputer Graphicsi+1110()ii iiFkD D gFMassGravity11, 1 1 11cosiiiix ii ii iiiixxFF FD X:Y:11, 1 1 11siniiiix ii ii iiiiyyFF FD From the Physics Notes:What does a Second Order solution look like in a Program?voidAdvanceOneTimeStep( ){GtD i(St t D i ti 1)GetDerivs( State, Derivatives1);State2.t = State.t + ∆t;State2.x = State.x + Derivatives1.vx * ∆t;State2.vx = State.vx + Derivatives1.ax * ∆t;GetDerivs( State2, Derivatives2 );aavg = ( Derivatives1.ax + Derivatives2.ax) / 2.;vavg = ( Derivatives1.vx + Derivatives2.vx) / 2.;State.x = State.x + vavg * ∆t;State vx=State vx+aavg*∆t;mjb – November 4, 2014Oregon State UniversityComputer GraphicsState.vx= State.vx+ aavg ∆t;State.t = State.t + ∆t ;}4Solve for Each State as a Whole, not as Individual Links:Do it this Wayfor( int i = 0; i < NUMLINKS; i++ ){ GetOneBodysDerivs( Links, i, &vx1[i], &vy1[i], &ax1[i], &ay1[i] );}Correct Second Order solution:Get allthe velocities and accelerations first} for( int i = 0; i < NUMLINKS; i++ ){ TmpLinks[i].vx = Links[i].vx + DT * ax1[i];TmpLinks[i].vy = Links[i].vy + DT * ay1[i];TmpLinks[i].x = Links[i].x + DT * vx1[i];TmpLinks[i].y = Links[i].y + DT * vy1[i];}for( int i = 0; i < NUMLINKS; i++ ){ GetOneBodysDerivs(TmpLinksi&vx2[i] &vy2[i] &ax2[i] &ay2[i]);Apply allthe velocities and accelerationsGet allthe velocities and mjb – November 4, 2014Oregon State UniversityComputer GraphicsGetOneBodysDerivs( TmpLinks, i, &vx2[i], &vy2[i], &ax2[i], &ay2[i] );} for( int i = 0; i < NUMLINKS; i++ ){ Links[i].vx = Links[i].vx + DT * ( ax1[i] + ax2[i] ) / 2.;Links[i].vy = Links[i].vy + DT * ( ay1[i] + ay2[i] ) / 2.;Links[i].x = Links[i].x + DT * ( vx1[i] + vx2[i] ) / 2.; Links[i].y = Links[i].y + DT * ( vy1[i] + vy2[i] ) / 2.; } accelerations firstApply allthe velocities and accelerationsSolve for Each State as a Whole, not as Individual Links:Do it this Wayfor( int i = 0; i < NUMLINKS; i++ ){ GetOneBodysDerivs( Links, i, &vx1[i], &vy1[i], &ax1[i], &ay1[i] );} C Extensions for Array Notion (CEAN) makes it look cleaner, and possibly more efficient:TmpLinks[ 0 : NUMLINKS ].vx = Links[ 0 : NUMLINKS ].vx + DT * ax1[ 0 : NUMLINKS ];TmpLinks[ 0 : NUMLINKS ].vy = Links[ 0 : NUMLINKS i].vy + DT * ay1[ 0 : NUMLINKS ];TmpLinks[ 0 : NUMLINKS ].x = Links[ 0 : NUMLINKS ].x + DT * vx1[ 0 : NUMLINKS ];TmpLinks[ 0 : NUMLINKS ].y = Links[ 0 : NUMLINKS ].y + DT * vy1[ 0 : NUMLINKS ];for( int i = 0; i < NUMLINKS; i++ ){ GetOneBodysDerivs( TmpLinks, i, &vx2[i], &vy2[i], &ax2[i], &ay2[i] );} Links[ 0 : NUMLINKS ]vx=Links[ 0 : NUMLINKS ]vx+DT*(ax1[ 0 : NUMLINKS ]+ax2[ 0 : NUMLINKS ])/2;mjb – November 4, 2014Oregon State UniversityComputer GraphicsLinks[ 0 : NUMLINKS ].vx= Links[ 0 : NUMLINKS ].vx+ DT ( ax1[ 0 : NUMLINKS ] + ax2[ 0 : NUMLINKS ] ) / 2.;Links[ 0 : NUMLINKS ].vy = Links[ 0 : NUMLINKS ].vy + DT * ( ay1[ 0 : NUMLINKS ] + ay2[ 0 : NUMLINKS ] ) / 2.;Links[ 0 : NUMLINKS ].x = Links[ 0 : NUMLINKS ].x + DT * ( vx1[ 0 : NUMLINKS ] + vx2[ 0 : NUMLINKS ] ) / 2.; Links[ 0 : NUMLINKS ].y = Links[ 0 : NUMLINKS ].y + DT * ( vy1[ 0 : NUMLINKS ] + vy2[ 0 : NUMLINKS ] ) / 2.;5voidGetOneBodysDerivs( array, node, float *vxi, float *vyi, float *axi, float *ayi ){float xm, ym; // vector from node to previous node (up the chain)float xp, yp; // vector from node to next node (down the chain)float sumfx = 0.;fl tfWihtGetLinkVelAcc( ), Ifloat sumfy= -Weight;if( node == 0 ){xm = X0 - array[node].x; // (X0,Y0) is the top of the chainym = Y0 - array[node].y;}else{xm = array[node-1].x - array [node].x;ym = array[node-1].y - array [node].y;mjb – November 4, 2014Oregon State UniversityComputer Graphics}float length = sqrt( xm*xm + ym*ym ); // length of the springxm /= length; // normalize the vectorym /= length;float stretch = length - D0; // amount the spring is stretchedfloat force = K * stretch;sumfx += force * xm;sumfy += force * ym; if( node < NUMLINKS-1 ){xp = array [node+1].x - array[node].x;yp = array [node+1].y - array [node].y;length = sqrt( xp*xp + yp*yp );GetLinkVelAcc( ), IIxp /= length;yp /= length;stretch = length - D0;force = K * stretch;sumfx += force * xp;sumfy += force * yp;}sumfx -= Cd * array[node].vx; // dampingsumfy -= Cd * array[node].vy;mjb – November 4, 2014Oregon State UniversityComputer Graphics*vx = array[node].vx;*vy = array[node].vy;*ax = sumfx / Mass;*ay = sumfy / Mass;}6for( int i = 0; i < NUMLINKS; i++ ){ GetOneBodysDerivs( Links, i, &vx1[i], &vy1[i], &ax1[i], &ay1[i] );TmpLinks[i]vx=Links[i]vx+DT*ax1[i];Don’t do it this Way!Incorrect Second Order solution:TmpLinks[i].vx Links[i].vx DT ax1[i];TmpLinks[i].vy = Links[i].vy + DT * ay1[i];TmpLinks[i].x = Links[i].x + DT * vx1[i];TmpLinks[i].y = Links[i].y + DT * vy1[i];}for( int i = 0; i < NUMLINKS; i++ ){ GetOneBodysDerivs( TmpLinks, i, &vx2[i], &vy2[i], &ax2[i], &ay2[i] );Links[i].vx = Links[i].vx + DT * ( ax1[i] + ax2[i] ) / 2.;Links[i].vy = Links[i].vy + DT * ( ay1[i] + ay2[i] ) / 2.;Links[i]x=Links[i] x + DT * ( vx1[i] + vx2[i])/2;mjb – November 4, 2014Oregon State UniversityComputer GraphicsLinks[i].x = Links[i].x + DT * ( vx1[i] + vx2[i] ) / 2.; Links[i].y = Links[i].y + DT * ( vy1[i] +
View Full Document