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));
120 for (
size_t i = 0; i < n; i++)
122 distances[i] =
DIST(x_coords[i], y_coords[i], x_focus, y_focus);
124 assert(n <= INT_MAX);
127 int *ordering =
gv_calloc(n,
sizeof(
int));
128 for (
size_t i = 0; i < n; i++)
130 ordering[i] = (int)i;
135 double *smoothed_densities =
smooth_vec(densities, ordering, n, interval);
138 if (distortion < 1.01 && distortion > 0.99)
140 for (
size_t i = 1; i < n; i++)
142 distances[ordering[i]] = distances[ordering[i - 1]] + (orig_distances[ordering[i]] -
143 orig_distances[ordering
145 1]]) / smoothed_densities[ordering[i]];
150 const double factor = (signbit(distortion) ? -1 : 1) * sqrt(fabs(distortion));
151 for (
size_t i = 1; i < n; i++)
153 distances[ordering[i]] =
154 distances[ordering[i - 1]] + (orig_distances[ordering[i]] -
155 orig_distances[ordering
158 pow(smoothed_densities[ordering[i]], factor);
163 for (
size_t i = 0; i < n; i++)
166 orig_distances[i] > 0 ? distances[i] / orig_distances[i] : 0;
167 x_coords[i] = x_focus + (x_coords[i] - x_focus) * ratio;
168 y_coords[i] = y_focus + (y_coords[i] - y_focus) * ratio;
172 free(smoothed_densities);
174 free(orig_distances);
180 double *x_foci,
double *y_foci,
int num_foci,
181 size_t n,
int interval,
double width,
182 double height,
double distortion) {
184 double minX, maxX, minY, maxY;
191 minX = maxX = x_coords[0];
192 minY = maxY = y_coords[0];
193 for (
size_t i = 1; i < n; i++)
195 minX = fmin(minX, x_coords[i]);
196 minY = fmin(minY, y_coords[i]);
197 maxX = fmax(maxX, x_coords[i]);
198 maxY = fmax(maxY, y_coords[i]);
200 aspect_ratio = (maxX - minX) / (maxY - minY);
203 assert(n <= INT_MAX);
209 y_foci[0], interval, distortion);
213 double *final_x_coords =
gv_calloc(n,
sizeof(
double));
214 double *final_y_coords =
gv_calloc(n,
sizeof(
double));
215 double *cp_x_coords =
gv_calloc(n,
sizeof(
double));
216 double *cp_y_coords =
gv_calloc(n,
sizeof(
double));
217 assert(n <= INT_MAX);
218 for (
int i = 0; i < num_foci; i++) {
222 x_foci[i], y_foci[i], interval, distortion);
223 scadd(final_x_coords, (
int)n - 1, 1.0 / num_foci, cp_x_coords);
224 scadd(final_y_coords, (
int)n - 1, 1.0 / num_foci, cp_y_coords);
228 free(final_x_coords);
229 free(final_y_coords);
236 minX = maxX = x_coords[0];
237 minY = maxY = y_coords[0];
238 for (
size_t i = 1; i < n; i++) {
239 minX = fmin(minX, x_coords[i]);
240 minY = fmin(minY, y_coords[i]);
241 maxX = fmax(maxX, x_coords[i]);
242 maxY = fmax(maxY, y_coords[i]);
246 for (
size_t i = 0; i < n; i++) {
252 scaleX = aspect_ratio * (maxY - minY) / (maxX - minX);
253 for (
size_t i = 0; i < n; i++) {
254 x_coords[i] *= scaleX;
260 MIN((width) / (aspect_ratio * (maxY - minY)),
261 (height) / (maxY - minY));
262 for (
size_t i = 0; i < n; i++) {
263 x_coords[i] *= scale_ratio;
264 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