58static double *
smooth_vec(
double *vec,
int *ordering,
size_t n,
int interval) {
60 assert(interval >= 0);
62 double *smoothed_vec =
gv_calloc(n,
sizeof(
double));
63 size_t n1 =
MIN(1 + (
size_t)interval, n);
65 for (
size_t i = 0; i < n1; i++) {
66 sum += vec[ordering[i]];
70 for (
size_t i = 0; i <
MIN(n, (
size_t)interval); i++) {
71 smoothed_vec[ordering[i]] = sum / (double)
len;
73 sum += vec[ordering[
len++]];
76 if (n <= (
size_t)interval) {
80 for (
size_t i = (
size_t)interval; i < n - (size_t)interval - 1; i++) {
81 smoothed_vec[ordering[i]] = sum / (double)
len;
83 vec[ordering[i + (size_t)interval + 1]] - vec[ordering[i - (
size_t)interval]];
85 for (
size_t i =
MAX(n - (
size_t)interval - 1, (size_t)interval); i < n; i++) {
86 smoothed_vec[ordering[i]] = sum / (double)
len;
87 sum -= vec[ordering[i - (size_t)interval]];
114 double *y_coords,
double x_focus,
115 double y_focus,
int interval,
118 double *densities =
NULL;
119 double *distances =
gv_calloc(n,
sizeof(
double));
120 double *orig_distances =
gv_calloc(n,
sizeof(
double));
122 for (
size_t i = 0; i < n; i++)
124 distances[i] =
DIST(x_coords[i], y_coords[i], x_focus, y_focus);
126 assert(n <= INT_MAX);
129 int *ordering =
gv_calloc(n,
sizeof(
int));
130 for (
size_t i = 0; i < n; i++)
132 ordering[i] = (int)i;
137 double *smoothed_densities =
smooth_vec(densities, ordering, n, interval);
140 if (distortion < 1.01 && distortion > 0.99)
142 for (
size_t i = 1; i < n; i++)
144 distances[ordering[i]] = distances[ordering[i - 1]] + (orig_distances[ordering[i]] -
145 orig_distances[ordering
147 1]]) / smoothed_densities[ordering[i]];
152 const double factor = (signbit(distortion) ? -1 : 1) * sqrt(fabs(distortion));
153 for (
size_t i = 1; i < n; i++)
155 distances[ordering[i]] =
156 distances[ordering[i - 1]] + (orig_distances[ordering[i]] -
157 orig_distances[ordering
160 pow(smoothed_densities[ordering[i]], factor);
165 for (
size_t i = 0; i < n; i++)
168 orig_distances[i] > 0 ? distances[i] / orig_distances[i] : 0;
169 x_coords[i] = x_focus + (x_coords[i] - x_focus) * ratio;
170 y_coords[i] = y_focus + (y_coords[i] - y_focus) * ratio;
174 free(smoothed_densities);
176 free(orig_distances);
182 double *x_foci,
double *y_foci,
int num_foci,
183 size_t n,
int interval,
double width,
184 double height,
double distortion) {
186 double minX, maxX, minY, maxY;
193 minX = maxX = x_coords[0];
194 minY = maxY = y_coords[0];
195 for (
size_t i = 1; i < n; i++)
197 minX = fmin(minX, x_coords[i]);
198 minY = fmin(minY, y_coords[i]);
199 maxX = fmax(maxX, x_coords[i]);
200 maxY = fmax(maxY, y_coords[i]);
202 aspect_ratio = (maxX - minX) / (maxY - minY);
205 assert(n <= INT_MAX);
211 y_foci[0], interval, distortion);
215 double *final_x_coords =
gv_calloc(n,
sizeof(
double));
216 double *final_y_coords =
gv_calloc(n,
sizeof(
double));
217 double *cp_x_coords =
gv_calloc(n,
sizeof(
double));
218 double *cp_y_coords =
gv_calloc(n,
sizeof(
double));
219 assert(n <= INT_MAX);
220 for (
int i = 0; i < num_foci; i++) {
224 x_foci[i], y_foci[i], interval, distortion);
225 scadd(final_x_coords, (
int)n - 1, 1.0 / num_foci, cp_x_coords);
226 scadd(final_y_coords, (
int)n - 1, 1.0 / num_foci, cp_y_coords);
230 free(final_x_coords);
231 free(final_y_coords);
238 minX = maxX = x_coords[0];
239 minY = maxY = y_coords[0];
240 for (
size_t i = 1; i < n; i++) {
241 minX = fmin(minX, x_coords[i]);
242 minY = fmin(minY, y_coords[i]);
243 maxX = fmax(maxX, x_coords[i]);
244 maxY = fmax(maxY, y_coords[i]);
248 for (
size_t i = 0; i < n; i++) {
254 scaleX = aspect_ratio * (maxY - minY) / (maxX - minX);
255 for (
size_t i = 0; i < n; i++) {
256 x_coords[i] *= scaleX;
262 MIN((width) / (aspect_ratio * (maxY - minY)),
263 (height) / (maxY - minY));
264 for (
size_t i = 0; i < n; i++) {
265 x_coords[i] *= scale_ratio;
266 y_coords[i] *= scale_ratio;
static void rescale_layout_polarFocus(v_data *graph, size_t n, double *x_coords, double *y_coords, double x_focus, double y_focus, int interval, double distortion)
void rescale_layout_polar(double *x_coords, double *y_coords, double *x_foci, double *y_foci, int num_foci, size_t n, int interval, double width, double height, double distortion)
static void gv_sort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *, void *), void *arg)
qsort with an extra state parameter, ala qsort_r