void drawlinerainbow(int x1, int y1, int x2, int y2) { int i,dx,dy,sdx,sdy,dxabs,dyabs,x,y,px,py; dx=x2-x1; /* the horizontal distance of the line */ dy=y2-y1; /* the vertical distance of the line */ dxabs=abs(dx); dyabs=abs(dy); sdx=signum(dx); sdy=signum(dy); x=dyabs>>1; y=dxabs>>1; px=x1; py=y1; putpixel(px,py,4); if (dxabs>=dyabs) /* the line is more horizontal than vertical */ { for(i=0;i<dxabs;i++) { y+=dyabs; if (y>=dxabs) { y-=dxabs; py+=sdy; } px+=sdx; if (i%20<5) putpixel(px,py,4); else if (i%20<10) putpixel(px,py,14); else if (i%20<15) putpixel(px,py,2); else putpixel(px,py,1); } } else /* the line is more vertical than horizontal */ { for(i=0;i<dyabs;i++) { x+=dxabs; if (x>=dyabs) { x-=dyabs; px+=sdx; } py+=sdy; if (i%20<5) putpixel(px,py,4); else if (i%20<10) putpixel(px,py,14); else if (i%20<15) putpixel(px,py,2); else putpixel(px,py,1); } } }
static int lwcircle_calculate_gbox_cartesian(const POINT4D *p1, const POINT4D *p2, const POINT4D *p3, GBOX *gbox) { POINT2D xmin, ymin, xmax, ymax; POINT4D center; int p2_side; double radius; LWDEBUG(2, "lwcircle_calculate_gbox called."); radius = lwcircle_center(p1, p2, p3, ¢er); /* Negative radius signals straight line, p1/p2/p3 are colinear */ if (radius < 0.0) { gbox->xmin = FP_MIN(p1->x, p3->x); gbox->ymin = FP_MIN(p1->y, p3->y); gbox->zmin = FP_MIN(p1->z, p3->z); gbox->xmax = FP_MAX(p1->x, p3->x); gbox->ymax = FP_MAX(p1->y, p3->y); gbox->zmax = FP_MAX(p1->z, p3->z); return LW_SUCCESS; } /* Matched start/end points imply circle */ if ( p1->x == p3->x && p1->y == p3->y ) { gbox->xmin = center.x - radius; gbox->ymin = center.y - radius; gbox->zmin = FP_MIN(p1->z,p2->z); gbox->mmin = FP_MIN(p1->m,p2->m); gbox->xmax = center.x + radius; gbox->ymax = center.y + radius; gbox->zmax = FP_MAX(p1->z,p2->z); gbox->mmax = FP_MAX(p1->m,p2->m); return LW_SUCCESS; } /* First approximation, bounds of start/end points */ gbox->xmin = FP_MIN(p1->x, p3->x); gbox->ymin = FP_MIN(p1->y, p3->y); gbox->zmin = FP_MIN(p1->z, p3->z); gbox->mmin = FP_MIN(p1->m, p3->m); gbox->xmax = FP_MAX(p1->x, p3->x); gbox->ymax = FP_MAX(p1->y, p3->y); gbox->zmax = FP_MAX(p1->z, p3->z); gbox->mmax = FP_MAX(p1->m, p3->m); /* Create points for the possible extrema */ xmin.x = center.x - radius; xmin.y = center.y; ymin.x = center.x; ymin.y = center.y - radius; xmax.x = center.x + radius; xmax.y = center.y; ymax.x = center.x; ymax.y = center.y + radius; /* Divide the circle into two parts, one on each side of a line joining p1 and p3. The circle extrema on the same side of that line as p2 is on, are also the extrema of the bbox. */ p2_side = signum(lw_segment_side((POINT2D*)p1, (POINT2D*)p3, (POINT2D*)p2)); if ( p2_side == signum(lw_segment_side((POINT2D*)p1, (POINT2D*)p3, &xmin)) ) gbox->xmin = xmin.x; if ( p2_side == signum(lw_segment_side((POINT2D*)p1, (POINT2D*)p3, &ymin)) ) gbox->ymin = ymin.y; if ( p2_side == signum(lw_segment_side((POINT2D*)p1, (POINT2D*)p3, &xmax)) ) gbox->xmax = xmax.x; if ( p2_side == signum(lw_segment_side((POINT2D*)p1, (POINT2D*)p3, &ymax)) ) gbox->ymax = ymax.y; return LW_SUCCESS; }
/* radix 4 subroutine */ void FR4TR(int in, int nn, real *b0, real *b1, real *b2, real* b3) { real arg, piovn, th2; real *b4 = b0, *b5 = b1, *b6 = b2, *b7 = b3; real t0, t1, t2, t3, t4, t5, t6, t7; real r1, r5, pr, pi; real c1, c2, c3, s1, s2, s3; int j, k, jj, kk, jthet, jlast, ji, jl, jr, int4; int L[16], L1, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11, L12, L13, L14, L15; int j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14; int k0, kl; L[1] = nn / 4; for(k = 2; k < 16; k++) { /* set up L's */ switch (signum(L[k-1] - 2)) { case -1: L[k-1]=2; case 0: L[k]=2; break; case 1: L[k]=L[k-1]/2; } } L15=L[1]; L14=L[2]; L13=L[3]; L12=L[4]; L11=L[5]; L10=L[6]; L9=L[7]; L8=L[8]; L7=L[9]; L6=L[10]; L5=L[11]; L4=L[12]; L3=L[13]; L2=L[14]; L1=L[15]; piovn = PI / nn; ji=3; jl=2; jr=2; for(j1=2;j1<=L1;j1+=2) for(j2=j1;j2<=L2;j2+=L1) for(j3=j2;j3<=L3;j3+=L2) for(j4=j3;j4<=L4;j4+=L3) for(j5=j4;j5<=L5;j5+=L4) for(j6=j5;j6<=L6;j6+=L5) for(j7=j6;j7<=L7;j7+=L6) for(j8=j7;j8<=L8;j8+=L7) for(j9=j8;j9<=L9;j9+=L8) for(j10=j9;j10<=L10;j10+=L9) for(j11=j10;j11<=L11;j11+=L10) for(j12=j11;j12<=L12;j12+=L11) for(j13=j12;j13<=L13;j13+=L12) for(j14=j13;j14<=L14;j14+=L13) for(jthet=j14;jthet<=L15;jthet+=L14) { th2 = jthet - 2; if(th2<=0.0) { for(k=0;k<in;k++) { t0 = b0[k] + b2[k]; t1 = b1[k] + b3[k]; b2[k] = b0[k] - b2[k]; b3[k] = b1[k] - b3[k]; b0[k] = t0 + t1; b1[k] = t0 - t1; } if(nn-4>0) { k0 = in*4 + 1; kl = k0 + in - 1; for (k=k0;k<=kl;k++) { kk = k-1; pr = IRT2 * (b1[kk]-b3[kk]); pi = IRT2 * (b1[kk]+b3[kk]); b3[kk] = b2[kk] + pi; b1[kk] = pi - b2[kk]; b2[kk] = b0[kk] - pr; b0[kk] = b0[kk] + pr; } } } else { arg = th2*piovn; c1 = cos(arg); s1 = sin(arg); c2 = c1*c1 - s1*s1; s2 = c1*s1 + c1*s1; c3 = c1*c2 - s1*s2; s3 = c2*s1 + s2*c1; int4 = in*4; j0=jr*int4 + 1; k0=ji*int4 + 1; jlast = j0+in-1; for(j=j0;j<=jlast;j++) { k = k0 + j - j0; kk = k-1; jj = j-1; r1 = b1[jj]*c1 - b5[kk]*s1; r5 = b1[jj]*s1 + b5[kk]*c1; t2 = b2[jj]*c2 - b6[kk]*s2; t6 = b2[jj]*s2 + b6[kk]*c2; t3 = b3[jj]*c3 - b7[kk]*s3; t7 = b3[jj]*s3 + b7[kk]*c3; t0 = b0[jj] + t2; t4 = b4[kk] + t6; t2 = b0[jj] - t2; t6 = b4[kk] - t6; t1 = r1 + t3; t5 = r5 + t7; t3 = r1 - t3; t7 = r5 - t7; b0[jj] = t0 + t1; b7[kk] = t4 + t5; b6[kk] = t0 - t1; b1[jj] = t5 - t4; b2[jj] = t2 - t7; b5[kk] = t6 + t3; b4[kk] = t2 + t7; b3[jj] = t3 - t6; } jr += 2; ji -= 2; if(ji-jl <= 0) { ji = 2*jr - 1; jl = jr; } } } }
void Player::update(float dt) { if (state_ == PlayerState::Launching) { launch_charge_ += launch_charge_speed_ * dt; launch_charge_ = clamp(launch_charge_,0.0f,1.0f); } aimer_->hold( clamp(aimer_->sequence_frame("charge") + int(aimer_->sequence_duration("charge") * launch_charge_), 0, aimer_->sequence_duration("charge") - 1)); sf::Vector2f friction(0.0f,0.0f); if (!state_machine_.state_in_the_air(state_)) { friction.x = -signum(velocity_.x); friction *= friction_constant_; } else { friction.x = -signum(velocity_.x); friction *= air_friction_constant_; } sf::Vector2f gravity_effect = current_gravity_; if (state_ == PlayerState::Winning) { gravity_effect = sf::Vector2f(0.0f,0.0f); } velocity_ += dt * (acceleration_ + gravity_effect); float velocity_after_friction = velocity_.x + dt * friction.x; // apply friction if (signum(velocity_.x) != signum(velocity_after_friction)) { float dv = velocity_after_friction - velocity_.x; float ratio = (0 - velocity_.x) / dv; move(sf::Vector2f(dt * (velocity_.x + ratio * dv),0.0f)); velocity_.x = 0.0f; } else { velocity_.x = velocity_after_friction; } if (state_ == PlayerState::Winning) { if (dt > 0.0f) { sf::Vector2f dampening = velocity_ * dt; velocity_ -= dampening; } } move(dt * (velocity_ + movement_velocity_)); rotate_aim(dt * current_aim_speed_); if (state_ == PlayerState::Flying) { if (velocity_.y >= 0.0f) { switch_to_state(PlayerState::Falling); } } if (state_ == PlayerState::Landing) { if (!animation().playing()) { switch_to_state(PlayerState::Idle); } } animation().update(dt); aimer_->update(dt); }
int CItem::CompareSibling(const CTreeListItem *tlib, int subitem) const { CItem *other = (CItem *)tlib; int r=0; switch (subitem) { case COL_NAME: if (GetType() == IT_DRIVE) { ASSERT(other->GetType() == IT_DRIVE); r = signum(GetPath().CompareNoCase(other->GetPath())); } else { r = signum(m_name.CompareNoCase(other->m_name)); } break; case COL_SUBTREEPERCENTAGE: if (MustShowReadJobs()) r = signum(m_readJobs - other->m_readJobs); else r = signum(GetFraction() - other->GetFraction()); break; case COL_PERCENTAGE: r = signum(GetFraction() - other->GetFraction()); break; case COL_SUBTREETOTAL: r = signum(GetSize() - other->GetSize()); break; case COL_ITEMS: r = signum(GetItemsCount() - other->GetItemsCount()); break; case COL_FILES: r = signum(GetFilesCount() - other->GetFilesCount()); break; case COL_SUBDIRS: r = signum(GetSubdirsCount() - other->GetSubdirsCount()); break; case COL_LASTCHANGE: { if (m_lastChange < other->m_lastChange) return -1; else if (m_lastChange == other->m_lastChange) return 0; else return 1; } break; case COL_ATTRIBUTES: r = signum(GetSortAttributes() - other->GetSortAttributes()); break; default: ASSERT(false); break; } return r; }
template <typename T> inline T copysign(const T &mag, const T &sign) { return abs(mag) * signum(sign); }
void MisesMat :: give1dStressStiffMtrx(FloatMatrix &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) { this->giveLinearElasticMaterial()->give1dStressStiffMtrx(answer, mode, gp, tStep); MisesMatStatus *status = static_cast< MisesMatStatus * >( this->giveStatus(gp) ); double kappa = status->giveCumulativePlasticStrain(); // increment of cumulative plastic strain as an indicator of plastic loading double tempKappa = status->giveTempCumulativePlasticStrain(); double omega = status->giveTempDamage(); double E = answer.at(1, 1); if ( mode != TangentStiffness ) { return; } if ( tempKappa <= kappa ) { // elastic loading - elastic stiffness plays the role of tangent stiffness answer.times(1 - omega); return; } // === plastic loading === const FloatArray &stressVector = status->giveTempEffectiveStress(); double stress = stressVector.at(1); answer.resize(1, 1); answer.at(1, 1) = ( 1 - omega ) * E * H / ( E + H ) - computeDamageParamPrime(tempKappa) * E / ( E + H ) * stress * signum(stress); }
int PY_Macro2D::update(void) { Domain *theDomain=this->getDomain(); Tt = theDomain->getCurrentTime(); double dt = Tt - Ct; // determine the strain const Vector &disp1 = theNodes[0]->getTrialDisp(); const Vector &disp2 = theNodes[1]->getTrialDisp(); double Ru = disp1(1); // pore water pressure // Use displacements to find the total strain in the element TU = 0.0; for (int i=0; i<2; i++) { TU -= (disp2(i)-disp1(i)) * trans(0,i); } // Find the change in strain double dU = TU - CU; // Declare the other variables required double dz, f, f_, Tzold, Tznew; dz = K/py*(1-(tanh(a*abs(Cz))/tanh(a))*(b+g*signum(dU*Cz)))*dU; Tz = Cz+dz; // Pore Pressure Generation Model Tforce = py*Tz*CS; Ttangent = K*(1-(tanh(a*fabs(Tz))/tanh(a))*(b+g*signum(dU*Tz)))*TS; TW = CW; double dSb = 0.0; if (fabs(Tz) <= 0.67*m2/m1) { TW = CW+fabs(Tforce*dU)/py/(py/K); dSb = exp(-1*pow(TW/w1,1.4))*1.4*pow(TW/w1,0.4)*fabs(Tforce*dU)/py/(py/K)/w1; } double Sff = 1-Ru; double dSd = beta/(0.01+0.99*fabs(Sff-CS0))*pow(CS,p1) *dt/(1+beta/(0.01+0.99*fabs(Sff-CS0))*pow(CS,p1) *dt)*(Sff-CS); TS0 = CS0 - dSb + dSd; if (fabs(Tz) <= 0.67*m2/m1) { TS = TS0; } else { double alp = 0.67*m2/m1; TS = TS0*(1+alp*alp)/(fabs(Tz)*alp+pow((Tz*alp)*(Tz*alp)+(1-Tz*Tz)*(1+alp*alp),0.5)); } // Compute force and tangent // Tforce = py*Tz*TS; // Ttangent = K*(1-(tanh(a*fabs(Tz))/tanh(a))*(b+g*signum(dU*Tz)))*TS; return 0; }
int main(){ px = malloc(sizeof(float)*n); py = malloc(sizeof(float)*n); vx = malloc(sizeof(float)*n); vy = malloc(sizeof(float)*n); mass = malloc(sizeof(float)*n); density = malloc(sizeof(float)*n); pressure = malloc(sizeof(float)*n); fx = malloc(sizeof(float)*n); fy = malloc(sizeof(float)*n); // initialize SDL SDL_Surface *screen; SDL_Event event; if (SDL_Init(SDL_INIT_VIDEO) < 0 ) return 1; if (!(screen = SDL_SetVideoMode(WIDTH, HEIGHT, DEPTH, SDL_FULLSCREEN|SDL_HWSURFACE))){ SDL_Quit(); return 1; } // initialize srand(time(NULL)); for(i=0;i<n;i++){ px[i]=0.4*(i % (int)sqrt(n) / sqrt(n))+0.3+randf()/100; py[i]=0.4*(float)i/(float)n+0.05+randf()/100; vx[i]=0; vy[i]=0; mass[i]=0.2; density[i]=0; pressure[i]=0; } for(iter=0;iter<maxiter;iter++){ // compute density #pragma omp parallel for private(j) schedule(static) num_threads(4) for(i=0; i<n; i++){ density[i] = 0; for(j=0; j<n; j++){ if(dist(i,j)<=h){ density[i] += mass[j]*w(px[i]-px[j], py[i]-py[j]); } } pressure[i] = k*(density[i]-density0); } // compute interactions #pragma omp parallel for private(j) schedule(static) num_threads(4) for(i=0;i<n;i++){ float fpx = 0; float fpy = 0; float fvx = 0; float fvy = 0; for(j=0;j<n;j++){ // check for kernel proximity if(dist(i,j)<=h){ struct Point p = dw(px[i]-px[j],py[i]-py[j]); fpx -= mass[j]*(pressure[i]+pressure[j])/(2*density[j])*p.x; fpy -= mass[j]*(pressure[i]+pressure[j])/(2*density[j])*p.y; fvx -= my*mass[j]*(vx[j]-vx[i])/density[j]*ddw(px[i]-px[j],py[i]-py[j]); fvy -= my*mass[j]*(vy[j]-vy[i])/density[j]*ddw(px[i]-px[j],py[i]-py[j]); } } fx[i]=fpx+fvx; fy[i]=fpy+fvy+g; if(px[i] < xmin){ // outside WEST fy[i] -= signum(fy[i])*min(f*abs(fx[i]),abs(fy[i])); fx[i] = (xmin-px[i]-vx[i]*dt)/(dt*dt); } else if(xmax < px[i]){ // outside EAST fy[i] -= signum(fy[i])*min(f*abs(fx[i]),abs(fy[i])); fx[i] = (xmax-px[i]-vx[i]*dt)/(dt*dt); } else if(py[i] < ymin){ // outside SOUTH fx[i] -= signum(fx[i])*min(f*abs(fy[i]),abs(fx[i])); fy[i] = (ymin-py[i]-vy[i]*dt)/(dt*dt); } else if(xmax < px[i]){ // outside NORTH fx[i] -= signum(fx[i])*min(f*abs(fy[i]),abs(fx[i])); fy[i] = (ymax-py[i]-vy[i]*dt)/(dt*dt); } // do euler steps vx[i] += fx[i]*dt; vy[i] += fy[i]*dt; px[i] += vx[i]*dt; py[i] += vy[i]*dt; } DrawScreen(screen); while(SDL_PollEvent(&event)) { switch (event.type) { case SDL_QUIT: SDL_Quit(); return 0; break; case SDL_KEYDOWN: SDL_Quit(); return 0; break; } } // Uncomment to save screenshots of every 10th frame. //if(iter%10==0){ // char *a = malloc(sizeof(char)*100); // sprintf(a, "tmp/FILE%05d.BMP", frame++); // SDL_SaveBMP(screen, a); //} } SDL_Quit(); return 0; }
int IncidenceMatrix::getValueByIndex(unsigned int i, unsigned int index_in_row) const { assert(i < n_rows); assert(index_in_row < m_indices[i].size()); return signum(m_indices[i][index_in_row]); }
void Stage::moveAndCheckCollisions( Ship **oldShips, Ship **ships, int numShips, int gameTime) { ShipMoveData *shipData = new ShipMoveData[numShips]; // Calculate initial movement and decide on a common sub-tick interval. int intervals = 1; for (int x = 0; x < numShips; x++) { Ship *ship = ships[x]; ShipMoveData shipDatum = shipData[x]; shipDatum.initialized = false; shipDatum.shipCircle = 0; shipDatum.nextShipCircle = 0; if (ship->alive) { shipDatum.initialized = true; Ship *oldShip = oldShips[x]; double force = ship->thrusterForce; double forceAngle = ship->thrusterAngle; shipDatum.dxSpeed = cos(forceAngle) * force; shipDatum.dySpeed = sin(forceAngle) * force; shipDatum.startXSpeed = cos(ship->heading) * ship->speed; shipDatum.startYSpeed = sin(ship->heading) * ship->speed; shipDatum.xSpeed = shipDatum.startXSpeed + shipDatum.dxSpeed; shipDatum.ySpeed = shipDatum.startYSpeed + shipDatum.dySpeed; ship->x += shipDatum.xSpeed; ship->y += shipDatum.ySpeed; ship->hitWall = false; ship->hitShip = false; setSpeedAndHeading(oldShip, ship, &shipDatum); shipDatum.shipCircle = new Circle2D(oldShip->x, oldShip->y, SHIP_RADIUS); shipDatum.nextShipCircle = new Circle2D(0, 0, SHIP_RADIUS); shipDatum.wallCollision = false; shipDatum.minWallImpactDiff = M_PI; shipDatum.wallImpactAngle = 0; shipDatum.wallImpactLine = 0; shipDatum.shipCollision = false; shipDatum.shipCollisionData = new ShipCollisionData*[numShips]; for (int y = 0; y < numShips; y++) { shipDatum.shipCollisionData[y] = 0; } shipDatum.stopped = false; double moveDistance = sqrt(square(ship->x - oldShip->x) + square(ship->y - oldShip->y)); int moveIntervals = ceil(moveDistance / COLLISION_FRAME); intervals = std::max(intervals, moveIntervals); } shipData[x] = shipDatum; } for (int x = 0; x < numShips; x++) { if (ships[x]->alive) { shipData[x].dx = shipData[x].xSpeed / intervals; shipData[x].dy = shipData[x].ySpeed / intervals; } } for (int x = 0; x < intervals; x++) { // Move ships one interval and check for wall collisions. for (int y = 0; y < numShips; y++) { if (ships[y]->alive) { ShipMoveData *shipDatum = &(shipData[y]); if (!shipDatum->stopped) { Ship *oldShip = oldShips[y]; shipDatum->nextShipCircle->setPosition( oldShip->x + (shipDatum->dx * (x + 1)), oldShip->y + (shipDatum->dy * (x + 1))); for (int z = 0; z < numWallLines_; z++) { Line2D* line = wallLines_[z]; Point2D *p1 = 0; Point2D *p2 = 0; if (shipDatum->nextShipCircle->intersects(line, &p1, &p2)) { double thisX = shipDatum->shipCircle->h(); double thisY = shipDatum->shipCircle->k(); bool valid = true; if (p1 != 0) { Line2D vertexSightLine1(thisX, thisY, p1->getX() - (signum(p1->getX() - thisX) * VERTEX_FUDGE), p1->getY() - (signum(p1->getY() - thisY) * VERTEX_FUDGE)); valid = hasVision(&vertexSightLine1); delete p1; } if (p2 != 0) { if (valid) { Line2D vertexSightLine2(thisX, thisY, p2->getX() - (signum(p2->getX() - thisX) * VERTEX_FUDGE), p2->getY() - (signum(p2->getY() - thisY) * VERTEX_FUDGE)); valid = hasVision(&vertexSightLine2); } delete p2; } if (valid) { shipDatum->stopped = shipDatum->wallCollision = true; double heading = ships[y]->heading; double angle1 = line->theta() - M_PI_2; double angleDiff1 = abs(normalRelativeAngle(heading - angle1)); double angle2 = line->theta() + M_PI_2; double angleDiff2 = abs(normalRelativeAngle(heading - angle2)); if (angleDiff1 < shipDatum->minWallImpactDiff) { shipDatum->minWallImpactDiff = angleDiff1; shipDatum->wallImpactAngle = angle1; shipDatum->wallImpactLine = line; } if (angleDiff2 < shipDatum->minWallImpactDiff) { shipDatum->minWallImpactDiff = angleDiff2; shipDatum->wallImpactAngle = angle2; shipDatum->wallImpactLine = line; } } } } } } } // Check for ship-ship collisions. for (int y = 0; y < numShips; y++) { ShipMoveData *shipDatum = &(shipData[y]); if (ships[y]->alive && !shipDatum->stopped) { for (int z = 0; z < numShips; z++) { if (y != z && ships[z]->alive) { ShipMoveData *shipDatum2 = &(shipData[z]); if (shipDatum->nextShipCircle->overlaps(shipDatum2->shipCircle) || (!shipDatum2->stopped && shipDatum->nextShipCircle->overlaps( shipDatum2->nextShipCircle))) { shipDatum->stopped = shipDatum2->stopped = shipDatum->shipCollision = shipDatum2->shipCollision = true; if (shipDatum->shipCollisionData[z] == 0) { shipDatum->shipCollisionData[z] = new ShipCollisionData; } if (shipDatum2->shipCollisionData[y] == 0) { shipDatum2->shipCollisionData[y] = new ShipCollisionData; } } } } } } // Update for next tick and clear old locations. for (int y = 0; y < numShips; y++) { if (ships[y]->alive) { ShipMoveData *shipDatum = &(shipData[y]); if (!shipDatum->stopped) { shipDatum->shipCircle->setPosition( shipDatum->nextShipCircle->h(), shipDatum->nextShipCircle->k()); } } } } // Calculate impact of wall collisions. for (int x = 0; x < numShips; x++) { if (ships[x]->alive) { ShipMoveData *shipDatum = &(shipData[x]); if (shipDatum->wallCollision) { Ship *ship = ships[x]; Ship *oldShip = oldShips[x]; ship->hitWall = true; ship->x = shipDatum->shipCircle->h(); ship->y = shipDatum->shipCircle->k(); if (shipStopped(oldShip, ship)) { shipDatum->xSpeed = shipDatum->dxSpeed; shipDatum->ySpeed = shipDatum->dySpeed; setSpeedAndHeading(oldShip, ship, shipDatum); } double bounceForce = abs(ship->speed * cos(shipDatum->minWallImpactDiff) * (1 + WALL_BOUNCE)); double bounceAngle = shipDatum->wallImpactAngle + M_PI; shipDatum->xSpeed += cos(bounceAngle) * bounceForce; shipDatum->ySpeed += sin(bounceAngle) * bounceForce; setSpeedAndHeading(oldShip, ship, shipDatum); for (int z = 0; z < numEventHandlers_; z++) { eventHandlers_[z]->handleShipHitWall( ship, bounceAngle, bounceForce, gameTime); } } } } // Update x/y/heading/speeds for ships with ship-ship collisions. for (int x = 0; x < numShips; x++) { ShipMoveData *shipDatum = &(shipData[x]); if (ships[x]->alive && shipDatum->shipCollision) { Ship *ship = ships[x]; ship->hitShip = true; ship->x = shipDatum->shipCircle->h(); ship->y = shipDatum->shipCircle->k(); if (shipStopped(oldShips[x], ship)) { shipDatum->xSpeed = shipDatum->dxSpeed; shipDatum->ySpeed = shipDatum->dySpeed; setSpeedAndHeading(oldShips[x], ship, shipDatum); } } } // Calculate momentum to be transferred between all colliding ships. for (int x = 0; x < numShips; x++) { ShipMoveData *shipDatum = &(shipData[x]); Ship *ship = ships[x]; if (ship-> alive && shipDatum->shipCollision) { double totalForce = 0; for (int y = 0; y < numShips; y++) { if (x != y && ships[y]->alive) { ShipCollisionData *collisionData = shipDatum->shipCollisionData[y]; if (collisionData != 0) { collisionData->angle = atan2(ships[y]->y - ship->y, ships[y]->x - ship->x); collisionData->force = cos(ship->heading - collisionData->angle) * ship->speed; totalForce += collisionData->force; } } } if (totalForce > ship->speed) { for (int y = 0; y < numShips; y++) { if (x != y) { ShipCollisionData *collisionData = shipDatum->shipCollisionData[y]; if (collisionData != 0) { collisionData->force *= ship->speed / totalForce; } } } } } } // Apply momentum transfers. for (int x = 0; x < numShips; x++) { ShipMoveData *shipDatum = &(shipData[x]); if (ships[x]->alive && shipDatum->shipCollision) { for (int y = 0; y < numShips; y++) { if (x != y && ships[y]->alive) { ShipMoveData *shipDatum2 = &(shipData[y]); ShipCollisionData *collisionData = shipDatum->shipCollisionData[y]; if (collisionData != 0) { double xForce = cos(collisionData->angle) * collisionData->force; double yForce = sin(collisionData->angle) * collisionData->force; shipDatum->xSpeed -= xForce; shipDatum->ySpeed -= yForce; setSpeedAndHeading(oldShips[x], ships[x], shipDatum); shipDatum2->xSpeed += xForce; shipDatum2->ySpeed += yForce; setSpeedAndHeading(oldShips[y], ships[y], shipDatum2); ShipCollisionData *collisionData2 = shipDatum2->shipCollisionData[x]; for (int z = 0; z < numEventHandlers_; z++) { eventHandlers_[z]->handleShipHitShip(ships[x], ships[y], collisionData->angle, collisionData->force, collisionData2->angle, collisionData2->force, gameTime); } } } } } } // Check for laser-ship collisions, laser-wall collisions, log destroys and // damage, remove dead lasers. bool **laserHits = new bool*[numShips]; for (int x = 0; x < numShips; x++) { laserHits[x] = new bool[numShips]; for (int y = 0; y < numShips; y++) { laserHits[x][y] = false; } } bool *wasAlive = new bool[numShips]; for (int x = 0; x < numShips; x++) { wasAlive[x] = ships[x]->alive; } // For lasers fired this tick, check if they intersect any other ships at // their initial position (0-25 from origin) before moving the first time. checkLaserShipCollisions(ships, shipData, numShips, laserHits, numLasers_, gameTime, true); // Move lasers one whole tick. for (int x = 0; x < numLasers_; x++) { Laser *laser = lasers_[x]; laser->x += laser->dx; laser->y += laser->dy; laserLines_[x]->shift(laser->dx, laser->dy); } checkLaserShipCollisions(ships, shipData, numShips, laserHits, numLasers_, gameTime, false); for (int x = 0; x < numShips; x++) { Ship *ship = ships[x]; if (wasAlive[x] && !ship->alive) { int numDestroyers = 0; for (int y = 0; y < numShips; y++) { if (laserHits[y][x]) { numDestroyers++; } } Ship **destroyers = new Ship*[numDestroyers]; int destroyerIndex = 0; for (int y = 0; y < numShips; y++) { if (laserHits[y][x]) { destroyers[destroyerIndex++] = ships[y]; } } for (int y = 0; y < numShips; y++) { if (laserHits[y][x]) { double destroyScore = 1.0 / numDestroyers; if (ship->teamIndex == ships[y]->teamIndex) { ships[y]->friendlyKills += destroyScore; } else { ships[y]->kills += destroyScore; } } } for (int z = 0; z < numEventHandlers_; z++) { eventHandlers_[z]->handleShipDestroyed(ship, gameTime, destroyers, numDestroyers); } delete destroyers; } } for (int x = 0; x < numLasers_; x++) { Laser *laser = lasers_[x]; Line2D *laserLine = laserLines_[x]; for (int y = 0; y < numWallLines_ && !lasers_[x]->dead; y++) { Line2D *wallLine = wallLines_[y]; if (wallLine->intersects(laserLine)) { lasers_[x]->dead = true; } } if (laser->dead) { if (numLasers_ > 1) { lasers_[x] = lasers_[numLasers_ - 1]; laserLines_[x] = laserLines_[numLasers_ - 1]; } for (int y = 0; y < numEventHandlers_; y++) { eventHandlers_[y]->handleLaserDestroyed(laser, gameTime); } delete laser; delete laserLine; numLasers_--; x--; } } for (int x = 0; x < numShips; x++) { delete laserHits[x]; } delete laserHits; // Move torpedoes and check for collisions. for (int x = 0; x < numShips; x++) { Ship *ship = ships[x]; wasAlive[x] = ship->alive; } bool **torpedoHits = new bool*[numShips]; for (int x = 0; x < numShips; x++) { torpedoHits[x] = new bool[numShips]; for (int y = 0; y < numShips; y++) { torpedoHits[x][y] = false; } } for (int x = 0; x < numTorpedos_; x++) { Torpedo *torpedo = torpedos_[x]; double distanceRemaining = torpedo->distance - torpedo->distanceTraveled; if (distanceRemaining >= TORPEDO_SPEED) { torpedo->x += torpedo->dx; torpedo->y += torpedo->dy; torpedo->distanceTraveled += TORPEDO_SPEED; } else { torpedo->x += cos(torpedo->heading) * distanceRemaining; torpedo->y += sin(torpedo->heading) * distanceRemaining; for (int y = 0; y < numShips; y++) { Ship *ship = ships[y]; if (ship->alive) { double distSq = square(torpedo->x - ship->x) + square(torpedo->y - ship->y); if (distSq < square(TORPEDO_BLAST_RADIUS)) { int firingShipIndex = torpedo->shipIndex; torpedoHits[firingShipIndex][y] = true; ShipMoveData *shipDatum = &(shipData[y]); double blastDistance = sqrt(distSq); double blastFactor = square(1.0 - (blastDistance / TORPEDO_BLAST_RADIUS)); double blastForce = blastFactor * TORPEDO_BLAST_FORCE; double blastDamage = blastFactor * (ship->energyEnabled ? TORPEDO_BLAST_DAMAGE : 0); double blastAngle = atan2(ship->y - torpedo->y, ship->x - torpedo->x); double damageScore = (blastDamage / DEFAULT_ENERGY); if (ship->teamIndex == ships[firingShipIndex]->teamIndex) { ships[firingShipIndex]->friendlyDamage += damageScore; } else { ships[firingShipIndex]->damage += damageScore; } ship->energy -= blastDamage; shipDatum->xSpeed += cos(blastAngle) * blastForce; shipDatum->ySpeed += sin(blastAngle) * blastForce; setSpeedAndHeading(oldShips[y], ship, shipDatum); for (int z = 0; z < numEventHandlers_; z++) { eventHandlers_[z]->handleTorpedoHitShip(ships[torpedo->shipIndex], ship, shipDatum->startXSpeed, shipDatum->startYSpeed, blastAngle, blastForce, blastDamage, gameTime); } if (ship->energy <= 0) { ship->alive = false; } } } } for (int z = 0; z < numEventHandlers_; z++) { eventHandlers_[z]->handleTorpedoExploded(torpedo, gameTime); } if (numTorpedos_ > 1) { torpedos_[x] = torpedos_[numTorpedos_ - 1]; } delete torpedo; numTorpedos_--; x--; } } for (int x = 0; x < numShips; x++) { Ship *ship = ships[x]; if (wasAlive[x] && !ship->alive) { int numDestroyers = 0; for (int y = 0; y < numShips; y++) { if (torpedoHits[y][x]) { numDestroyers++; } } Ship **destroyers = new Ship*[numDestroyers]; int destroyerIndex = 0; for (int y = 0; y < numShips; y++) { if (torpedoHits[y][x]) { destroyers[destroyerIndex++] = ships[y]; } } for (int y = 0; y < numShips; y++) { if (torpedoHits[y][x]) { double destroyScore = 1.0 / numDestroyers; if (ship->teamIndex == ships[y]->teamIndex) { ships[y]->friendlyKills += destroyScore; } else { ships[y]->kills += destroyScore; } } } for (int z = 0; z < numEventHandlers_; z++) { eventHandlers_[z]->handleShipDestroyed(ship, gameTime, destroyers, numDestroyers); } delete destroyers; } } for (int x = 0; x < numShips; x++) { delete torpedoHits[x]; } delete torpedoHits; delete wasAlive; for (int x = 0; x < numShips; x++) { ShipMoveData *shipDatum = &(shipData[x]); if (shipDatum->initialized) { delete shipDatum->shipCircle; delete shipDatum->nextShipCircle; for (int y = 0; y < numShips; y++) { ShipCollisionData *collisionData = shipDatum->shipCollisionData[y]; if (collisionData != 0) { delete collisionData; } } delete shipDatum->shipCollisionData; } } delete shipData; }
// returns the stress vector in 3d stress space // computed from the previous plastic strain and current total strain void MisesMat :: performPlasticityReturn(GaussPoint *gp, const FloatArray &totalStrain) { double kappa, yieldValue, dKappa; FloatArray reducedStress; FloatArray strain, plStrain; MaterialMode mode = gp->giveMaterialMode(); MisesMatStatus *status = static_cast< MisesMatStatus * >( this->giveStatus(gp) ); StressVector fullStress(mode); this->initTempStatus(gp); this->initGpForNewStep(gp); // get the initial plastic strain and initial kappa from the status status->givePlasticStrain(plStrain); kappa = status->giveCumulativePlasticStrain(); // === radial return algorithm === if ( mode == _1dMat ) { LinearElasticMaterial *lmat = this->giveLinearElasticMaterial(); double E = lmat->give('E', gp); /*trial stress*/ fullStress.at(1) = E * ( totalStrain.at(1) - plStrain.at(1) ); double sigmaY = sig0 + H * kappa; double trialS = fullStress.at(1); trialS = fabs(trialS); /*yield function*/ yieldValue = trialS - sigmaY; // === radial return algorithm === if ( yieldValue > 0 ) { dKappa = yieldValue / ( H + E ); kappa += dKappa; fullStress.at(1) = fullStress.at(1) - dKappa *E *signum( fullStress.at(1) ); plStrain.at(1) = plStrain.at(1) + dKappa *signum( fullStress.at(1) ); } } else if ( ( mode == _PlaneStrain ) || ( mode == _3dMat ) ) { // elastic predictor StrainVector elStrain(totalStrain, mode); elStrain.subtract(plStrain); StrainVector elStrainDev(mode); double elStrainVol; elStrain.computeDeviatoricVolumetricSplit(elStrainDev, elStrainVol); StressVector trialStressDev(mode); elStrainDev.applyDeviatoricElasticStiffness(trialStressDev, G); /**************************************************************/ double trialStressVol; trialStressVol = 3 * K * elStrainVol; /**************************************************************/ // store the deviatoric and trial stress (reused by algorithmic stiffness) status->letTrialStressDevBe(trialStressDev); status->setTrialStressVol(trialStressVol); // check the yield condition at the trial state double trialS = trialStressDev.computeStressNorm(); double sigmaY = sig0 + H * kappa; yieldValue = sqrt(3. / 2.) * trialS - sigmaY; if ( yieldValue > 0. ) { // increment of cumulative plastic strain dKappa = yieldValue / ( H + 3. * G ); kappa += dKappa; StrainVector dPlStrain(mode); // the following line is equivalent to multiplication by scaling matrix P trialStressDev.applyDeviatoricElasticCompliance(dPlStrain, 0.5); // increment of plastic strain dPlStrain.times(sqrt(3. / 2.) * dKappa / trialS); plStrain.add(dPlStrain); // scaling of deviatoric trial stress trialStressDev.times(1. - sqrt(6.) * G * dKappa / trialS); } // assemble the stress from the elastically computed volumetric part // and scaled deviatoric part double stressVol = 3. * K * elStrainVol; trialStressDev.computeDeviatoricVolumetricSum(fullStress, stressVol); } // store the effective stress in status status->letTempEffectiveStressBe(fullStress); // store the plastic strain and cumulative plastic strain status->letTempPlasticStrainBe(plStrain); status->setTempCumulativePlasticStrain(kappa); }
Maybe<Collision> World::checkCollision(const AABB& entity) const { /* std::cout << entity.center << "\t" << entity.size << std::endl; */ Vec3i minBlock,maxBlock; for(int i=0;i<3;++i) { int blocks[] = { (int)std::ceil(entity.center[i]+entity.size[i]/2), (int)std::floor(entity.center[i]-entity.size[i]/2) }; if(blocks[0] < blocks[1]) { minBlock[i] = blocks[0]; maxBlock[i] = blocks[1]; } else { minBlock[i] = blocks[1]; maxBlock[i] = blocks[0]; } } /* std::cout << minBlock << "\t" << maxBlock << std::endl; */ std::vector<Vec3f> blockOverlaps; Vec3i regionSize = maxBlock-minBlock+Vec3i{{1,1,1}}; blockOverlaps.reserve(regionSize[0]*regionSize[1]*regionSize[2]); auto calcIndex = [minBlock,regionSize](int x,int y,int z) { return (x-minBlock[0])*(regionSize[1]*regionSize[2]) +(z-minBlock[2])*regionSize[1] +(y-minBlock[1]); }; bool collision = false; for(int x=minBlock[0];x<=maxBlock[0];++x) { for(int z=minBlock[2];z<=maxBlock[2];++z) { for(int y=minBlock[1];y<=maxBlock[1];++y) { auto b = getBlock(x,y,z); if(!b.filled) { continue; } Vec3f loc = {{x+0.5f,y+0.5f,z+0.5f}}; AABB block = { loc,{{1,1,1}} }; auto blockCollision = entity.checkCollision(block,false); Collision c; if(blockCollision.extract(c)) { auto blockOverlap = c.overlap; blockOverlaps.push_back(blockOverlap); collision = true; } else { blockOverlaps.push_back({{0,0,0}}); } } } } for(int x=minBlock[0];x<=maxBlock[0];++x) { for(int z=minBlock[2];z<=maxBlock[2];++z) { for(int y=minBlock[1];y<=maxBlock[1];++y) { Vec3i loc = {{x,y,z}}; auto& overlap = blockOverlaps[calcIndex(x,y,z)]; for(int i=0;i<3;++i) { int dir = signum(overlap[i]); auto otherLoc = loc; otherLoc[i] += dir; if(otherLoc[i] < minBlock[i] || otherLoc[i] > maxBlock[i]) { continue; } auto& otherOverlap = blockOverlaps[calcIndex(otherLoc[0], otherLoc[1], otherLoc[2])]; if(dir != 0 && signum(otherOverlap[i]) == -dir) { otherOverlap[i] = 0; AABB combined; combined.center = loc+Vec3f{{0.5,0.5,0.5}}; combined.center[i] = (dir > 0 ? otherLoc[i] : loc[i]); combined.size = {{1,1,1}}; combined.size[i] = 2; Collision collision; entity.checkCollision(combined).extract(collision); overlap[i] = collision.overlap[i]; } } } } } Vec3f totalOverlap; for(auto overlap:blockOverlaps) { totalOverlap += overlap; } int minAxis = 0; for(int i=1;i<3;++i) { if(std::abs(totalOverlap[i]) < std::abs(totalOverlap[minAxis])) { minAxis = i; } } totalOverlap[(minAxis+1)%3] = totalOverlap[(minAxis+2)%3] = 0; if(collision) { return {{totalOverlap}}; } return {}; }
void Input_maker(int type, Interval &In) { int i, j; real var, norm = 0; const real t[11] = {.1, .13, .15, .23, .25, .40, .44, .65, .76, .78, .81}; const real h[11] = {4, -5, 3, -4, 5, -4.2, 2.1, 4.3, -3.1, 5.1, -7.2}; const real w[11] = {.005, .005, .006, .01, .01, .03, .01, .01, .005, .008, .005}; switch(type) { case 1: /* Chirp */ for(i = In.beg; i <= In.end; i++) { var = (1.0 * i) / In.length; In.origin[i] = 10.0 * (var * var * (1 - var) * (1 - var)) * cos(200 * var * var); norm += In.origin[i] * In.origin[i]; } break; case 2: /* Doppler */ for(i = In.beg; i <= In.end; i++) { var = (1.0 * i) / In.length; In.origin[i] = sin(2.0 * 3.1415926 * (1 + .05) / (.05 + var)); norm += In.origin[i] * In.origin[i]; } break; case 3: /* Polynomial */ for(i = In.beg; i <= In.end; i++) { var = (1.0 * i) / In.length; In.origin[i] = -96.0 * (i) / In.length * (var - 1) * (var - 1) * (var - 1) * (var - .5) * (var - .5); norm += In.origin[i] * In.origin[i]; } break; case 4: /* Blocks */ for(i = In.beg; i <= In.end; i++) { var = (1.0 * i) / In.length; In.origin[i] = 0; for(j = 0; j < 11; j++) { In.origin[i] += (h[j] * 0.5 * (1 + signum(var - t[j]))); } norm += In.origin[i] * In.origin[i]; } break; case 5: /* Bumps */ for(i = In.beg; i <= In.end; i++) { var = (1.0 * i) / In.length; In.origin[i] = 0; for(j = 0; j < 11; j++) { In.origin[i] += (h[j] * (funct((var - t[j]) / w[j]))); } norm += In.origin[i] * In.origin[i]; } break; case 6: /* Heavisine */ for(i = In.beg; i <= In.end; i++) { var = (1.0 * i) / In.length; In.origin[i] = 4 * sin(4 * Pi * var) - signum(var - 0.3) - signum(.72 - var); norm += In.origin[i] * In.origin[i]; } break; case 7: /* Zeros */ for(i = In.beg; i <= In.end; i++) In.origin[i] = 0.0; break; case 8: // constant for(i = In.beg; i <= In.end; i++) { In.origin[i] = 1.0; norm += In.origin[i] * In.origin[i]; } break; case 9: /* tent */ for(i = In.beg; i <= In.end; i++) { var = (1.0 * i) / In.length; In.origin[i] = fabs(var - 0.5); norm += In.origin[i] * In.origin[i]; } break; default: std::cout << "You goofed in Input_maker" << std::endl; exit(1); break; } if(norm > 0) norm = (1.0) / sqrt(norm); for(int i = In.beg; i <= In.end; i++) In.origin[i] *= norm; return; }
bool Point::on(const Point &a, const Point &b) const { Point p = *this; return signum(det(p - a, p - b)) == 0 && signum(dot(p - a, p - b)) < 0; }
void MisesMat :: performPlasticityReturn(GaussPoint *gp, const FloatArray &totalStrain) { MisesMatStatus *status = static_cast< MisesMatStatus * >( this->giveStatus(gp) ); double kappa; FloatArray plStrain; FloatArray fullStress; // get the initial plastic strain and initial kappa from the status plStrain = status->givePlasticStrain(); kappa = status->giveCumulativePlasticStrain(); // === radial return algorithm === if ( totalStrain.giveSize() == 1 ) { LinearElasticMaterial *lmat = this->giveLinearElasticMaterial(); double E = lmat->give('E', gp); /*trial stress*/ fullStress.resize(6); fullStress.at(1) = E * ( totalStrain.at(1) - plStrain.at(1) ); double trialS = fabs(fullStress.at(1)); /*yield function*/ double yieldValue = trialS - (sig0 + H * kappa); // === radial return algorithm === if ( yieldValue > 0 ) { double dKappa = yieldValue / ( H + E ); kappa += dKappa; plStrain.at(1) += dKappa * signum( fullStress.at(1) ); plStrain.at(2) -= 0.5 * dKappa * signum( fullStress.at(1) ); plStrain.at(3) -= 0.5 * dKappa * signum( fullStress.at(1) ); fullStress.at(1) -= dKappa * E * signum( fullStress.at(1) ); } } else { // elastic predictor FloatArray elStrain = totalStrain; elStrain.subtract(plStrain); FloatArray elStrainDev; double elStrainVol; elStrainVol = computeDeviatoricVolumetricSplit(elStrainDev, elStrain); FloatArray trialStressDev; applyDeviatoricElasticStiffness(trialStressDev, elStrainDev, G); /**************************************************************/ double trialStressVol = 3 * K * elStrainVol; /**************************************************************/ // store the deviatoric and trial stress (reused by algorithmic stiffness) status->letTrialStressDevBe(trialStressDev); status->setTrialStressVol(trialStressVol); // check the yield condition at the trial state double trialS = computeStressNorm(trialStressDev); double yieldValue = sqrt(3./2.) * trialS - (sig0 + H * kappa); if ( yieldValue > 0. ) { // increment of cumulative plastic strain double dKappa = yieldValue / ( H + 3. * G ); kappa += dKappa; FloatArray dPlStrain; // the following line is equivalent to multiplication by scaling matrix P applyDeviatoricElasticCompliance(dPlStrain, trialStressDev, 0.5); // increment of plastic strain plStrain.add(sqrt(3. / 2.) * dKappa / trialS, dPlStrain); // scaling of deviatoric trial stress trialStressDev.times(1. - sqrt(6.) * G * dKappa / trialS); } // assemble the stress from the elastically computed volumetric part // and scaled deviatoric part computeDeviatoricVolumetricSum(fullStress, trialStressDev, trialStressVol); } // store the effective stress in status status->letTempEffectiveStressBe(fullStress); // store the plastic strain and cumulative plastic strain status->letTempPlasticStrainBe(plStrain); status->setTempCumulativePlasticStrain(kappa); }
template <typename T> inline constexpr int signum(T x) { return signum(x, std::is_signed<T>()); }
int do_test (void) { enum { max_align = 64, max_string_length = 33 }; size_t blob_size = max_align + max_string_length + 1; char *left = memalign (max_align, blob_size); char *right = memalign (max_align, blob_size); if (left == NULL || right == NULL) { printf ("error: out of memory\n"); return 1; } const struct { const char *name; int (*implementation) (const char *, const char *); } functions[] = { { "strcmp", strcmp }, { "strcasecmp", strcasecmp }, { "strncmp (without NUL)", strncmp_no_terminator}, { "strncasecmp (without NUL)", strncasecmp_no_terminator}, { "strncmp (with NUL)", strncmp_terminator}, { "strncasecmp (with NUL)", strncasecmp_terminator}, { "strncmp (length 64)", strncmp_64}, { "strncasecmp (length 64)", strncasecmp_64}, { "strncmp (length SIZE_MAX)", strncmp_max}, { "strncasecmp (length SIZE_MAX)", strncasecmp_max}, { NULL, NULL } }; const char *const strings[] = { "", "0", "01", "01234567", "0123456789abcde", "0123456789abcdef", "0123456789abcdefg", "1", "10", "123456789abcdef", "123456789abcdefg", "23456789abcdef", "23456789abcdefg", "abcdefghijklmnopqrstuvwxyzABCDEF", NULL }; const unsigned char pads[] = { 0, 1, 32, 64, 128, '0', '1', 'e', 'f', 'g', 127, 192, 255 }; bool errors = false; for (int left_idx = 0; strings[left_idx] != NULL; ++left_idx) for (int left_align = 0; left_align < max_align; ++left_align) for (unsigned pad_left = 0; pad_left < sizeof (pads); ++pad_left) { memset (left, pads[pad_left], blob_size); strcpy (left + left_align, strings[left_idx]); for (int right_idx = 0; strings[right_idx] != NULL; ++right_idx) for (unsigned pad_right = 0; pad_right < sizeof (pads); ++pad_right) for (int right_align = 0; right_align < max_align; ++right_align) { memset (right, pads[pad_right], blob_size); strcpy (right + right_align, strings[right_idx]); for (int func = 0; functions[func].name != NULL; ++func) { int expected = left_idx - right_idx; int actual = functions[func].implementation (left + left_align, right + right_align); if (signum (actual) != signum (expected)) { printf ("error: mismatch for %s: %d\n" " left: \"%s\"\n" " right: \"%s\"\n" " pad_left = %u, pad_right = %u,\n" " left_align = %d, right_align = %d\n", functions[func].name, actual, strings[left_idx], strings[right_idx], pad_left, pad_right, left_align, right_align); errors = true; } } } } free (right); free (left); return errors; }