//------------------------------------------------------------------------------ void Missile::frameMove(float dt) { Projectile::frameMove(dt); updateTarget(dt); Vector cur_dir = getGlobalLinearVel(); cur_dir.normalize(); Vector target_dir = target_ - getPosition(); float l = target_dir.length(); if (equalsZero(l)) return; target_dir /= l; float alpha = acosf(vecDot(&cur_dir, &target_dir)); if (alpha > agility_*dt ) { Matrix m; Vector axis; vecCross(&axis, &target_dir, &cur_dir); if (!equalsZero(axis.length())) { m.loadRotationVector(agility_*dt, axis); target_dir = m.transformVector(cur_dir); } else target_dir = cur_dir; } setGlobalLinearVel(target_dir*speed_); }
// sets q equal to the polynomial s.t. a = bq + r void eucDiv(float a[], float b[], float q[]) { if (equalsZero(a) == 1) { printf("You are calling eucDiv with a equal to the zero vector\n"); return; } if (equalsZero(b) == 1) { printf("You are calling a division by 0\n"); return; } // printf("a in eucdiv call: "); // printPoly(a); // printf("b in eucdiv call: "); // printPoly(b); int i; // printf("\narg1 of eucdiv: "); // printPoly(a); // printf("\narg2 of eucdiv: "); // printPoly(b); int degA = degree(a); int degB = degree(b); //printf("\ndeg arg1: %d, deg arg2: %d\n", degA, degB); int d = degA - degB; if (d < 0) { printf("This is a nonsensical call of eucDiv\n"); return; } float tempQ; setZero(q); // creates tempA as a clone of a float tempA[maxDegree+1]; setEquals(tempA, a); float tempB[maxDegree+1]; setEquals(tempB, b); // float tempPoly[maxDegree+1]; // algorithm for euclidean division for (i = d; i >= 0; --i) { tempQ = tempA[degA + i - d] / tempB[degB]; q[i] = tempQ; if (tempQ != 0) { scale(tempB, tempQ); polyTimesXn(tempB, i); subtract(tempA, tempB); polyTimesXn(tempB, -i); scale(tempB, 1.0/tempQ); } } }
int dividesRowAndCol(float A[][M][maxDegree+1], int tempN, int tempM) { int m, n; int ret = 1; if (equalsZero(A[tempN][tempM]) == 1) { printf("You have called this with A[i][j] = the zero vector\n"); return 0; } if (tempN == -1 || tempM == -1) { printf("You have called this with tempN = -1 or tempM = -1\n"); return 0; } for(n = 0; n < N; ++n) { if (n != tempN) { if (dividesPoly(A[n][tempM], A[tempN][tempM]) == 0) { ret = 0; } } } for(m = 0; m < M; ++m) { if (m != tempM) { if (dividesPoly(A[tempN][m], A[tempN][tempM]) == 0) { ret = 0; } } } return ret; }
void findLeastEntry(float A[][M][maxDegree+1], int finishedRows[], int finishedColumns[], int *tempN, int *tempM, int *finished) { int m, n; int boole = 0; *finished = 0; int tempMin = -1; // stores a minimum degree // find one element that does not equal zero for(n = 0; n < N; ++n) { for(m = 0; m < M; ++m) { if(contains(finishedRows, N, n) == 0 || contains(finishedColumns, M, m) == 0) { if(equalsZero(A[n][m]) == 0) { *tempN = n; *tempM = m; tempMin = degree(A[n][m]); boole = 1; break; } if (boole == 1) { break; } } } } if (tempMin == -1) { printf("There is no valid least entry\n"); *finished = 1; return; } for(n = 0; n < N; ++n) { for (m = 0; m < M; ++m) { if(contains(finishedRows, N, n) == 0 || contains(finishedColumns, M, m) == 0) { if (equalsZero(A[n][m]) == 0) { if(degree(A[n][m]) < tempMin) { *tempN = n; *tempM = m; tempMin = degree(A[n][m]); } } } } } if (*tempM == -1 || *tempN == -1) { *finished = 1; } }
// sets q equal to the polynomial s.t. a = bq + r void eucDiv(float a[], float b[], float q[]) { if (equalsZero(a) == 1) { printf("You are calling eucDiv with a equal to the zero vector\n"); return; } if (equalsZero(b) == 1) { printf("You are calling a division by 0\n"); return; } clearZeroes(a); clearZeroes(b); int i; int degA = degree(a); int degB = degree(b); int d = degA - degB; if (d < 0) { printf("This is a nonsensical call of eucDiv\n"); return; } float tempQ; setZero(q); // creates tempA as a clone of a float tempA[maxDegree+1]; setEquals(tempA, a); float tempB[maxDegree+1]; setEquals(tempB, b); // algorithm for euclidean division of polynomials for (i = d; i >= 0; --i) { tempQ = tempA[degA + i - d] / tempB[degB]; q[i] = tempQ; // runs iff |tempQ| < 0.001 if (isAboutZero(tempQ) == 0) { scale(tempB, tempQ); polyTimesXn(tempB, i); subtract(tempA, tempB); polyTimesXn(tempB, -i); scale(tempB, 1.0/tempQ); } } }
void updateFinishedColumns(float A[][M][maxDegree+1], int finishedColumns[]) { int tempCount, m, n; for(m = 0; m < M; ++m) { tempCount = 0; for(n = 0; n < N; ++n) { if(equalsZero(A[n][m]) == 0) { ++tempCount; } } if(tempCount < 2) { finishedColumns[m] = m; } else { finishedColumns[m] = -1; } } }
void orderHelper(float A[][M][maxDegree+1], int *tempN, int *tempM, int counter) { int m, n; int tempMin = -1; int boole = 0; for(n = counter; n < N; ++n) { for(m = counter; m < M; ++m) { if(equalsZero(A[n][m]) == 0) { *tempN = n; *tempM = m; tempMin = degree(A[n][m]); boole = 1; break; } if (boole == 1) { break; } } } if (tempMin == -1) { printf("This should not execute Error in orderHelper.\n"); return; } for(n = counter; n < N; ++n) { for (m = counter; m < M; ++m) { if (equalsZero(A[n][m]) == 0) { if(degree(A[n][m]) < tempMin) { *tempN = n; *tempM = m; tempMin = degree(A[n][m]); } } } } if(*tempN == -1 || *tempM == -1) { printf("tempN or tempN is equal to -1\n"); } // } }
// calculates the rank of a matrix where there is only one entry per row and one entry per column int getRank(float A[][M][maxDegree+1]) { int rank = 0; int n, m; for (n = 0; n < N; ++n) { for(m = 0; m < M; ++m) { if (equalsZero(A[n][m]) == 0) { ++rank; break; } } } return rank; }
// helper method for printDiff void printDiffRow(float p[][maxDegree+1]) { int n; printf("("); for(n = 0; n < N; ++n) { if (equalsZero(p[n]) == 0) { printf("("); printPoly(p[n], 0); printf(")"); printf("*f_%d", n); if (n + 1 < N) { printf(" + "); } } } printf(")"); }
/** * Converts the relative probabilities for instance models into * absolute ones, taking into account the instance density of the * underlying terrain type. * * * * \param instance_probability [in,out] The probability for a model occuring * as specified in Grome. First vector are different terrain types, * second is model type. Doesn't sum up to one, doesn't reflect * different densities of terrain types yet. * * \param max_density The maximum instance density of any terrain * type. This will determine the number of actual instance prototypes * allocated per toroidal buffer cell. * * \param tex_info Description of the different terrain types. */ void InstancePlacer::normalizeProbabilities(std::vector<std::vector<float> > & instance_probability, float max_density, const std::vector<bbm::DetailTexInfo> & tex_info) const { assert(instance_probability.size() == tex_info.size()); for (unsigned i=0; i<instance_probability.size(); ++i) { float sum = 0.0f; for (unsigned j=0; j<instance_probability[i].size(); ++j) { sum += instance_probability[i][j]; } for (unsigned j=0; j<instance_probability[i].size(); ++j) { float density = tex_info[i].grass_density_; if (!equalsZero(sum)) instance_probability[i][j] *= density / (max_density * sum); } } }
int dividesPoly(float a[], float b[]) { int i; // creates tempA as a clone of a float tempA[maxDegree+1]; setEquals(tempA, a); float tempB[maxDegree+1]; setEquals(tempB, b); float q[maxDegree+1]; setZero(q); int degA = degree(a); int degB = degree(b); int d = degA - degB; float tempQ; // algorithm for euclidean division for (i = d; i >= 0; --i) { tempQ = tempA[degA + i - d] / tempB[degB]; q[i] = tempQ; if (tempQ != 0) { scale(tempB, tempQ); polyTimesXn(tempB, i); subtract(tempA, tempB); polyTimesXn(tempB, -i); scale(tempB, 1.0/tempQ); } } multiply(b, q, tempA); subtract(tempA, a); clearZeroes(tempA); if(equalsZero(tempA) == 1) { return 1; } else { return 0; } }
void leastEntryAlgo(float A[][M][maxDegree+1], float P[][N][maxDegree+1], float Pinv[][N][maxDegree+1], float Q[][M][maxDegree+1], float Qinv[][M][maxDegree+1]) { int n, m; // used in for loops over rows, columns respectively int p; // used in for loops over polynomial array int tempN, tempM, tempMin; //used to store temporary locations in A int finished = 0; // bool to decide if while loop is over int tempRowEntry, tempColEntry, tempMult, tempEntry; int diag = 0; float q[maxDegree+1]; // for finishedRows and finishedColumns, // set entry i to -1 if row/col i is not finished, or // set entry i to i if row/col i is finished int finishedRows[N]; int finishedColumns[M]; //initializes finishedRows and finishedColumns for(n = 0; n < N; ++n) { finishedRows[n] = -1; } for(m = 0; m < M; ++m) { finishedColumns[m] = -1; } // begin the least entry algorithm while (finished == 0) { // resets tempM and tempN to -1 tempM = -1; tempN = -1; // finds least non-zero entry, stores it in tempN, tempM findLeastEntry(A, finishedRows, finishedColumns, &tempN, &tempM, &finished); /* the loop should never break here; this if statement is more or less a "just in case" used when developing */ if(finished == 1) { break; } // resets tempRowEntry and tempColEntry to -1 tempRowEntry = -1; tempColEntry = -1; /* checks if we can do row operations. by convention established (arbitrarily) in this program, we do row oeprations when we can */ if(contains(finishedColumns, M, tempM) == 0) { // finds an entry for the least entry to reduce for(n = 0; n < N; ++n) { if(equalsZero(A[n][tempM]) == 0 && n != tempN) { tempRowEntry = n; break; } } /* if there is no good entry to operate on, break the loop in practice this would never happen, but convienient for dev. */ if (tempRowEntry == -1) { break; } /* sets the vector q (in the sense of a = b*q + r) so we can use it to do row operations */ eucDiv(A[tempRowEntry][tempM], A[tempN][tempM], q); rowOperations2(A, P, Pinv, tempRowEntry, tempN, q); } // if we cannot do row operations, we do column operations else { for(m = 0; m < M; ++m) { if(equalsZero(A[tempN][m]) == 0 && m != tempM) { tempColEntry = m; break; } } if (tempColEntry == -1) { break; } eucDiv(A[tempN][tempColEntry], A[tempN][tempM], q); columnOperations2(A, Q, Qinv, tempColEntry, tempM, q); } // updates rows and colums that are finished updateFinishedRows(A, finishedRows); updateFinishedColumns(A, finishedColumns); finished = done(finishedRows, finishedColumns, N, M); } // now we can compute the rank rank = getRank(A); /* perform type 3 operations to order the non-zero elements onto the diagonals */ orderDiagonals(A, P, Pinv, Q, Qinv); // make all polynomials monic makeAllMonic(A, P, Pinv); // computation trick: transpose Q and Pinv so they are correct transposeM(Qinv); transposeN(Pinv); }