1Modeling the World as a Mesh of SpringsMike [email protected] – November 4, 2014Oregon State UniversityComputer GraphicsOregon State Universitymeshofsprings.pptxSolving for Motion where there is a Spring()FkyD+y, +Fmjb – November 4, 2014Oregon State UniversityComputer GraphicsWeight0()springFkyD 0()FWkyDvt tmm Modeling a String as a Group of Masses Connected by Springs“Lumped Masses”+Y+y0mjb – November 4, 2014Oregon State UniversityComputer Graphics+y1+y2Computing Forces in 1D110()ii i iFkYYD i-1+yi-1+yiGeneralize by using indices:mjb – November 4, 2014Oregon State UniversityComputer GraphicsgFMass Gravity110()ii i iFkYYD ii+1+yi+1Computing Forces in 2Di-1110()ii iiFkDD 1ˆiiV+Y11, 1 1 11cosiiiix ii ii iiiixxFF FD X:1iiiyyFF F+Xmjb – November 4, 2014Oregon State UniversityComputer Graphicsii+1110()ii iiFkDD gFMass Gravity1ˆiiVY:11, 1 1 11cosiiiix ii ii iiiixxFF FD X:Y:11, 1 1 11siniiiix ii ii iiiiyyFF FD 11, 1 1 11siniiiix ii ii iiiiyyFF FD From the Physics Notes:What does a Second Order solution look like in a Program?voidAdvanceOneTimeStep( ){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);mjb – November 4, 2014Oregon State UniversityComputer GraphicsGetDerivs( 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;State.t = State.t + ∆t ;}2Solve 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] );} 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];Correct Second Order solution:Get allthe velocities and accelerations firstApply allthe velocities and ltimjb – November 4, 2014Oregon State UniversityComputer GraphicsTmpLinks[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] );} 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.; } accelerationsGet allthe velocities and 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] );} 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 ];C Extensions for Array Notion (CEAN) makes it look cleaner, and possibly more efficient:mjb – November 4, 2014Oregon State UniversityComputer Graphicsfor( 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.;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.; voidGetOneBodysDerivs( 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;GetLinkVelAcc( ), Imjb – November 4, 2014Oregon State UniversityComputer Graphicsym= 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 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 );xp /= length;yp /= length;stretch = length - D0;force = K * stretch;sumfx += force * xp;sumfy+= force*yp;GetLinkVelAcc( ), IImjb – November 4, 2014Oregon State UniversityComputer Graphicssumfy+= force yp;}sumfx -= Cd * array[node].vx; // dampingsumfy -= Cd * array[node].vy;*vx = array[node].vx;*vy = array[node].vy;*ax = sumfx / Mass;*ay = sumfy / Mass;} for( 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];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];}Don’t do it this Way!Incorrect Second Order solution:mjb – November 4, 2014Oregon State UniversityComputer Graphicsfor( 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.; Links[i].y = Links[i].y + DT * ( vy1[i] + vy2[i] ) / 2.; } Changes the state before we are done getting
View Full Document