Blame | Last modification | View Log | Download
╚ёяюы№чє чръюэ ёюїЁрэхэш шьяєы№ёр, яюыєўрхь ЇюЁьєыє ЁрёўхЄр тхъЄюЁют ёъюЁюёЄш °рЁют W1 ш W2 яюёых єфрЁр:W1 = V1 + M2*(1+k)/(M1+M2)*(|V1|*cos(fi1) + |V2|*cos(fi2))*n1;W2 = V2 + M1*(1+k)/(M1+M2)*(|V1|*cos(fi1) + |V2|*cos(fi2))*n2;╟фхё№ fi1 ш fi2 - єуы√ ьхцфє ышэшхщ юс∙хщ эюЁьрыш ш тхъЄюЁрьш ёъюЁюёЄхщ V1 ш V2 т ьюьхэЄ єфрЁр.n1 ш n2 - тхъЄюЁ√ хфшэшўэ√ї эюЁьрыхщ ъ яютхЁїэюёЄш °рЁют т Єюўъх ъюэЄръЄр.|V1| ш |V2| - ьюфєыш тхъЄюЁют ёъюЁюёЄхщ V1 ш V2.void PlayRoomActors::Tick(){Actors::Tick();Vertex3Df min, max;min = *playRoomLevelInfo->GetMin();max = *playRoomLevelInfo->GetMax();// ╬сЁрсюЄрЄ№ яЁюфтшцхэшх ръЄхЁютfloat time = timer->Intervalf();int count = 0;while ( time > 0 ){float timeToHit = time;PlayRoomActor *actor;PlayRoomActor *who = NULL;PlayRoomActor *whom = NULL;Vertex3Df normal, normal2;float when;// ═рїюфшь сышцрщ°хх ёЄюыъэютхэшхfor ( actor = (PlayRoomActor *) actors.GetFirst(); actor;actor = (PlayRoomActor *) actor->GetNext() ){// ╧ЁютхЁшь ёЄюыъэютхэш ё юуЁрэшўшЄхы ьш яюыfor ( int i = 0; i <= 2; i++ ){if ( actor->speed[ i ] ){float dist = max[ i ] - actor->pos[ i ] - actor->radius;when = dist / actor->speed[ i ];//if ( (when >= -maxE) && (when <= maxE) )// when = 0;if ( (when > 0) && (when < timeToHit) ){timeToHit = when;who = actor;whom = NULL;normal.x = normal.y = normal.z = 0;normal[ i ] = -1.0f;}else if ( (dist < 0) && (actor->speed[ i ] > 0) ){Vertex3Df normal2( 0, 0, 0 );normal2[ i ] = -1.0f;//actor->speed[ i ] = -dist;actor->DoHit( NULL, normal2, -dist );};dist = actor->pos[ i ] - min[ i ] - actor->radius;when = -dist / actor->speed[ i ];if ( (when >= -maxE) && (when <= maxE) )when = 0;if ( (when > 0) && (when < timeToHit) ){timeToHit = when;who = actor;whom = NULL;normal.x = normal.y = normal.z = 0;normal[ i ] = +1.0f;}else if ( (dist <= 0) && (actor->speed[ i ] < 0) ){Vertex3Df normal2( 0, 0, 0 );normal2[ i ] = +1.0f;//actor->speed[ i ] = dist;actor->DoHit( NULL, normal2, -dist );};};};// ╧ЁютхЁшь ёЄюыъэютхэш ё фЁєушьш °рЁрьшfor ( PlayRoomActor *other = (PlayRoomActor *) actor->GetNext();other; other = (PlayRoomActor *) other->GetNext() ){if ( IntersectSphereBySphere( actor->pos, actor->radius, actor->speed,other->pos, other->radius, other->speed,&when, &normal2 ) ){if ( (when >= -maxE) && (when <= maxE) )when = 0;if ( (when > 0) && (when < timeToHit) ){timeToHit = when;who = actor;whom = other;normal = normal2;};if ( (when == 0) && ((actor->speed & other->speed) < 0) ){actor->DoHit( other, normal2 );};};};// ╧ЁютхЁшь х∙х ёЄюыъэютхэш ...for ( int i = 0; i < 4; i++ ){if ( IntersectTrisBySphere( playRoomLevel->GetPyramid( i )[ 0 ],playRoomLevel->GetPyramid( i )[ 1 ],playRoomLevel->GetPyramid( i )[ 2 ],actor->pos, actor->radius, actor->speed, &when, &normal2 ) ){if ( (when >= -maxE) && (when <= maxE) )when = 0;if ( (when > 0) && (when < timeToHit) ){timeToHit = when;who = actor;whom = NULL;normal = normal2;}float dist = when * actor->speed.Length();if ( (dist < 0) && (dist >= -actor->radius) && ((actor->speed & normal2) < 0) ){actor->DoHit( other, normal2, -dist );};};};};// ╤фхырхь °руif ( count++ > 20 )timeToHit = time;time -= timeToHit;for ( actor = (PlayRoomActor *) actors.GetFirst(); actor;actor = (PlayRoomActor *) actor->GetNext() ){actor->DoStep( timeToHit );};// ╧Ёютхфхь ёЄюыъэютхэшхif ( who ){who->DoHit( whom, normal );};};};float k = 2.0f; // k = [ 1.0f ... 2.0f ]float coef = mass / (mass + whom->mass);Vertex3Df relSpeed = speed - whom->speed;Vertex3Df nRelSpeed = -((-normal) & relSpeed) * normal;nRelSpeed *= k;speed -= (1.0f - coef) * nRelSpeed;whom->speed += coef * nRelSpeed;mass, whom->mass - ьрёё√ Єхъє∙хую, ш фЁєуюую °рЁрspeed, whom-speed - ёъюЁюёЄш Єхъє∙хую ш фЁєуюую °рЁр (тхъЄюЁ√)normal - эюЁьры№ т Єюўъх ёюєфрЁхэш (эряЁртыхэр тэєЄЁ№ Єхъє∙хую °рЁр) (Єюцх тхъЄюЁ)k - ъю¤ЇЇшЎшхэЄ єяЁєуюёЄш. яЁш ъ = 2 єфрЁ рсёюы■Єэю єяЁєу, яЁш k = 1 - рсё. эхєяЁєуфы эрїюцфхэш эюЁьрыш ёюяЁшъюёэютхэш шёяюы№чютрырё№ Єрър Ї- :// IntersectSphereBySphere: тючтЁр∙рхЄ true, хёыш юъЁєцэюёЄш ё Ёрфшєёрьш// r1 ш r2 ё ЎхэЄЁрьш т Єюўърї c1 ш ё2, фтшцє∙шхё ёю ёъюЁюёЄ ьш v1 ш v2// ёюяЁшъюёэєЄё т Ёхчєы№ЄрЄх ётюхую фтшцхэш .// ┼ёыш тючтЁр∙рхЄ true, Єю т ярЁрьхЄЁ time ёюїЁрэ хЄё тЁхь ъюЄюЁюх фюыцэю// яЁющЄш фю ьюьхэЄр ёюяЁшъюёэютхэш , р т ярЁрьхЄЁ normal - эюЁьры№ ёюяЁшъюёэютрэш , Є.х.// хфшэшўэ√щ тхъЄюЁ, ыхцр∙шщ эр юЄЁхчъх, ёюхфшэ ■∙хщ ЎхэЄЁ√ юъЁєцэюёЄхщ т ьюьхэЄ// ёюяЁшъюёэютхэш , эряЁртыхээ√щ т ёЄюЁюэє ЎхэЄЁр яхЁтющ юъЁєцэюёЄш c1.template < class T >bool IntersectSphereBySphere( const Vertex3D< T > &c1, T r1, const Vertex3D< T > &v1,const Vertex3D< T > &c2, T r2, const Vertex3D< T > &v2,T *time, Vertex3D< T > *normal ){Vertex3D< T > nPos = c1 - c2;Vertex3D< T > nSpeed = v1 - v2;T nSpeedLen = nSpeed.Length();if ( nSpeedLen <= 0 )return false;Vertex3D< T > nSpeedDir = nSpeed / nSpeedLen;T dist = (-nPos) & nSpeedDir;if ( dist <= 0 )return false;T nPosLen = nPos.Length();T r = r1 + r2;T x = nPosLen * nPosLen - dist * dist;if ( x > r * r )return false;T z = dist - sqrtf( r * r - x );*time = z / nSpeedLen;*normal = +nPos + nSpeedDir * z;normal->Normalize();return true;};ЄєЄ ╬╬╧-э√щ ъюф, Єхъє∙шщ юс·хъЄ - °рЁ, р whom - °рЁ ё ъюЄюЁ√ь ёЄюыъэютхэшх яЁюшёїюфшЄ.mass, speed яюы ьрёё ш ёъюЁюёЄхщ ёююЄтхЄёЄтхээю, raduis т фрээюь ЁрёўхЄх эх эєцхэnormal - эюЁьры№ ёЄюыъэютхэш , т ёє∙эюёЄш тхъЄюЁ ёюхфшэ ■∙шщ ЎхэЄЁ√ °рЁют, эю хфшэшўэющ фышэ√. т ъръє■ ёЄюЁюэє эряЁртыхэ єцх эх яюьэ■.хёёхёэю шёяюы№чєхЄё тхъЄюЁэр рыухсЁр, Єръ ўЄю operator& - ёъры Ёэюх єьэюцхэшх тхъЄюЁют (dot product).k ъюэЄЁюышЁєхЄ ёЄхяхэ№ єяЁєуюёЄш єфрЁр, яЁш 2 - рсёюы■Єэю єяЁєушщ.TVector pb1,pb2,xaxis,U1x,U1y,U2x,U2y,V1x,V1y,V2x,V2y;double a,b;// ═рщЄш Ёрёяюыюцхэшх яхЁтюую °рЁрpb1=OldPos[BallColNr1]+ArrayVel[BallColNr1]*BallTime;// ═рщЄш Ёрёяюыюцхэшх тЄюЁюую °рЁрpb2=OldPos[BallColNr2]+ArrayVel[BallColNr2]*BallTime;xaxis=(pb2-pb1).unit(); // ═рщЄш X-Axisa=xaxis.dot(ArrayVel[BallColNr1]); // ═рщЄш яЁюхъЎш■U1x=xaxis*a; // ═рщЄш ёяЁюхЎшЁютрээ√х тхъЄюЁрU1y=ArrayVel[BallColNr1]-U1x;xaxis=(pb1-pb2).unit(); // ╤фхырЄ№ Єръцх, ъръ т√°хb=xaxis.dot(ArrayVel[BallColNr2]); // ═рщЄш яЁюхъЎш■U2x=xaxis*b; // ┬хъЄюЁ√ фы фЁєуюую °рЁрU2y=ArrayVel[BallColNr2]-U2x;V1x=(U1x+U2x-(U1x-U2x))*0.5; // ╤хщўрё эрщЄш эют√х ёъюЁюёЄшV2x=(U1x+U2x-(U2x-U1x))*0.5;V1y=U1y;V2y=U2y;for (j=0;j<NrOfBalls;j++) // ╬сэютшЄ№ тёх эют√х ЁрёяюыюцхэшArrayPos[j]=OldPos[j]+ArrayVel[j]*BallTime;ArrayVel[BallColNr1]=V1x+V1y; // ╙ёЄрэютшЄ№ эют√х тхъЄюЁр ёъюЁюёЄшArrayVel[BallColNr2]=V2x+V2y; // ёЄюыъэєт°шьё °рЁрьяєёЄ№ 1щ °рЁ т яЁюЎхёёх ёЄюыъэютхэш яюыєўрхЄ шчьхэхэшх шьяєы№ёр p, т юЄёєЄёЄтшш ЄЁхэш юэю эряЁртыхээю яю эюЁьрыш n (ышэшш, ёюхф. ЎхэЄЁ√ °рЁют т ьюьхэЄ єфрЁр), p = p*n, Єюуфр яю ╟╤╚ 2щ °рЁ яюыєўрхЄ -p,Єюуфр эют√х ёъюЁюёЄшv1'=v1+p/m1v2'=v2 -p/m2яЁш рсё.єяЁєуюь єфрЁх шч ╟╤▌m1*v1^2+m2*v2^2=m1*(v1+p*n/m1)^2+m2*(v2-p*n/m2)^22*p*(n,v1-v2)+p^2*(1/m1+1/m2)=0p=2*(v2-v1,n)/(1/m1+1/m2)dx1n-dx1=Rxdx2n-dx2=-Rxdy1n-dy1=Rydy2n-dy2=-Rydx1^2 + dy1^2 + dx2^2 + dy2^2 = dx1n^2 + dy1n^2 + dx2n^2 + dy2n^2dx2n=(dx1+dx2)-dx1ndy2n=(dy1+dy2)-dy1nR - "ёшыр" ЁхръЎшш эряЁртыхэр тфюы№ яЁ ьющ, ёюхфшэ ■∙хщ ЎхэЄЁ√ °рЁютърър є эх╕ фышэр? чртшёшЄ юЄ яЁюхъЎшш шёїюфэющ юЄэюёшЄхы№эющ ёъюЁюёЄш эр эюЁьры№ ьхцфє °рЁрьшх╕ ьюфєы№ - ёъры Ёэюх яЁюшчтхфхэшх (v2-v1,n)?TODO:яЁшЄ уштрэшх ъ ыєчрьыєч√ ъЁєяэххЄЁ ёЄш ёЄюы ъэюяъющьхЄъш эх фюыцэ√ яхЁхёхърЄ№ё яю эюьхЁрь ё ртЄюьхЄърьш?хёыш ьхЄър т ЇєэъЎшш, ъюЄюЁр т√°х ёюфхЁцшЄ for/do/if (ё яхЁхїюфюь, р эх ret CC) шыш ъръшх-Єю х∙╕ эхяюэ Єэ√х єёыютш , Єю юэр эх ьюцхЄ яюёўшЄрЄ№ ъръющ-Єю ЁрчьхЁєсЁры ёЄхъЇЁхщь (___sdcc_enter_ix - ьюцхЄ яю тшЄ№ё ш фы тЁхьхээ√ї Ёхчєы№ЄрЄют т√ўшёыхэшщ, ш фрцх эш ё Єюую эш ё ёхую) - эх яюьюуыюьхЄър ю°шсюўэю ухэхЁшЁєхЄё ё Єрсєы Ўшхщ, эю ¤Єю, тЁюфх с√, эх трцэю