56static double *
smooth_vec(
double *vec,
int *ordering,
size_t n,
int interval) {
58 assert(interval >= 0);
60 double *smoothed_vec =
gv_calloc(n,
sizeof(
double));
61 size_t n1 =
MIN(1 + (
size_t)interval, n);
63 for (
size_t i = 0; i < n1; i++) {
64 sum += vec[ordering[i]];
68 for (
size_t i = 0; i <
MIN(n, (
size_t)interval); i++) {
69 smoothed_vec[ordering[i]] = sum / (double)
len;
71 sum += vec[ordering[
len++]];
74 if (n <= (
size_t)interval) {
78 for (
size_t i = (
size_t)interval; i < n - (size_t)interval - 1; i++) {
79 smoothed_vec[ordering[i]] = sum / (double)
len;
81 vec[ordering[i + (size_t)interval + 1]] - vec[ordering[i - (
size_t)interval]];
83 for (
size_t i =
MAX(n - (
size_t)interval - 1, (size_t)interval); i < n; i++) {
84 smoothed_vec[ordering[i]] = sum / (double)
len;
85 sum -= vec[ordering[i - (size_t)interval]];
112 double *y_coords,
double x_focus,
113 double y_focus,
int interval,
116 double *densities =
NULL;
117 double *distances =
gv_calloc(n,
sizeof(
double));
118 double *orig_distances =
gv_calloc(n,
sizeof(
double));
121 for (
size_t i = 0; i < n; i++)
123 distances[i] =
DIST(x_coords[i], y_coords[i], x_focus, y_focus);
125 assert(n <= INT_MAX);
128 int *ordering =
gv_calloc(n,
sizeof(
int));
129 for (
size_t i = 0; i < n; i++)
131 ordering[i] = (int)i;
136 double *smoothed_densities =
smooth_vec(densities, ordering, n, interval);
139 if (distortion < 1.01 && distortion > 0.99)
141 for (
size_t i = 1; i < n; i++)
143 distances[ordering[i]] = distances[ordering[i - 1]] + (orig_distances[ordering[i]] -
144 orig_distances[ordering
146 1]]) / smoothed_densities[ordering[i]];
154 factor = sqrt(distortion);
158 factor = -sqrt(-distortion);
160 for (
size_t i = 1; i < n; i++)
162 distances[ordering[i]] =
163 distances[ordering[i - 1]] + (orig_distances[ordering[i]] -
164 orig_distances[ordering
167 pow(smoothed_densities[ordering[i]], factor);
172 for (
size_t i = 0; i < n; i++)
174 if (orig_distances[i] == 0)
180 ratio = distances[i] / orig_distances[i];
182 x_coords[i] = x_focus + (x_coords[i] - x_focus) * ratio;
183 y_coords[i] = y_focus + (y_coords[i] - y_focus) * ratio;
187 free(smoothed_densities);
189 free(orig_distances);
195 double *x_foci,
double *y_foci,
int num_foci,
196 size_t n,
int interval,
double width,
197 double height,
double distortion) {
199 double minX, maxX, minY, maxY;
206 minX = maxX = x_coords[0];
207 minY = maxY = y_coords[0];
208 for (
size_t i = 1; i < n; i++)
210 minX = fmin(minX, x_coords[i]);
211 minY = fmin(minY, y_coords[i]);
212 maxX = fmax(maxX, x_coords[i]);
213 maxY = fmax(maxY, y_coords[i]);
215 aspect_ratio = (maxX - minX) / (maxY - minY);
218 assert(n <= INT_MAX);
224 y_foci[0], interval, distortion);
228 double *final_x_coords =
gv_calloc(n,
sizeof(
double));
229 double *final_y_coords =
gv_calloc(n,
sizeof(
double));
230 double *cp_x_coords =
gv_calloc(n,
sizeof(
double));
231 double *cp_y_coords =
gv_calloc(n,
sizeof(
double));
232 assert(n <= INT_MAX);
233 for (
int i = 0; i < num_foci; i++) {
237 x_foci[i], y_foci[i], interval, distortion);
238 scadd(final_x_coords, (
int)n - 1, 1.0 / num_foci, cp_x_coords);
239 scadd(final_y_coords, (
int)n - 1, 1.0 / num_foci, cp_y_coords);
243 free(final_x_coords);
244 free(final_y_coords);
251 minX = maxX = x_coords[0];
252 minY = maxY = y_coords[0];
253 for (
size_t i = 1; i < n; i++) {
254 minX = fmin(minX, x_coords[i]);
255 minY = fmin(minY, y_coords[i]);
256 maxX = fmax(maxX, x_coords[i]);
257 maxY = fmax(maxY, y_coords[i]);
261 for (
size_t i = 0; i < n; i++) {
267 scaleX = aspect_ratio * (maxY - minY) / (maxX - minX);
268 for (
size_t i = 0; i < n; i++) {
269 x_coords[i] *= scaleX;
275 MIN((width) / (aspect_ratio * (maxY - minY)),
276 (height) / (maxY - minY));
277 for (
size_t i = 0; i < n; i++) {
278 x_coords[i] *= scale_ratio;
279 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