void Normalize(void) { static float Error = 0.0; static float Temp[3][3]; static float Renorm = 0.0; static boolean Problem = FALSE; static byte r; Error= -VDot(&DCM_M[0][0], &DCM_M[1][0]) * 0.5; //eq.19 VScale(&Temp[0][0], &DCM_M[1][0], Error); //eq.19 VScale(&Temp[1][0], &DCM_M[0][0], Error); //eq.19 VAdd(&Temp[0][0], &Temp[0][0], &DCM_M[0][0]); //eq.19 VAdd(&Temp[1][0], &Temp[1][0], &DCM_M[1][0]); //eq.19 VCross(&Temp[2][0],&Temp[0][0], &Temp[1][0]); // c= a * b eq.20 #if EXTENDED == 1 for ( r= 0; r < 3; r++ ) { Renorm= VDot(&Temp[r][0],&Temp[r][0]); if ( Renorm < 1.5625 && Renorm > 0.64 ) Renorm = 0.5 * (3.0 - Renorm); //eq.21 else if ( Renorm < 100.0 && Renorm > 0.01 ) Renorm = 1.0 / sqrt( Renorm ); else Problem = TRUE; VScale(&DCM_M[r][0], &Temp[r][0], Renorm); } if ( Problem ) // Our solution is blowing up and we will force back to initial condition. Hope we are not upside down! { DCM_M[0][0] = 1.0; DCM_M[0][1] = 0.0; DCM_M[0][2] = 0.0; DCM_M[1][0] = 0.0; DCM_M[1][1] = 1.0; DCM_M[1][2] = 0.0; DCM_M[2][0] = 0.0; DCM_M[2][1] = 0.0; DCM_M[2][2] = 1.0; Problem = TRUE; } #else for ( r= 0; r < 3; r++ ) { Renorm = 0.5 * (3.0 - VDot(&Temp[r][0], &Temp[r][0])); //eq.21 VScale(&DCM_M[r][0], &Temp[r][0], Renorm); } #endif // EXTENDED } // Normalize
void ComputeForcesDipoleF () { VecR vc, vn, vs; real fMult, gr, gs, gu, pc, ps, sumC, sumS, t, w; int n, nvv, nx, ny, nz; gu = 2. * M_PI * dipoleInt / Cube (region.x); gr = 4. * M_PI * gu / region.x; gs = 2. * gu; EvalSinCos (); w = Sqr (M_PI / (region.x * alpha)); for (nz = 0; nz <= fSpaceLimit; nz ++) { for (ny = - fSpaceLimit; ny <= fSpaceLimit; ny ++) { for (nx = - fSpaceLimit; nx <= fSpaceLimit; nx ++) { VSet (vn, nx, ny, nz); nvv = VLenSq (vn); if (nvv == 0 || nvv > Sqr (fSpaceLimit)) continue; fMult = 2. * exp (- w * nvv) / nvv; if (nz == 0) fMult *= 0.5; sumC = sumS = 0.; DO_MOL { VSet (vc, tCos[abs (nx)][n].x, tCos[abs (ny)][n].y, tCos[nz][n].z); VSet (vs, tSin[abs (nx)][n].x, tSin[abs (ny)][n].y, tSin[nz][n].z); if (nx < 0) vs.x = - vs.x; if (ny < 0) vs.y = - vs.y; pc = vc.x * vc.y * vc.z - vc.x * vs.y * vs.z - vs.x * vc.y * vs.z - vs.x * vs.y * vc.z; ps = vs.x * vc.y * vc.z + vc.x * vs.y * vc.z + vc.x * vc.y * vs.z - vs.x * vs.y * vs.z; sumC += VDot (vn, mol[n].s) * pc; sumS += VDot (vn, mol[n].s) * ps; } DO_MOL { VSet (vc, tCos[abs (nx)][n].x, tCos[abs (ny)][n].y, tCos[nz][n].z); VSet (vs, tSin[abs (nx)][n].x, tSin[abs (ny)][n].y, tSin[nz][n].z); if (nx < 0) vs.x = - vs.x; if (ny < 0) vs.y = - vs.y; pc = vc.x * vc.y * vc.z - vc.x * vs.y * vs.z - vs.x * vc.y * vs.z - vs.x * vs.y * vc.z; ps = vs.x * vc.y * vc.z + vc.x * vs.y * vc.z + vc.x * vc.y * vs.z - vs.x * vs.y * vs.z; t = gr * fMult * VDot (vn, mol[n].s) * (sumC * ps - sumS * pc); VVSAdd (mol[n].ra, t, vn); t = gs * fMult * (sumC * pc + sumS * ps); VVSAdd (mol[n].sa, - t, vn); } uSum += gu * fMult * (Sqr (sumC) + Sqr (sumS)); } } } }
static void plane_intersect(plane * pln, ray * ry) { flt t,td; t=-(pln->d + VDot(&pln->norm, &ry->o)); td=VDot(&pln->norm, &ry->d); if (td != 0.0) { t /= td; if (t > 0.0) add_intersection(t,(object *) pln, ry); } }
static Vector Closest_Line_Point(Vector dir, Vector line_pt, Vector pt) { Vector result; double temp_d; /* Need to find a perpendicular from the point to the line. */ VSub(pt, line_pt, result); temp_d = VDot(result, dir) / VDot(dir, dir); VScalarMul(dir, temp_d, result); VAdd(result, line_pt, result); return result; }
static void Smooth_Triangle_Normal(VECTOR Result, OBJECT *Object, INTERSECTION *Inter) { int Axis; DBL u, v; VECTOR PIMinusP1; SMOOTH_TRIANGLE *Triangle = (SMOOTH_TRIANGLE *)Object; VSub(PIMinusP1, Inter->IPoint, Triangle->P1); VDot(u, PIMinusP1, Triangle->Perp); if (u < EPSILON) { Assign_Vector(Result, Triangle->N1); return; } Axis = Triangle->vAxis; v = (PIMinusP1[Axis] / u + Triangle->P1[Axis] - Triangle->P2[Axis]) / (Triangle->P3[Axis] - Triangle->P2[Axis]); /* This is faster. [DB 8/94] */ Result[X] = Triangle->N1[X] + u * (Triangle->N2[X] - Triangle->N1[X] + v * (Triangle->N3[X] - Triangle->N2[X])); Result[Y] = Triangle->N1[Y] + u * (Triangle->N2[Y] - Triangle->N1[Y] + v * (Triangle->N3[Y] - Triangle->N2[Y])); Result[Z] = Triangle->N1[Z] + u * (Triangle->N2[Z] - Triangle->N1[Z] + v * (Triangle->N3[Z] - Triangle->N2[Z])); VNormalize(Result, Result); }
Bullet::Bullet(VECTOR direction, VECTOR translation, int damage, float speed, BULLET_TYPE bulletType,float size) :Object(direction,translation) { _damage = damage; _size = size; _speed = speed; _bulletType = bulletType; _count = 0; _targetEnemy = NULL; _hit = false; if (_bulletType == BULLET_TYPE_PLAYER_HORMING) { float mdist = FLT_MAX; auto &enemies = ObjectField::getObjectField().Enemies; for (auto& enemy : enemies) { VECTOR v = VSub(_translation, enemy.GetTranslation()); float dist = VDot(v, v); if (mdist > dist) { mdist = dist; _targetEnemy = &enemy; } } } }
void SingleEvent () { real vvSum; real sp; int n; NextEvent (); if (evIdB < MOL_LIMIT) { ProcessCollision (); ++ collCount; } else if (evIdB < MOL_LIMIT + NDIM * 2 || evIdB >= MOL_LIMIT + 100) { ProcessCellCrossing (); ++ crossCount; } else if (evIdB == MOL_LIMIT + 6) { UpdateSystem (); nextSumTime += intervalSum; ScheduleEvent (0, MOL_LIMIT + 6, nextSumTime); VZero (vSum); vvSum = 0.; sp = 0.; DO_MOL { VVAdd (vSum, mol[n].rv); vvSum += VLenSq (mol[n].rv); sp += VDot (mol[n].r, gravField); } kinEnVal = vvSum * 0.5 / nMol; totEnVal = kinEnVal - sp / nMol; PrintSummary (stdout); } else if (evIdB == MOL_LIMIT + 7) {
void ApplyThermostat () { RMat mc, mt; VecR vt, waB, wvB; real s1, s2, vFac; int n; s1 = s2 = 0.; DO_MOL { VSAdd (vt, mol[n].rv, 0.5 * deltaT, mol[n].ra); s1 += VDot (vt, mol[n].ra); s2 += VLenSq (vt); VSAdd (vt, mol[n].wv, 0.5 * deltaT, mol[n].wa); MVMulT (wvB, mol[n].rMatT.u, vt); MVMulT (waB, mol[n].rMatT.u, mol[n].wa); s1 += VWDot (mInert, wvB, waB); s2 += VWLenSq (mInert, wvB); } vFac = - s1 / s2; DO_MOL { VSAdd (vt, mol[n].rv, 0.5 * deltaT, mol[n].ra); VVSAdd (mol[n].ra, vFac, vt); VSAdd (vt, mol[n].wv, 0.5 * deltaT, mol[n].wa); VVSAdd (mol[n].wa, vFac, vt); } }
static void cylinder_normal(const cylinder * cyl, const vector * pnt, const ray * incident, vector * N) { vector a, b; flt t, invlen, invlen2; a.x = pnt->x - cyl->ctr.x; a.y = pnt->y - cyl->ctr.y; a.z = pnt->z - cyl->ctr.z; b=cyl->axis; invlen = 1.0 / SQRT(b.x*b.x + b.y*b.y + b.z*b.z); b.x *= invlen; b.y *= invlen; b.z *= invlen; VDOT(t, a, b); N->x = pnt->x - (b.x * t + cyl->ctr.x); N->y = pnt->y - (b.y * t + cyl->ctr.y); N->z = pnt->z - (b.z * t + cyl->ctr.z); invlen2 = 1.0 / SQRT(N->x*N->x + N->y*N->y + N->z*N->z); N->x *= invlen2; N->y *= invlen2; N->z *= invlen2; /* Flip surface normal to point toward the viewer if necessary */ if (VDot(N, &(incident->d)) > 0.0) { N->x=-N->x; N->y=-N->y; N->z=-N->z; } }
static void cylinder_normal(cylinder * cyl, vector * pnt, ray * incident, vector * N) { vector a,b,c; flt t; VSub((vector *) pnt, &(cyl->ctr), &a); c=cyl->axis; VNorm(&c); VDOT(t, a, c); b.x = c.x * t + cyl->ctr.x; b.y = c.y * t + cyl->ctr.y; b.z = c.z * t + cyl->ctr.z; VSub(pnt, &b, N); VNorm(N); if (VDot(N, &(incident->d)) > 0.0) { /* make cylinder double sided */ N->x=-N->x; N->y=-N->y; N->z=-N->z; } }
/* Boolean ** Point_On_Plane(Vector normal, double plane_pt, Vector pt) ** Returns TRUE if the point pt lies in the plane defined by plane_pt and ** normal. */ static Boolean Point_On_Plane(Vector normal, double plane_pt, Vector pt) { double temp1 = VDot(normal, pt); return DEqual(temp1, plane_pt); }
float Vfunc(int which, float* v1, float* v2, float* vresult, float scalar) { int i = 0; float fTmp[3]; if (which == 2) { // vresult = v1 - v2 for (; i < 3; i++) vresult[i] = v1[i] - v2[i]; } if (which == 4) { // vresult = scalar * v1 for (; i < 3; ++i) vresult[i] = scalar * v1[i]; } if (which == 6) { // returns distance between v1 and v2 VSub(v1, v2, fTmp); // fTmp = v1 - v2 return VLen(fTmp); } if (which == 8) return acosf(VDot(v1, v2)/(VLen(v1) * VLen(v2)))*180.0/PI; if (which == 9) { // unit vector pointing from v1 toward v2 VSub(v2, v1, vresult); VUnit(vresult); } return 0; }
int D_Iteration_HCompl_z3(const VECTOR IPoint, const Fractal *HCompl, const VECTOR& Direction, DBL *Dist, DBL **IterStack) { int i; DBL xx, yy, zz, ww; DBL Exit_Value, F_Value, Step; DBL x, y, z, w; VECTOR H_Normal; x = IterStack[X][0] = IPoint[X]; y = IterStack[Y][0] = IPoint[Y]; z = IterStack[Z][0] = IPoint[Z]; w = IterStack[W][0] = (HCompl->SliceDist - HCompl->Slice[X]*x - HCompl->Slice[Y]*y - HCompl->Slice[Z]*z)/HCompl->Slice[T]; Exit_Value = HCompl->Exit_Value; for (i = 1; i <= HCompl->Num_Iterations; ++i) { F_Value = x * x + y * y + z * z + w * w; if (F_Value > Exit_Value) { Normal_Calc_HCompl_z3(H_Normal, i - 1, HCompl, IterStack); VDot(Step, H_Normal, Direction); if (Step < -Fractal_Tolerance) { Step = -2.0 * Step; if ((F_Value > HCompl->Precision * Step) && (F_Value < 30 * HCompl->Precision * Step)) { *Dist = F_Value / Step; return (false); } } *Dist = HCompl->Precision; return (false); } /*************** Case: z->z^2+c *********************/ HSqr(xx, yy, zz, ww, x, y, z, w); x = IterStack[X][i] = xx + HCompl->Julia_Parm[X]; y = IterStack[Y][i] = yy + HCompl->Julia_Parm[Y]; z = IterStack[Z][i] = zz + HCompl->Julia_Parm[Z]; w = IterStack[W][i] = ww + HCompl->Julia_Parm[T]; } *Dist = HCompl->Precision; return (true); }
double Distance_Point_To_Plane(Vector norm, Vector plane_pt, Vector pt) { Vector temp_v; VSub(pt, plane_pt, temp_v); return VDot(temp_v, norm); }
static int Intersect_Plane (RAY *Ray, PLANE *Plane, DBL *Depth) { DBL NormalDotOrigin, NormalDotDirection; VECTOR P, D; Increase_Counter(stats[Ray_Plane_Tests]); if (Plane->Trans == NULL) { VDot(NormalDotDirection, Plane->Normal_Vector, Ray->Direction); if (fabs(NormalDotDirection) < EPSILON) { return(false); } VDot(NormalDotOrigin, Plane->Normal_Vector, Ray->Initial); } else { MInvTransPoint(P, Ray->Initial, Plane->Trans); MInvTransDirection(D, Ray->Direction, Plane->Trans); VDot(NormalDotDirection, Plane->Normal_Vector, D); if (fabs(NormalDotDirection) < EPSILON) { return(false); } VDot(NormalDotOrigin, Plane->Normal_Vector, P); } *Depth = -(NormalDotOrigin + Plane->Distance) / NormalDotDirection; if ((*Depth >= DEPTH_TOLERANCE) && (*Depth <= Max_Distance)) { Increase_Counter(stats[Ray_Plane_Tests_Succeeded]); return (true); } else { return (false); } }
bool Plane::Intersect(const Ray& ray, DBL *Depth, TraceThreadData *Thread) const { DBL NormalDotOrigin, NormalDotDirection; VECTOR P, D; Thread->Stats()[Ray_Plane_Tests]++; if (Trans == NULL) { VDot(NormalDotDirection, Normal_Vector, ray.Direction); if (fabs(NormalDotDirection) < EPSILON) { return(false); } VDot(NormalDotOrigin, Normal_Vector, ray.Origin); } else { MInvTransPoint(P, ray.Origin, Trans); MInvTransDirection(D, ray.Direction, Trans); VDot(NormalDotDirection, Normal_Vector, D); if (fabs(NormalDotDirection) < EPSILON) { return(false); } VDot(NormalDotOrigin, Normal_Vector, P); } *Depth = -(NormalDotOrigin + Distance) / NormalDotDirection; if ((*Depth >= DEPTH_TOLERANCE) && (*Depth <= MAX_DISTANCE)) { Thread->Stats()[Ray_Plane_Tests_Succeeded]++; return (true); } else { return (false); } }
void ApplyThermostat () { real s1, s2, vFac; int n; s1 = s2 = 0.; DO_MOL { s1 += VDot (mol[n].rv, mol[n].ra); s2 += VLenSq (mol[n].rv); } DO_MOL { s1 += mInert * VDot (mol[n].sv, mol[n].sa); s2 += mInert * VLenSq (mol[n].sv); } vFac = - s1 / s2; DO_MOL VVSAdd (mol[n].ra, vFac, mol[n].rv); DO_MOL VVSAdd (mol[n].sa, vFac, mol[n].sv); }
static int Inside_Plane (VECTOR IPoint, OBJECT *Object) { DBL Temp; VECTOR P; if (((PLANE *)Object)->Trans == NULL) { VDot (Temp, IPoint, ((PLANE *)Object)->Normal_Vector); } else { MInvTransPoint(P, IPoint, ((PLANE *)Object)->Trans); VDot (Temp, P, ((PLANE *)Object)->Normal_Vector); } return((Temp + ((PLANE *)Object)->Distance) < EPSILON); }
static void ring_normal(ring * rng, vector * pnt, ray * incident, vector * N) { *N=rng->norm; VNorm(N); if (VDot(N, &(incident->d)) > 0.0) { N->x=-N->x; N->y=-N->y; N->z=-N->z; } }
bool Plane::Inside(const VECTOR IPoint, TraceThreadData *Thread) const { DBL Temp; VECTOR P; if(Trans == NULL) { VDot(Temp, IPoint, Normal_Vector); } else { MInvTransPoint(P, IPoint, Trans); VDot(Temp, P, Normal_Vector); } return((Temp + Distance) < EPSILON); }
static int compute_smooth_triangle(SMOOTH_TRIANGLE *Triangle) { VECTOR P3MinusP2, VTemp1, VTemp2; DBL x, y, z, uDenominator, Proj; VSub(P3MinusP2, Triangle->P3, Triangle->P2); x = fabs(P3MinusP2[X]); y = fabs(P3MinusP2[Y]); z = fabs(P3MinusP2[Z]); Triangle->vAxis = max3_coordinate(x, y, z); VSub(VTemp1, Triangle->P2, Triangle->P3); VNormalize(VTemp1, VTemp1); VSub(VTemp2, Triangle->P1, Triangle->P3); VDot(Proj, VTemp2, VTemp1); VScaleEq(VTemp1, Proj); VSub(Triangle->Perp, VTemp1, VTemp2); VNormalize(Triangle->Perp, Triangle->Perp); VDot(uDenominator, VTemp2, Triangle->Perp); VInverseScaleEq(Triangle->Perp, -uDenominator); /* Degenerate if smooth normals are more than 90 from actual normal or its inverse. */ VDot(x,Triangle->Normal_Vector,Triangle->N1); VDot(y,Triangle->Normal_Vector,Triangle->N2); VDot(z,Triangle->Normal_Vector,Triangle->N3); if ( ((x<0.0) && (y<0.0) && (z<0.0)) || ((x>0.0) && (y>0.0) && (z>0.0)) ) { return(true); } Set_Flag(Triangle, DEGENERATE_FLAG); return(false); }
static void sphere_normal(sphere * spr, vector * pnt, ray * incident, vector * N) { VSub((vector *) pnt, &(spr->ctr), N); VNorm(N); if (VDot(N, &(incident->d)) > 0.0) { N->x=-N->x; N->y=-N->y; N->z=-N->z; } }
static void light_normal(point_light * l, vector * pnt, ray * incident, vector * N) { VSub((vector *) pnt, &(l->ctr), N); VNorm(N); if (VDot(N, &(incident->d)) > 0.0) { N->x=-N->x; N->y=-N->y; N->z=-N->z; } }
void ComputeDipoleAccel () { real t; int n; DO_MOL { t = VDot (mol[n].sa, mol[n].s) + mInert * VLenSq (mol[n].sv); VVSAdd (mol[n].sa, - t, mol[n].s); VScale (mol[n].sa, 1. / mInert); } }
static void ring_intersect(ring * rng, ray * ry) { flt d; flt t,td; vector hit, pnt; d = -VDot(&(rng->ctr), &(rng->norm)); t=-(d+VDot(&(rng->norm), &(ry->o))); td=VDot(&(rng->norm),&(ry->d)); if (td != 0.0) { t= t / td; if (t>=0.0) { hit=Raypnt(ry, t); VSUB(hit, rng->ctr, pnt); VDOT(td, pnt, pnt); td=sqrt(td); if ((td > rng->inrad) && (td < rng->outrad)) add_intersection(t,(object *) rng, ry); } } }
static void tri_normal(tri * trn, vector * pnt, ray * incident, vector * N) { CROSS((*N), trn->edge1, trn->edge2); VNorm(N); if (VDot(N, &(incident->d)) > 0.0) { N->x=-N->x; N->y=-N->y; N->z=-N->z; } }
void ComputeForcesDipoleR () { VecR dr, w; real a1, a2, a3, alpha2, d, irPi, rr, rrCut, rri, sr1, sr2, ss, t; int j1, j2, n; rrCut = Sqr (0.5 * region.x); irPi = 1. / sqrt (M_PI); alpha2 = Sqr (alpha); DO_MOL VZero (mol[n].sa); for (j1 = 0; j1 < nMol - 1; j1 ++) { for (j2 = j1 + 1; j2 < nMol; j2 ++) { VSub (dr, mol[j1].r, mol[j2].r); VWrapAll (dr); rr = VLenSq (dr); if (rr < rrCut) { d = sqrt (rr); rri = 1. / rr; t = 2. * dipoleInt * alpha * exp (- alpha2 * rr) * rri * irPi; a1 = dipoleInt * erfc (alpha * d) * rri / d + t; a2 = 3. * a1 * rri + 2. * alpha2 * t; a3 = 5. * a2 * rri + 4. * Sqr (alpha2) * t; ss = VDot (mol[j1].s, mol[j2].s); sr1 = VDot (mol[j1].s, dr); sr2 = VDot (mol[j2].s, dr); VSSAdd (w, sr2, mol[j1].s, sr1, mol[j2].s); t = (a2 * ss - a3 * sr1 * sr2); VSSAdd (w, t, dr, a2, w); VVAdd (mol[j1].ra, w); VVSub (mol[j2].ra, w); VVSAdd (mol[j1].sa, - a1, mol[j2].s); VVSAdd (mol[j1].sa, a2 * sr2, dr); VVSAdd (mol[j2].sa, - a1, mol[j1].s); VVSAdd (mol[j2].sa, a2 * sr1, dr); uSum += a1 * ss - a2 * sr1 * sr2; } } } uSum -= 2. * dipoleInt * Cube (alpha) * nMol * irPi / 3.; }
void EvalRdf () { VecR dr; real deltaR, normFac, rr, sr1, sr2, ss; int j1, j2, k, n; if (countRdf == 0) { for (k = 0; k < 3; k ++) { for (n = 0; n < sizeHistRdf; n ++) histRdf[k][n] = 0.; } } deltaR = rangeRdf / sizeHistRdf; for (j1 = 0; j1 < nMol - 1; j1 ++) { for (j2 = j1 + 1; j2 < nMol; j2 ++) { VSub (dr, mol[j1].r, mol[j2].r); VWrapAll (dr); rr = VLenSq (dr); if (rr < Sqr (rangeRdf)) { ss = VDot (mol[j1].s, mol[j2].s); sr1 = VDot (mol[j1].s, dr); sr2 = VDot (mol[j2].s, dr); n = sqrt (rr) / deltaR; ++ histRdf[0][n]; histRdf[1][n] += ss; histRdf[2][n] += 3. * sr1 * sr2 / rr - ss; } } } ++ countRdf; if (countRdf == limitRdf) { normFac = VProd (region) / (2. * M_PI * Cube (deltaR) * Sqr (nMol) * countRdf); for (k = 0; k < 3; k ++) { for (n = 0; n < sizeHistRdf; n ++) histRdf[k][n] *= normFac / Sqr (n - 0.5); } PrintRdf (stdout); countRdf = 0; } }
static FeatureData Combine_Plane_Line_Constraints(FeaturePtr c1, FeaturePtr c2) { double dot; double alpha; Vector temp_v; FeatureData result; /* The result is inconsistent if the line is parallel to but not in the ** plane, the line if it is parallel and in the plane, or the point ** of intersection otherwise. */ dot = VDot( c1->f_vector, c2->f_vector ); if ( IsZero(dot) ) { /* The line and plane are parallel. */ if ( Point_On_Plane(c1->f_vector, c1->f_value, c2->f_point) ) { /* The line lies in the plane. */ return *c2; } else { result.f_type = inconsistent_feature; return result; } } /* Find the intersection point. */ alpha = ( VDot(c1->f_vector, c1->f_point) - VDot(c1->f_vector, c2->f_point) ) / dot; result.f_type = point_feature; VScalarMul(c2->f_vector, alpha, temp_v); VAdd(temp_v, c2->f_point, result.f_point); return result; }
void ApplyThermostat () { real s1, s2, vFac; VecR w; int n; s1 = s2 = 0.; DO_MOL { s1 += VDot (mol[n].rv, mol[n].ra); s2 += VLenSq (mol[n].rv); } DO_MOL { ComputeAngVel (n, &w); s1 += VDot (w, mol[n].torq); s2 += VWLenSq (mInert, w); } vFac = - s1 / s2; DO_MOL { VVSAdd (mol[n].ra, vFac, mol[n].rv); QSAdd (mol[n].qa, mol[n].qa, vFac, mol[n].qv); } }