void ConjugateGradient( float **A, float *b, float *x, int N, int iterations) { // vectors float r[N]; float w[N]; float z[N]; // scalars float alpha; float beta; float temp[N]; // initialization of residual vector: r matrixVectorProduct( A, x, temp, N); vectorDifference( b, temp, r, N); // w vectorScale( r, -1, w, N); // z matrixVectorProduct( A, w, z, N); // alpha alpha = dotProduct( r, w, N) / dotProduct( w, z, N); // beta beta = 0.; // x vectorScale( w, alpha, temp, N); vectorSum( x, temp, x, N); for( int i=0; i<iterations; i++){ vectorScale( z, alpha, temp, N); vectorDifference( r, temp, r, N); if( sqrt( dotProduct( r, r, N)) < 1e-10) return; // B = (r'*z)/(w'*z); beta = dotProduct( r, z, N) / dotProduct( w, z, N); // w = -r + B*w; vectorScale( w, beta, w, N); vectorDifference( w, r, w, N); // z = A*w; matrixVectorProduct( A, w, z, N); // a = (r'*w)/(w'*z); alpha = dotProduct( r, w, N) / dotProduct( w, z, N); // x = x + a*w; vectorScale( w, alpha, temp, N); vectorSum( x, temp, x, N); } }
void ConjugateGradient3( float **A, float *b, float *x, int N, int iterations) { float r[N]; float r2[N]; float p[N]; float q[N]; //float beta[N]; //float alpha[N]; float beta; float alpha; float temp[N]; // initialization of residual vector: r_0 matrixVectorProduct( A, x, temp, N); vectorDifference( b, temp, r, N); // initialization of p_0 vectorCopy( r, p, N); for( int i=0; i<iterations; i++){ // q_k matrixVectorProduct( A, p, q, N); alpha = dotProduct( r, r, N); if(i>0){ beta = alpha / dotProduct( r2, r2, N); vectorScale( p, beta, p, N); vectorSum( r, p, p, N); } alpha /= dotProduct( p, q, N); // next x vectorScale( p, alpha, temp, N); vectorSum( x, temp, x, N); // old r vectorCopy( r, r2, N); // next r vectorScale( q, -alpha, temp, N); vectorSum( r, temp, r, N); //float *pointer ; } }
void test_eigen2_sum() { for(int i = 0; i < g_repeat; i++) { CALL_SUBTEST_1( matrixSum(Matrix<float, 1, 1>()) ); CALL_SUBTEST_2( matrixSum(Matrix2f()) ); CALL_SUBTEST_3( matrixSum(Matrix4d()) ); CALL_SUBTEST_4( matrixSum(MatrixXcf(3, 3)) ); CALL_SUBTEST_5( matrixSum(MatrixXf(8, 12)) ); CALL_SUBTEST_6( matrixSum(MatrixXi(8, 12)) ); } for(int i = 0; i < g_repeat; i++) { CALL_SUBTEST_5( vectorSum(VectorXf(5)) ); CALL_SUBTEST_7( vectorSum(VectorXd(10)) ); CALL_SUBTEST_5( vectorSum(VectorXf(33)) ); } }
vector<float> projectVectorOnPlane (vector<float> vec,vector<float> axis1,vector<float> axis2) { float projAxis1; float projAxis2; vector <float> axis1Norm ; vector <float> axis2Norm ; vector <float> projAxis1Vec ; vector <float> projAxis2Vec ; vector <float> projectedVector ; projAxis1 = projVector(vec,axis1); projAxis2 = projVector(vec,axis2); axis1Norm = normVector(axis1); axis2Norm = normVector(axis2); projAxis1Vec =scalarVector(axis1Norm,projAxis1); projAxis2Vec =scalarVector(axis2Norm,projAxis2); projectedVector = vectorSum(projAxis1Vec,projAxis2Vec); return projectedVector; }
Complex Block::trace(cflag tp)const{ try{ checkUni10TypeError(tp); if(!(Rnum == Cnum)){ std::ostringstream err; err<<"Cannot perform trace on a non-square matrix."; throw std::runtime_error(exception_msg(err.str())); } if(diag) return vectorSum(cm_elem, elemNum(), 1, ongpu); else return vectorSum(cm_elem, Cnum, Cnum + 1, ongpu); }catch(const std::exception& e){ propogate_exception(e, "In function Matrix::trace(uni10::cflag ):"); return 0; } }
int64 problem72(int64 n) { if (n < 1) { throw string("Denominator should be able to be positive"); } vector<int64> phi; totientValues(n, phi); return vectorSum(phi) - 1; // Minus 1 from phi(1) which should not be included }
Complex Block::sum(cflag tp)const{ try{ checkUni10TypeError(tp); return vectorSum(cm_elem, elemNum(), 1, ongpu); } catch(const std::exception& e){ propogate_exception(e, "In function Matrix::sum(uni10::cflag ):"); } return 0; }
Real Block::sum(rflag tp)const{ try{ throwTypeError(tp); return vectorSum(m_elem, elemNum(), 1, ongpu); } catch(const std::exception& e){ propogate_exception(e, "In function Matrix::sum(uni10::rflag ):"); } return 0; }
static pamd_point textPosFromFontPos(pamd_point const fontPos, pamd_point const textBoxOrigin, pamd_point const center, pamd_point const glyphOrigin, unsigned int const height, long const rotcos, long const rotsin) { /*---------------------------------------------------------------------------- 'fontPos' is a position within a glyph as told by the font definition. It is relative to the center of the glyph, in units of font tuples (1/21 of a glyph cell). We return the position on the canvas of that point. That takes into account where in the text box we are, where the text box is on the canvas, the size of the characters, and the rotation of the text box. -----------------------------------------------------------------------------*/ pamd_point const ptl = vectorSum(center, fontPos); /* Position relative to the top left of the standard glyph cell */ pamd_point const pl = vectorSum(glyphOrigin, ptl); /* Position relative to the top left of the whole text box, assuming the text box is horizontal and has font scale. */ pamd_point const ps = makePoint((pl.x * (int)height) / Scalef, (pl.y * (int)height) / Scalef); /* Same as above, but with the text box its actual size */ pamd_point const retval = makePoint(textBoxOrigin.x + (ps.x * rotcos - (ps.y-(int)height) * rotsin) / 65536, textBoxOrigin.y + (ps.x * rotsin + (ps.y-(int)height) * rotcos) / 65536); pamd_validatePoint(retval); return retval; }
void boatPersonFree(boat b) /*Joga as pessoas de volta no oceano*/ { int i, errorCode; listLink aux = b->extra->personList; double angDif = 2 * PI / b->extra->peopleHeld; for (i = 0; i < b->extra->peopleHeld; i++) { if (aux == NULL) genError ("Falha de sincronia entre personList e peopleHeld! Contate um programador."); aux->person->pos = vectorSum(b->pos, vectorPolarToCartesian(b->radius + aux->person->radius, i * angDif)); aux->person->vel = vectorAngleSet(aux->person->vel, angDif); if ((errorCode = objectTableAddObject(aux->person))) { if (errorCode == ERROR_OBJECT_LIMIT_EXCEEDED) genWarning ("Nao foi possivel fazer a pessoa cair do bote!\n"); if (errorCode == ERROR_OBJECT_IS_COLLIDING) { do { aux->person->pos = vectorSum(aux->person->pos, vectorMulDouble(vectorSub (aux->person->pos, b->pos), 1.1)); /*Se ele tentar colocar a pessoa num lugar ja ocupado, ele joga ela pra mais longe ate estar num lugar disponivel*/ } while (objectTableAddObject(aux->person) == ERROR_OBJECT_IS_COLLIDING); } } aux = aux->next; } for (aux = b->extra->personList; aux != NULL; aux = b->extra->personList) { b->extra->personList = b->extra->personList->next; free(aux); b->extra->peopleHeld--; } }
virtual int selectNextArm() { double n = vectorSum(Ni); std::vector<double> indices = std::vector<double>(K, 0.0); for(uint k=0; k<K; ++k) { if(Ni[k]==0) { return k; } indices[k] = (Gi[k]/Ni[k]) + sqrt( std::max<double>( log(n/(K*Ni[k])) , 0.0) / (double)Ni[k] ); } int targetArm = vectorMaxIndex(indices); return targetArm; }
void renderMagneticField(const RenderContext* context) { size_t i, count; pthread_mutex_lock(&_fieldPointsMutex); for (i = 0, count = arrayGetLength(_fieldPoints); i < count; ++i) { VectorFieldPoint* point = (VectorFieldPoint*) arrayGetAt(_fieldPoints, i); drawVector(point->position, point->direction, colorWhite, colorRed); } pthread_mutex_unlock(&_fieldPointsMutex); for (i = 0, count = arrayGetLength(_conductors); i < count; ++i) { Conductor* conductor = (Conductor*) arrayGetAt(_conductors, i); renderParallelepiped(conductor->position, vectorSum(conductor->position, conductor->l), colorBlue); } }
QVector<QPoint> ImageProcessor::findOcculsionSlower(QImage input) { QVector<QPoint> returnMe; int radius = (int) (.1 * input.height()); //qDebug()<<"radius: " <<radius; //left side int bestLeftY=0; int bestLeftYval=INT_MAX; for(int currentY=radius;currentY<input.height()-radius;currentY++) { int sum =0; foreach(int x,ImageProcessor::regionVals(0,currentY,radius,input)) { sum+=x; } if(sum < bestLeftYval) { bestLeftY = currentY; bestLeftYval = sum; } } QPoint currentPoint(0,bestLeftY); returnMe.append(currentPoint); for(int lookX =0;lookX<input.width();lookX++) { qreal bestAngle=0; qreal bestAngleValue=1024; for(int angle=-89;angle<90;angle++) { qreal angleValue = vectorSum(input,currentPoint,angle); if(angleValue < bestAngleValue) { bestAngle = angle; bestAngleValue = angleValue; } } qDebug()<<"Best angle was: " << bestAngle << " with "<< bestAngleValue; if(bestAngle > 15) { QPoint nextPoint(currentPoint.x() +1, currentPoint.y() +1); currentPoint = nextPoint; } else if(bestAngle < -15) { QPoint nextPoint(currentPoint.x() +1, currentPoint.y() - 1); currentPoint = nextPoint; } else { QPoint nextPoint(currentPoint.x() +1, currentPoint.y()); currentPoint = nextPoint; } returnMe.append(currentPoint); } return returnMe; }
static inline void drawVector(Vector position, Vector vector, Color lineColor, Color endColor) { if (vectorGetLengthSq(vector) < 0.001) { return; } Vector sum = vectorSum(position, vector); glColor3f(lineColor.r, lineColor.g, lineColor.b); glBegin(GL_LINES); glVertex3d(position.x, position.y, position.z); glVertex3d(sum.x, sum.y, sum.z); glEnd(); static double endSize = 0.05; renderCube(sum, vectorCreate(endSize, endSize, endSize), endColor); }
virtual int selectNextArm(){ double n = vectorSum(Ni); std::vector<double> indices = std::vector<double>(K, 0.0); for(uint k=0;k<K;++k){ if(Ni[k]==0){ return k; } double variance = getVariance(k); //UCB-V index indices[k] = (Gi[k]/Ni[k]) + sqrt( (2 * zeta * variance * log(n)) / (double)Ni[k] ) + 3 * amp * zeta * log(n)/(double)Ni[k]; } int targetArm = vectorMaxIndex(indices); return targetArm; }
std::vector<T> repeatVector(const std::vector<T>& vec, const std::vector<uint64_t>& repeatNumber) { std::vector<T> ans; if (repeatNumber.size() == 1) { ans.reserve(repeatNumber[0] * vec.size()); for (uint64_t i = 0; i < repeatNumber[0]; ++i) { addOtherVec(ans, vec); } } else if (repeatNumber.size() == vec.size()) { uint32_t pos = 0; auto sum = vectorSum(repeatNumber); ans.reserve(sum); for (const auto& iter : vec) { addOtherVec(ans, std::vector<T>(repeatNumber[pos], iter)); pos++; } } else { std::cout << "Repeat number vector needs to be either same size of the " "vector to be repeated or needs to be one number" << "\n"; } return ans; }
int main(int argc, char** argv) { if(argc != 2) { printf("You should use the following format for running this program: %s <Number of Iterations>\n", argv[0]); exit(1); } int N = atoi(argv[1]); int rng = 42; srand(rng); array_number_t vec1 = vector_fill(DIM, 0.0); array_number_t vec2 = vector_fill(DIM, 0.0); array_number_t vec3 = vector_fill(DIM, 0.0); for(int i=0; i<DIM; i++) { vec1->arr[i] = dist(rng); vec2->arr[i] = dist(rng); vec3->arr[i] = dist(rng); } #ifdef HOIST storage_t s = storage_alloc(VECTOR_ALL_BYTES(DIM)); #endif timer_t t = tic(); double total = 0; for (int count = 0; count < N; ++count) { vec1->arr[0] += 1.0 / (2.0 + vec1->arr[0]); vec2->arr[10] += 1.0 / (2.0 + vec2->arr[10]); #ifdef DPS #ifndef HOIST storage_t s = storage_alloc(VECTOR_ALL_BYTES(DIM)); #endif #endif #ifdef ADD3 #ifdef DPS total += vectorSum(TOP_LEVEL_linalg_vectorAdd3_dps(s, vec1, vec2, vec3, DIM, DIM, DIM)); #else total += vectorSum(TOP_LEVEL_linalg_vectorAdd3(vec1, vec2, vec3)); #endif #elif DOT #ifdef DPS total += TOP_LEVEL_linalg_dot_prod_dps(s, vec1, vec2, DIM, DIM); #else total += TOP_LEVEL_linalg_dot_prod(vec1, vec2); #endif #elif CROSS #ifdef DPS total += vectorSum(TOP_LEVEL_linalg_cross_dps(s, vec1, vec2, DIM, DIM)); #else total += vectorSum(TOP_LEVEL_linalg_cross(vec1, vec2)); #endif #endif #ifdef DPS #ifndef HOIST storage_free(s, VECTOR_ALL_BYTES(DIM)); #endif #endif } float elapsed = toc2(t); printf("total =%f, time per call = %f ms\n", total, elapsed / (double)(N)); return 0; }
T getSumOfVecStr(const VecStr & vec) { return vectorSum(njh::lexical_cast_con<VecStr, std::vector<T>>(vec)); }
void boatUpdate(boat b, int keepDir, double timedif) { double anchorRatio; if (b->extra->timeStuckLeft > 0) { /*Se o barco esta encalhado */ b->extra->timeStuckLeft -= timedif; b->tex.color = b->extra->color / 2; /* Torna o bote mais escuro - note que os valores para R e G sempre sao pares para lidar com isso */ if (b->extra->timeStuckLeft <= 0) { if (b->extra->life >= 0) { b->extra->timeStuckLeft = 0; b->pos = b->extra->respawnPoint; b->vel = vectorCreate(0, 0); b->acc = vectorCreate(0, 0); b->dir = PI/2; b->tex.color = b->extra->color; /* Retornando a cor original, ja que o bote muda de cor quando encalhado */ } else b->toBeRemoved = 1; } return; } /*Verificando se ja deve ganahr uma vida nova*/ if (b->extra->points >= b->extra->extraLivesCount * b->extra->extraLifeScore) { b->extra->life++; b->extra->extraLivesCount++; } /*Le teclado*/ boatReadKeyboard(b); if (b->extra->isAccel && !b->extra->isAnchored) { b->acc.x = -b->extra->accel * cos(b->dir) * b->extra->isAccel; b->acc.y = -b->extra->accel * sin(b->dir) * b->extra->isAccel; } else b->acc = vectorCreate(0, 0); if (b->extra->isAnchored) anchorRatio = b->extra->anchorMultiplier; else anchorRatio = 1; b->acc.x = b->acc.x - b->vel.x * b->extra->friction * anchorRatio; b->acc.y = b->acc.y - b->vel.y * b->extra->friction * anchorRatio; b->vel = vectorSum(b->vel, vectorMulDouble(b->acc, timedif)); b->pos = vectorSum(b->pos, vectorMulDouble(b->vel, timedif)); if (!b->extra->isAnchored) b->dir += b->extra->isTurning * b->extra->turnRate * timedif; objectQuadUpdate(b); /*Resgate de pessoas*/ if (b->extra->isAnchored && distanceBetweenPoints(b->pos, shipPos) <= b->extra->unloadDistance) { if (b->extra->personList != NULL) { if (b->extra->unloadTimeLeft <= 0.0) { debugDouble("b->extra->unloadtimeleft", b->extra->unloadTimeLeft); rescuePerson(b); b->extra->unloadTimeLeft = b->extra->unloadTime; } else b->extra->unloadTimeLeft = b->extra->unloadTimeLeft - timedif; } } else b->extra->unloadTimeLeft = b->extra->unloadTime; /*Fala o que precisa ser mostrado no display*/ statusReport(b->extra->player, b->extra->name, b->extra->life, b->extra->points, b->extra->peopleHeld); }
void pamd_circle(tuple ** const tuples, unsigned int const cols, unsigned int const rows, unsigned int const depth, sample const maxval, pamd_point const center, unsigned int const radius, pamd_drawproc drawProc, const void * const clientData) { /*---------------------------------------------------------------------------- If lineclip mode is on, draw only points within the image. If lineclip is off, "draw" all points (by designated drawproc). Note that the drawproc can't actually draw a point outside the image, but it might maintain state that is affected by imaginary points outside the image. Initial point is 3 o'clock. -----------------------------------------------------------------------------*/ if (radius >= DDA_SCALE) pm_error("Error drawing circle. Radius %d is too large.", radius); pamd_validateCoord(center.x + radius); pamd_validateCoord(center.y + radius); pamd_validateCoord(center.x - radius); pamd_validateCoord(center.y - radius); if (radius > 0) { long const e = DDA_SCALE / radius; pamd_point const p0 = makePoint(radius, 0); /* 3 o'clock */ /* The starting point around the circle, assuming (0, 0) center */ pamd_point p; /* Current drawing position in the circle, assuming (0,0) center */ bool onFirstPoint; bool prevPointExists; pamd_point prevPoint; /* Previous drawing position, assuming (0, 0) center*/ long sx, sy; /* 'p', scaled by DDA_SCALE */ p = p0; sx = p.x * DDA_SCALE + DDA_SCALE / 2; sy = p.y * DDA_SCALE + DDA_SCALE / 2; onFirstPoint = TRUE; prevPointExists = FALSE; while (onFirstPoint || !pointsEqual(p, p0)) { if (prevPointExists && pointsEqual(p, prevPoint)) { /* We're on the same point we were on last time (we moved less than a point's worth). Just keep moving. */ } else { pamd_point const imagePoint = vectorSum(center,p); if (!lineclip || pointIsWithinBounds(imagePoint, cols, rows)) drawPoint(drawProc, clientData, tuples, cols, rows, depth, maxval, imagePoint); prevPoint = p; prevPointExists = TRUE; } if (!pointsEqual(p, p0)) onFirstPoint = FALSE; sx += e * sy / DDA_SCALE; sy -= e * sx / DDA_SCALE; p = makePoint(sx / DDA_SCALE, sy / DDA_SCALE); } } }
Vector calculateLorenzForce(double q, Vector E, Vector v, Vector B) { return vectorMultiply(vectorSum(E, vectorCrossProduct(v, B)), q); }
void updateMagneticField(const RenderContext* context) { static const Vector minCellPosRel = { -48, -48, -48 }; static const Vector maxCellPosRel = { 48, 48, 48 }; static const int cellStep = 8; Vector minCellPos = vectorSum(context->camera.position, minCellPosRel); Vector maxCellPos = vectorSum(context->camera.position, maxCellPosRel); size_t i, count; // remove points which is too far from camera for (i = 0, count = arrayGetLength(_fieldPoints); i < count; ++i) { pthread_mutex_lock(&_fieldPointsMutex); VectorFieldPoint* point = (VectorFieldPoint*) arrayGetAt(_fieldPoints, i); if (point->position.x < minCellPos.x + minCellPosRel.x || point->position.x > maxCellPos.x + maxCellPosRel.x || point->position.y < minCellPos.y + minCellPosRel.y || point->position.y > maxCellPos.y + maxCellPosRel.y || point->position.z < minCellPos.z + minCellPosRel.z || point->position.z > maxCellPos.z + maxCellPosRel.z) { arrayDestroy(_fieldPoints, i); --i; --count; } pthread_mutex_unlock(&_fieldPointsMutex); } // compute points int x, y, z; for (x = (int) (minCellPos.x / cellStep) * cellStep; x <= maxCellPos.x; x += cellStep) { for (y = (int) (minCellPos.y / cellStep) * cellStep; y <= maxCellPos.y; y += cellStep) { for (z = (int) (minCellPos.z / cellStep) * cellStep; z <= maxCellPos.z; z += cellStep) { const Vector position = { x, y, z }; // try to find int pointExists = 0; for (i = 0, count = arrayGetLength(_fieldPoints); i < count; ++i) { pthread_mutex_lock(&_fieldPointsMutex); VectorFieldPoint* point = (VectorFieldPoint*) arrayGetAt(_fieldPoints, i); if (point->position.x >= x && point->position.x <= x + cellStep && point->position.y >= y && point->position.y <= y + cellStep && point->position.z >= z && point->position.z <= z + cellStep) { pointExists = 1; pthread_mutex_unlock(&_fieldPointsMutex); break; } pthread_mutex_unlock(&_fieldPointsMutex); } if (pointExists) { continue; } // compute if not exist VectorFieldPoint* result = (VectorFieldPoint*) malloc(sizeof(VectorFieldPoint)); result->position = position; result->direction = vectorZero; for (i = 0, count = arrayGetLength(_conductors); i < count; ++i) { Conductor* conductor = (Conductor*) arrayGetAt(_conductors, i); result->direction = vectorSum( result->direction, calculateMagneticFieldPoint(conductor->I, conductor->permeability, conductor->l, vectorSubstract(position, conductor->position)) ); } pthread_mutex_lock(&_fieldPointsMutex); arrayAppend(_fieldPoints, result); pthread_mutex_unlock(&_fieldPointsMutex); } } } }
int main(int argc,char** argv) { ///////////////////////////// //Changable settings for the program bool enableOpenMP = 0; bool enableMPI = 0; int vectorSize = 256; ///////////////////////////// int k=atoi(argv[1]); //for(int k=3;k<=14;k++){ vectorSize = 2^k; if(enableOpenMP) omp_set_num_threads(4); if(enableMPI) { int rank , mpiSize; MPI_Init (&argc , &argv); MPI_Comm_size(MPI_COMM_WORLD , &mpiSize); MPI_Comm_rank(MPI_COMM_WORLD , &rank); struct Vector* globalVector = newVector(); struct Vector* localVector = newVector(); double globalSum =0.0, localSum =0.0; double endTime = 0.0, startTime = 0.0; int *localSize, *displ; splitVector(vectorSize,mpiSize,&localSize,&displ); allocVector(localSize[rank], localVector); if(rank ==0) { startTime = MPI_Wtime(); initVector(vectorSize,globalVector,enableOpenMP); } MPI_Scatterv(globalVector->data,localSize,displ,MPI_DOUBLE,localVector->data,localSize[rank],MPI_DOUBLE, 0,MPI_COMM_WORLD); localSum = vectorSum(localVector,enableOpenMP); MPI_Reduce(&localSum,&globalSum,1,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD); if(rank==0) { double diff = fabs((PI*PI)/6-globalSum); endTime = MPI_Wtime(); printf("Difference MPI |S-Sn| = %f \n",diff); printf("Walltime MPI = %f \n",endTime - startTime); freeVector(globalVector); } if(rank!=0) free(globalVector); freeVector(localVector); free(localSize); free(displ); MPI_Finalize(); }else { struct timeval* startTime = malloc(sizeof(struct timeval)); struct timeval* endTime = malloc(sizeof(struct timeval)); struct Vector* globalVector = newVector(); gettimeofday(startTime,0); initVector(vectorSize,globalVector,enableOpenMP); double sumSn = vectorSum(globalVector, enableOpenMP); double diff = fabs((PI*PI)/6-sumSn); gettimeofday(endTime,0); printf("Difference serial |S-Sn| = %f \n",diff); printf("Walltime serial = %f\n",(endTime->tv_sec+endTime->tv_usec)/1.0e6 -(startTime->tv_sec+startTime->tv_usec)/1.0e6); freeVector(globalVector); free(startTime); free(endTime); } //} return 0; }
void boatCollide(boat b, object o, double timediff) { double objectSide; /*Variavel que guarda o tamanho de um dos lados do outro objeto, caso seja o Asimov ou um coral */ switch (o->type) { case TYPE_BOAT: if (vectorLength(o->extra->prevVel) != 0) { b->vel = o->extra->prevVel; o->extra->prevVel = vectorCreate(0, 0); } else { b->extra->prevVel = b->vel; b->vel = o->vel; } b->pos = vectorSum(vectorLengthSet (vectorSub(b->pos, o->pos), b->radius + o->radius + 1), o->pos); break; case TYPE_CORAL: objectSide = o->radius * SQRT_2 / 2; /*Note que a colisao so existe caso bata num dos lados do coral, nao se simplesmente estiver no circulo de colisao*/ if (((abs(b->pos.x - o->pos.x) <= objectSide && abs(b->pos.y - o->pos.y) <= (objectSide + b->radius)) || (abs(b->pos.y - o->pos.y) <= objectSide && abs(b->pos.x - o->pos.x) <= (objectSide + b->radius)) || ((abs(b->pos.x - o->pos.x) >= objectSide && abs(b->pos.y - o->pos.y) >= objectSide))) && b->extra->timeStuckLeft == 0) boatCrash(b); break; case TYPE_SHIP: objectSide = o->radius / SQRT_5; /*Note que o retangulo e um retangulo inscrito ao circulo de colisao */ /*Vide comentarios para colisao com coral */ if (abs(b->pos.x - o->pos.x) <= 2 * objectSide && abs(b->pos.y - o->pos.y) <= (objectSide + b->radius)) { b->vel.y *= -1; (b->pos.y >= o->pos.y) ? (b->pos.y = o->pos.y + objectSide + b->radius + 1) : (b->pos.y = o->pos.y - objectSide - b->radius - 1); } else if (abs(b->pos.y - o->pos.y) <= objectSide && abs(b->pos.x - o->pos.x) <= (2 * objectSide + b->radius)) { b->vel.x *= -1; (b->pos.x >= o->pos.x) ? (b->pos.x = o->pos.x + objectSide * 2 + b->radius + 1) : (b->pos.x = o->pos.x - objectSide * 2 - b->radius - 1); } else if (abs(b->pos.x - o->pos.x) >= 2 * objectSide && abs(b->pos.y - o->pos.y) >= objectSide) { b->vel.x *= -1; b->vel.y *= -1; b->pos = vectorSum(vectorLengthSet (vectorSub(b->pos, o->pos), b->radius + o->radius + 1), o->pos); } break; case TYPE_PERSON: if (!boatFullOrCrashed(b)) personBoatCollision(b, o); break; default: genWarning("Colisao de barco com tipo desconhecido!\n"); } }