Modeling the World as a Mesh of SpringsMike [email protected] State Universitymjb – November 4, 2014Oregon State UniversityComputer Graphicsmeshofsprings.pptxSolving for Motion where there is a Spring+y, +F0()springFky D0()FWkyDvt tmm mjb – November 4, 2014Oregon State UniversityComputer GraphicsWeightModeling a String as a Group of Masses Connected by Springs+y0+Yy0“Lumped Masses”+y1+y2mjb – November 4, 2014Oregon State UniversityComputer GraphicsComputing Forces in 1D+yi-1Generalize by using indices:()FkYYDi-1110()ii i iFkYYD +yi110()ii i iFkYYD i+ygF Mass Gravity110()ii i i i+1+yi+1mjb – November 4, 2014Oregon State UniversityComputer Graphicsi+1Computing Forces in 2D+Y+Xi1()FkDDi-1110()ii iiFkDDˆ11,111cosiiiix ii ii iixxFF FDX:i1iiVˆV,1iiDY:11, 1 1 11siniiiix ii ii iiiiyyFF FD i+1110()ii iiFkDD1iiVi1110()ii iiFkDDgF Mass Gravity11, 1 1 11cosiiiix ii ii iiiixxFF FD X:mjb – November 4, 2014Oregon State UniversityComputer GraphicsY:11, 1 1 11siniiiix ii ii iiiiyyFF FD From the Physics Notes:What does a Second Order solution look like in a Program?voidAdvanceOneTimeStep( )p(){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;vavg= ( Derivatives1.vx + Derivatives2.vx) / 2.;State.x = State.x + vavg * ∆t;State.vx = State.vx + aavg * ∆t;State.t = State.t + ∆t ;}mjb – November 4, 2014Oregon State UniversityComputer GraphicsSolve for Each State as a Whole, not as Individual Links:Do it this Wayfor( int i = 0; i < NUMLINKS; i++ ){ Correct Second Order solution:Get allthe velocities and li fiGetOneBodysDerivs( Links, i, &vx1[i], &vy1[i], &ax1[i], &ay1[i] );} for( int i = 0; i < NUMLINKS; i++ ){ TmpLinks[i].vx=Links[i].vx+DT*ax1[i];accelerations firstAl llth 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];}Apply allthe velocities and accelerationsfor( int i = 0; i < NUMLINKS; i++ ){ GetOneBodysDerivs( TmpLinks, i, &vx2[i], &vy2[i], &ax2[i], &ay2[i] );} Get allthe velocities and accelerations first}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;Apply allthe velocities and 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] + vy2[i] ) / 2.; } velocities and accelerationsSolve for Each State as a Whole, not as Individual Links:Do it this Wayfor( int i = 0; i < NUMLINKS; i++ ){ GtO Bd D i(Li ki&1[i]& 1[i]& 1[i]& 1[i])C Extensions for Array Notion (CEAN) makes it look cleaner, and possibly more efficient:GetOneBodysDerivs( Links, i, &vx1[i], &vy1[i], &ax1[i], &ay1[i] );} 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 ];TLik[ 0 NUMLINKS ] Li k [ 0 NUMLINKS ]DT *1[ 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++ ){ GtO Bd D i(TLiki&2[i]& 2[i]& 2[i]& 2[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.;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.; mjb – November 4, 2014Oregon State UniversityComputer GraphicsvoidGetLinkVelAcc( ), IGetOneBodysDerivs( 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.;float 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;}float length = sqrt( xm*xm + ym*ym ); // length of the springxm /= length; // normalize the vectorym /= length;float stretch = length - D0; // amount the spring is stretchedmjb – November 4, 2014Oregon State UniversityComputer Graphicsfloat force = K * stretch;sumfx += force * xm;sumfy += force * ym;GetLinkVelAcc( ), IIif( node < NUMLINKS-1 ){xp = array [node+1].x - array[node].x;yp= array [node+1] y-array [node] y;yp= array [node+1].y -array [node].y;length = sqrt( xp*xp + yp*yp );xp /= 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;*vx = array[node].vx;*arra [node]*vy = array[node].vy;*ax = sumfx / Mass;*ay = sumfy / Mass;} mjb – November 4, 2014Oregon State UniversityComputer GraphicsDon’t do it this Way!for( int i = 0; i < NUMLINKS; i++ ){ Incorrect Second Order solution:GetOneBodysDerivs( Links, i, &vx1[i], &vy1[i], &ax1[i], &ay1[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];TmpLinks[i].y Links[i].y DT vy1[i];}for( int i = 0; i < NUMLINKS; i++ ){ GtO Bd D i(TLiki&2[i]& 2[i]& 2[i]& 2[i])GetOneBodysDerivs( TmpLinks, i, &vx2[i], &vy2[i], &ax2[i], &ay2[i] );Links[i].vx =
View Full Document