/* Actually move the fish. */ void move_fish(fish_t* fish, const int n_fish, const double dt) { int i; for (i = 0; i < n_fish; ++i) { fish[i].x += dt * fish[i].vx; fish[i].y += dt * fish[i].vy; fish[i].vx += dt * fish[i].ax; fish[i].vy += dt * fish[i].ay; bounce_fish(&fish[i]); assert(scale_coord(fish[i].x) >= 0.0); assert(scale_coord(fish[i].y) >= 0.0); } }
/* Dump out all the fishies (and their center of gravity) in a format that the viewer understands. */ void output_fish(FILE* output_fp, const double t, const double dt, const fish_t* fish, const int n_fish) { int i; double cg_x = 0.0; double cg_y = 0.0; fprintf(output_fp, "%.5g (%.5g):\n", t, dt); for (i = 0; i < n_fish; ++i) { cg_x += fish[i].x; cg_y += fish[i].y; fprintf(output_fp, " %d: (%g, %g)\n", i, scale_coord(fish[i].x), scale_coord(fish[i].y)); } cg_x /= n_fish; cg_y /= n_fish; fprintf(output_fp, " cg: (%g, %g)\n", scale_coord(cg_x), scale_coord(cg_y)); }
real overlap_scaling(int dim, int m, real *x, real *width, real scale_sta, real scale_sto, real epsilon, int maxiter){ /* do a bisection between scale_sta and scale_sto, up to maxiter iterations or till interval <= epsilon, to find the best scaling to avoid overlap m: number of points x: the coordinates width: label size scale_sta: starting bracket. If <= 0, assumed 0. If > 0, we will test this first and if no overlap, return. scale_sto: stopping bracket. This must be overlap free if positive. If <= 0, we will find automatically by doubling from scale_sta, or epsilon if scale_sta <= 0. typically usage: - for shrinking down a layout to reduce white space, we will assume scale_sta and scale_sto are both given and positive, and scale_sta is the current guess. - for scaling up, we assume scale_sta, scale_sto <= 0 */ real scale = -1, scale_best = -1; SparseMatrix C = NULL; int check_overlap_only = 1; int overlap = 0; real two = 2; int iter = 0; assert(epsilon > 0); if (scale_sta <= 0) { scale_sta = 0; } else { scale_coord(dim, m, x, scale_sta); C = get_overlap_graph(dim, m, x, width, check_overlap_only); if (!C || C->nz == 0) { if (Verbose) fprintf(stderr," shrinking with with %f works\n", scale_sta); SparseMatrix_delete(C); return scale_sta; } scale_coord(dim, m, x, 1./scale_sta); SparseMatrix_delete(C); } if (scale_sto < 0){ if (scale_sta == 0) { scale_sto = epsilon; } else { scale_sto = scale_sta; } scale_coord(dim, m, x, scale_sto); do { scale_sto *= two; scale_coord(dim, m, x, two); C = get_overlap_graph(dim, m, x, width, check_overlap_only); overlap = (C && C->nz > 0); SparseMatrix_delete(C); } while (overlap); scale_coord(dim, m, x, 1/scale_sto);/* unscale */ } scale_best = scale_sto; while (iter++ < maxiter && scale_sto - scale_sta > epsilon){ fprintf(stderr,"in overlap_scaling iter=%d, maxiter=%d, scaling bracket: {%f,%f}\n", iter, maxiter, scale_sta, scale_sto); scale = 0.5*(scale_sta + scale_sto); scale_coord(dim, m, x, scale); C = get_overlap_graph(dim, m, x, width, check_overlap_only); scale_coord(dim, m, x, 1./scale);/* unscale */ overlap = (C && C->nz > 0); SparseMatrix_delete(C); if (overlap){ scale_sta = scale; } else { scale_best = scale_sto = scale; } } /* final scaling */ scale_coord(dim, m, x, scale_best); return scale_best; }