/* Rotate substring left by one bit. */ static void bitarray_rotate_left_one(bitarray_t *ba, size_t bit_off, size_t bit_len) { size_t i; bool first_bit = bitarray_get(ba, bit_off); for (i = bit_off; i + 1 < bit_off + bit_len; i++) bitarray_set(ba, i, bitarray_get(ba, i + 1)); bitarray_set(ba, i, first_bit); }
static void bitarray_reverse(bitarray_t *const bitarray, const size_t bit_offset, const size_t bit_length) { bool temp_bit; for (size_t i = bit_offset; i < (bit_offset + bit_length) / 2; i++) { bitarray_set(bitarray, i, bitarray_get(bitarray,i) ^ bitarray_get(bitarray, bit_offset + bit_length - (i - bit_offset) - 1)); bitarray_set(bitarray, bit_offset + bit_length - (i - bit_offset) - 1, bitarray_get(bitarray,i) ^ bitarray_get(bitarray, bit_offset + bit_length - (i - bit_offset) - 1)); bitarray_set(bitarray, i, bitarray_get(bitarray,i) ^ bitarray_get(bitarray, bit_offset + bit_length - (i - bit_offset) - 1) ); } }
static void bitarray_rotate_left_one(bitarray_t *const bitarray, const size_t bit_offset, const size_t bit_length) { // Grab the first bit in the range, shift everything left by one, and // then stick the first bit at the end. const bool first_bit = bitarray_get(bitarray, bit_offset); size_t i; for (i = bit_offset; i + 1 < bit_offset + bit_length; i++) { bitarray_set(bitarray, i, bitarray_get(bitarray, i + 1)); } bitarray_set(bitarray, i, first_bit); }
size_t bitarray_count_flips(bitarray_t *ba, size_t bit_off, size_t bit_len) { assert(bit_off + bit_len <= ba->bit_sz); size_t i, ret = 0; /* Go from the first bit in the substring to the second to last one. For each bit, count another transition if the bit is different from the next one. Note: do "i + 1 < bit_off + bit_len" instead of "i < bit_off + bit_len - 1" to prevent wraparound in the case where bit_off + bit_len == 0. */ for (i = bit_off; i + 1 < bit_off + bit_len; i++) { if (bitarray_get(ba, i) != bitarray_get(ba, i + 1)) ret++; } return ret; }
static void testutil_expect_internal(const char *bitstring, const char *const func_name, const int line) { // The reason why the test fails. If the test passes, this will stay // NULL. const char *bad = NULL; assert(test_bitarray != NULL); // Check the length of the bit array under test. const size_t bitstring_length = strlen(bitstring); if (bitstring_length != bitarray_get_bit_sz(test_bitarray)) { bad = "bitarray size"; } // Check the content. for (size_t i = 0; i < bitstring_length; i++) { if (bitarray_get(test_bitarray, i) != boolfromchar(bitstring[i])) { bad = "bitarray content"; } } // Obtain a string for the actual bitstring. const size_t actual_bitstring_length = bitarray_get_bit_sz(test_bitarray); char* actual_bitstring = malloc(sizeof(char) * bitstring_length); for (size_t i = 0; i < actual_bitstring_length; i++) { if (bitarray_get(test_bitarray, i)) { actual_bitstring[i] = '1'; } else { actual_bitstring[i] = '0'; } } if (bad != NULL) { bitarray_fprint(stdout, test_bitarray); fprintf(stdout, " expect bits=%s \n", bitstring); TEST_FAIL_WITH_NAME(func_name, line, " Incorrect %s.\n Expected: %s\n Actual: %s", bad, bitstring, actual_bitstring); } else { TEST_PASS_WITH_NAME(func_name, line); } free(actual_bitstring); }
/* Verify that the test_ba bitarray has the expected content. Output FAIL or PASS as appropriate for the Python testing script to parse. Use the testutil_expect() macro to run this function. */ static void testutil_expect_internal(const char *bitstr, size_t flipcount, const char* name) { const char *bad = NULL; assert(test_ba != NULL); size_t sl = strlen(bitstr), i; if (sl != bitarray_get_bit_sz(test_ba)) bad = "bitarray size"; for (i = 0; i < sl; i++) { if (bitarray_get(test_ba, i) != boolfromchar(bitstr[i])) bad = "bitarray content"; } if (bad != NULL) { bitarray_fprint(stdout, test_ba); fprintf(stdout, " expect bits=%s \n", bitstr); TEST_FAIL(name, "incorrect %s", bad); } else { TEST_PASS_WITH_NAME(name); } }
/* Print a string representation of a bitarray. */ static void bitarray_fprint(FILE *f, bitarray_t *ba) { size_t i; for (i = 0; i < bitarray_get_bit_sz(ba); i++) fprintf(f, "%d", bitarray_get(ba, i) ? 1 : 0); }
static void bitarray_fprint(FILE *const stream, const bitarray_t *const bitarray) { for (size_t i = 0; i < bitarray_get_bit_sz(bitarray); i++) { fprintf(stream, "%d", bitarray_get(bitarray, i) ? 1 : 0); } }
void display() { glClearColor(1, 1, 1, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); if ((glParams->forcemode & (CHARGED_WALLS | BOUNCY_WALLS)) == 0) { //I actually need to normalise all the values for drawing float minx = FLT_MAX, maxx = FLT_MIN, miny = FLT_MAX, maxy = FLT_MIN; for (int i = 0; i < glGraph[0]->numNodes; i++) { node* n = glGraph[0]->nodes + i; if (n->x - n->width / 2 < minx) { minx = n->x - n->width / 2; } if (n->x + n->width / 2 > maxx) { maxx = n->x + n->width / 2; } if (n->y - n->height / 2 < miny) { miny = n->y - n->height / 2; } if (n->y + n->height / 2 > maxy) { maxy = n->y + n->height / 2; } } glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(minx, maxx, maxy, miny); glMatrixMode(GL_MODELVIEW); } //draw edges glBegin(GL_LINES); glColor3f(1.0f, 0.0f, 0.0f); /* set object color as red */ for (int i = 0; i < glGraph[0]->numNodes; i++) { for (int j = i + 1; j < glGraph[0]->numNodes; j++) { if (bitarray_get(glGraph[0]->edges, i + j * glGraph[0]->numNodes)) { float x1 = glGraph[0]->nodes[i].x; float x2 = glGraph[0]->nodes[j].x; float y1 = glGraph[0]->nodes[i].y; float y2 = glGraph[0]->nodes[j].y; glVertex2f(x1, y1); glVertex2f(x2, y2); } } } glEnd(); //draw Nodes glBegin(GL_QUADS); glColor3f(0.0, 0, 1.0); for (int i = 0; i < glGraph[0]->numNodes; i++) { node* n = glGraph[0]->nodes + i; int x = (int) (n->x - n->width / 2); int y = (int) (n->y - n->height / 2); int width = n->width; int height = n->height; glVertex2f(x, y); glVertex2f(x + width, y); glVertex2f(x + width, y + height); glVertex2f(x, y + height); } glEnd(); glDisable(GL_DEPTH_TEST); glDisable(GL_LIGHTING); glDisable(GL_COLOR_MATERIAL); GLenum error = glGetError(); while (error != GL_NO_ERROR) { fprintf(stderr, "%s\n", gluErrorString(error)); error = glGetError(); } glutSwapBuffers(); }
void graph_toSVG(graph* g, const char* filename, int screenwidth, int screenheight, bool hasWalls, long time, layout_params* params) { FILE* svg = ensureFile(filename); if (svg == NULL) { printf("Failed to create file (%s).\n", filename); return; } int stat; stat = fprintf(svg, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" standalone=\"no\"?>\n"); stat = fprintf(svg, "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 20010904//EN\"\n"); stat = fprintf(svg, "\"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">\n"); stat = fprintf(svg, "<svg xmlns=\"http://www.w3.org/2000/svg\"\n"); stat = fprintf(svg, "xmlns:xlink=\"http://www.w3.org/1999/xlink\" xml:space=\"preserve\"\n"); stat = fprintf(svg, "width=\"%dpx\" height=\"%dpx\"\n", screenwidth, screenheight); if (hasWalls) { stat = fprintf(svg, "viewBox=\"0 0 %d %d\"\n", screenwidth, screenheight); } else { float minx = FLT_MAX, maxx = FLT_MIN, miny = FLT_MAX, maxy = FLT_MIN; for (int i = 0; i < g->numNodes; i++) { node* n = g->nodes + i; if (n->x - n->width / 2 < minx) { minx = n->x - n->width / 2; } if (n->x + n->width / 2 > maxx) { maxx = n->x + n->width / 2; } if (n->y - n->height / 2 < miny) { miny = n->y - n->height / 2; } if (n->y + n->height / 2 > maxy) { maxy = n->y + n->height / 2; } } stat = fprintf(svg, "viewBox=\"%ld %ld %ld %ld\"\n", (long) minx, (long) miny, (long) (maxx - minx), (long) (maxy - miny)); } stat = fprintf(svg, "zoomAndPan=\"disable\" >\n"); /** * As a comment, print out the graph and data */ stat = fprintf(svg, "<!--\n"); // Begin comment block (for easy extraction) stat = fprintf(svg, "elapsed: %ld\n", time); stat = fprintf(svg, "filename: %s\n", g->filename); //Print the program arguments stat = fprintf(svg, "width: %d\n", params->width); stat = fprintf(svg, "height: %d\n", params->height); stat = fprintf(svg, "iterations: %d\n", params->iterations); stat = fprintf(svg, "forcemode: %d\n", params->forcemode); stat = fprintf(svg, "ke: %f\n", params->ke); stat = fprintf(svg, "kh: %f\n", params->kh); stat = fprintf(svg, "kl: %f\n", params->kl); stat = fprintf(svg, "kw: %f\n", params->kw); stat = fprintf(svg, "mass: %f\n", params->mass); stat = fprintf(svg, "time: %f\n", params->time); stat = fprintf(svg, "coefficientOfRestitution: %f\n", params->coefficientOfRestitution); stat = fprintf(svg, "mus: %f\n", params->mus); stat = fprintf(svg, "muk: %f\n", params->muk); stat = fprintf(svg, "kg: %f\n", params->kg); stat = fprintf(svg, "wellMass: %f\n", params->wellMass); stat = fprintf(svg, "edgeCharge: %f\n", params->edgeCharge); stat = fprintf(svg, "finalKineticEnergy: %f\n", g->finalEK); stat = fprintf(svg, "nodeWidth: %f\n", g->nodes[0].width); stat = fprintf(svg, "nodeHeight: %f\n", g->nodes[0].height); stat = fprintf(svg, "nodeCharge: %f\n", g->nodes[0].charge); stat = fprintf(svg, "-\n"); // Begin comment block (for easy extraction) //Print the graph as the adjacency matrix stat = fprintf(svg, "Start Graph:\n"); stat = fprintf(svg, "%d\n", g->numNodes); // num Nodes for (int i = 0; i < g->numNodes; i++) { stat = fprintf(svg, "%0.2f %0.2f ", g->nodes[i].x, g->nodes[i].y); for (int j = 0; j < g->numNodes; j++) { stat = fprintf(svg, "%d ", (bitarray_get(g->edges,i * g->numNodes + j)) ? 1 : 0); } fprintf(svg, "\n"); //end row } stat = fprintf(svg, "-->\n"); // End comment block (for easy extraction) int i, j; /*Draw edges*/ for (i = 0; i < g->numNodes; i++) { for (j = i + 1; j < g->numNodes; j++) { if (bitarray_get(g->edges,i + j * g->numNodes)) { int x1 = g->nodes[i].x; int x2 = g->nodes[j].x; int y1 = g->nodes[i].y; int y2 = g->nodes[j].y; stat = fprintf(svg, "<line x1=\"%d\" x2=\"%d\" y1=\"%d\" y2=\"%d\" stroke=\"%s\" fill=\"%s\" opacity=\"%.2f\"/>\n", x1, x2, y1, y2, "rgb(255,0,0)", "rgb(255,0,0)", 1.0f); if (stat < 0) { printf("An error occured while writing to the file"); fclose(svg); return; } } } } /*Draw nodes*/ for (i = 0; i < g->numNodes; i++) { node* n = g->nodes + i; int x = (int) (n->x - n->width / 2); int y = (int) (n->y - n->height / 2); int width = n->width; int height = n->height; stat = fprintf(svg, "<rect x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" fill=\"%s\" stroke=\"%s\" opacity=\"%.2f\"/>\n", x, y, width, height, "rgb(0,0,255)", "rgb(0,0,0)", 1.0f); if (stat < 0) { printf("An error occurred while writing to the file"); fclose(svg); return; } } stat = fprintf(svg, "<rect x=\"0\" y=\"0\" width=\"%d\" height=\"%d\" stroke=\"rgb(0,255,0)\" fill-opacity=\"0\"/>\n", screenwidth, screenheight); fprintf(svg, "</svg>"); fclose(svg); }