void Ball::Collide3DWall(const Vertex3Ds& hitNormal, const float elasticity, float antifriction, float scatter_angle) { //speed normal to wall float dot = vel.Dot(hitNormal); if (dot >= -C_LOWNORMVEL ) // nearly receding ... make sure of conditions { // otherwise if clearly approaching .. process the collision if (dot > C_LOWNORMVEL) return; //is this velocity clearly receding (i.e must > a minimum) #ifdef C_EMBEDDED if (m_coll.distance < -C_EMBEDDED) dot = -C_EMBEDSHOT; // has ball become embedded???, give it a kick else return; #endif } #ifdef C_DISP_GAIN // correct displacements, mostly from low velocity, alternative to acceleration processing float hdist = -C_DISP_GAIN * m_coll.distance; // limit delta noise crossing ramps, if (hdist > 1.0e-4f) // when hit detection checked it what was the displacement { if (hdist > C_DISP_LIMIT) hdist = C_DISP_LIMIT; // crossing ramps, delta noise pos += hdist * hitNormal; // push along norm, back to free area // use the norm, but this is not correct, reverse time is correct } #endif dot *= -1.005f - elasticity; //!! some small minimum vel += dot * hitNormal; if (antifriction >= 1.0f || antifriction <= 0.0f) antifriction = c_hardFriction; // use global //friction all axes vel *= antifriction; if (scatter_angle <= 0.0f) scatter_angle = c_hardScatter; // if <= 0 use global value scatter_angle *= g_pplayer->m_ptable->m_globalDifficulty; // apply difficulty weighting if (dot > 1.0f && scatter_angle > 1.0e-5f) //no scatter at low velocity { float scatter = rand_mt_m11(); // -1.0f..1.0f scatter *= (1.0f - scatter*scatter)*2.59808f * scatter_angle; // shape quadratic distribution and scale const float radsin = sinf(scatter); // Green's transform matrix... rotate angle delta const float radcos = cosf(scatter); // rotational transform from current position to position at time t const float vxt = vel.x; const float vyt = vel.y; vel.x = vxt *radcos - vyt *radsin; // rotate to random scatter angle vel.y = vyt *radcos + vxt *radsin; } //calc new rolling dynamics AngularAcceleration(hitNormal); }
void Ball::UpdateDisplacements(const float dtime) { if (!fFrozen) { const Vertex3Ds ds = dtime * vel; pos += ds; drsq = ds.LengthSquared(); // used to determine if static ball if (vel.z < 0.f && pos.z <= z_min) //rolling point below the table and velocity driving deeper { pos.z = z_min; // set rolling point to table surface vel.z *= -0.2f; // reflect velocity ... dull bounce vel.x *= c_hardFriction; vel.y *= c_hardFriction; //friction other axiz const Vertex3Ds vnormal(0.0f,0.0f,1.0f); AngularAcceleration(vnormal); } else if (vel.z > 0.f && pos.z >= z_max) //top glass ...contact and going higher { pos.z = z_max; // set diametric rolling point to top glass vel.z *= -0.2f; // reflect velocity ... dull bounce } // side walls are handled via actual collision objects set up in Player::CreateBoundingHitShapes CalcHitRect(); Matrix3 mat3; mat3.CreateSkewSymmetric(m_angularvelocity); Matrix3 addedorientation; addedorientation.MultiplyMatrix(&mat3, &m_orientation); addedorientation.MultiplyScalar(dtime); m_orientation.AddMatrix(&addedorientation, &m_orientation); m_orientation.OrthoNormalize(); Matrix3 matTransposeOrientation; m_orientation.Transpose(&matTransposeOrientation); m_inverseworldinertiatensor.MultiplyMatrix(&m_orientation,&m_inversebodyinertiatensor); m_inverseworldinertiatensor.MultiplyMatrix(&m_inverseworldinertiatensor,&matTransposeOrientation); m_angularvelocity = m_inverseworldinertiatensor.MultiplyVector(m_angularmomentum); } }
int main() { // double d; // cin >> d; Speed v1 = 10.m/2.5s; Speed v2 = 5.m/2.5s; Time dist = (v1+v2) * 10.s / v2; cout << v1 << endl; cout << v2 << endl; cout << 10.m << endl; cout << 20.s << endl; cout << dist << endl; Speed sum_v = v1 + v2; cout << (v1 + v2) / 2.s << endl; cout << AngularAcceleration(5000) << endl; return 0; }