bool mapHandleEvent(SDL_Event *event) { switch (event->type) { case SDL_MOUSEMOTION: // Drag the map with the right mouse button if (event->motion.state & SDL_BUTTON_RMASK) { map.offset.x += event->motion.x - map.dragPos.x; map.offset.y += event->motion.y - map.dragPos.y; SDL_WarpMouseInWindow(engine.window, map.dragPos.x, map.dragPos.y); } // Update block selection map.selEnd = (Vector){ eucDiv(event->motion.x - map.offset.x, TILE_SIZE*map.zoom), eucDiv(event->motion.y - map.offset.y, TILE_SIZE*map.zoom), }; if (!(event->motion.state & SDL_BUTTON_LMASK)) { map.selStart = map.selEnd; } break; case SDL_MOUSEBUTTONDOWN: if (event->button.button == SDL_BUTTON_RIGHT) { // Capture cursor for map dragging SDL_GetMouseState(&map.dragPos.x, &map.dragPos.y); SDL_ShowCursor(0); } break; case SDL_MOUSEBUTTONUP: if (event->button.button == SDL_BUTTON_LEFT) { // Holding in SHIFT deselects the block SDL_Keymod mod = SDL_GetModState(); if (mod & KMOD_SHIFT) { mapDeselect(); } else { mapSelect(); } map.selStart = map.selEnd; } else if (event->button.button == SDL_BUTTON_RIGHT) { // Uncapture cursor SDL_ShowCursor(1); } break; case SDL_KEYDOWN: if (event->key.keysym.sym == SDLK_1) { map.zoom = 1; } else if (event->key.keysym.sym == SDLK_2) { map.zoom = 2; } } return true; }
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); }