作図ソフト dia の改良版
Revision | fc773583c62a5fda06cd4e501a46410907d1458a (tree) |
---|---|
Zeit | 2012-10-04 04:57:18 |
Autor | Hans Breuer <hans@breu...> |
Commiter | Hans Breuer |
[substitute] improve auto-routing to avoid intersects
The auto-routing algorithm now prefers intersection-free
routes between the connected objects.
@@ -60,6 +60,23 @@ static Point *autolayout_unnormalize_points(guint dir, | ||
60 | 60 | Point *points, |
61 | 61 | guint num_points); |
62 | 62 | |
63 | +static int | |
64 | +autolayout_calc_intersects (const Rectangle *r1, const Rectangle *r2, | |
65 | + const Point *points, guint num_points) | |
66 | +{ | |
67 | + guint i, n = 0; | |
68 | + | |
69 | + /* ignoring the first and last line assuming a proper 'outer' algorithm */ | |
70 | + for (i = 1; i < num_points - 2; ++i) { | |
71 | + Rectangle rt = { points[i].x, points[i].y, points[i+1].x, points[i+1].y }; | |
72 | + if (r1) | |
73 | + n += (rectangle_intersects (r1, &rt) ? 1 : 0); | |
74 | + if (r2) | |
75 | + n += (rectangle_intersects (r2, &rt) ? 1 : 0); | |
76 | + } | |
77 | + | |
78 | + return n; | |
79 | +} | |
63 | 80 | /*! |
64 | 81 | * \brief Apply a good route (or none) to the given _OrthConn |
65 | 82 | * |
@@ -84,6 +101,8 @@ autoroute_layout_orthconn(OrthConn *conn, | ||
84 | 101 | ConnectionPoint *startconn, ConnectionPoint *endconn) |
85 | 102 | { |
86 | 103 | real min_badness = MAX_BADNESS; |
104 | + guint best_intersects = G_MAXINT; | |
105 | + guint intersects; | |
87 | 106 | Point *best_layout = NULL; |
88 | 107 | guint best_num_points = 0; |
89 | 108 | int startdir, enddir; |
@@ -144,24 +163,33 @@ autoroute_layout_orthconn(OrthConn *conn, | ||
144 | 163 | &this_layout); |
145 | 164 | } |
146 | 165 | if (this_layout != NULL) { |
147 | - if (this_badness-min_badness < -0.00001) { | |
166 | + /* this_layout is eaten by unnormalize */ | |
167 | + Point *unnormalized = autolayout_unnormalize_points(startdir, startpoint, | |
168 | + this_layout, this_num_points); | |
169 | + | |
170 | + intersects = autolayout_calc_intersects ( | |
171 | + startconn ? dia_object_get_bounding_box (startconn->object) : NULL, | |
172 | + endconn ? dia_object_get_bounding_box (endconn->object) : NULL, | |
173 | + unnormalized, this_num_points); | |
174 | + | |
175 | + if ( intersects <= best_intersects | |
176 | + && this_badness-min_badness < -0.00001) { | |
148 | 177 | /* |
149 | 178 | printf("Dir %d to %d badness %f < %f\n", startdir, enddir, |
150 | 179 | this_badness, min_badness); |
151 | 180 | */ |
152 | 181 | min_badness = this_badness; |
153 | 182 | if (best_layout != NULL) g_free(best_layout); |
154 | - best_layout = autolayout_unnormalize_points(startdir, startpoint, | |
155 | - this_layout, | |
156 | - this_num_points); | |
183 | + best_layout = unnormalized; | |
157 | 184 | best_num_points = this_num_points; |
158 | 185 | /* revert adjusting start and end point */ |
159 | 186 | autolayout_adjust_for_arrow(&best_layout[0], startdir, |
160 | 187 | -conn->extra_spacing.start_trans); |
161 | 188 | autolayout_adjust_for_arrow(&best_layout[best_num_points-1], enddir, |
162 | 189 | -conn->extra_spacing.end_trans); |
190 | + best_intersects = intersects; | |
163 | 191 | } else { |
164 | - g_free(this_layout); | |
192 | + g_free(unnormalized); | |
165 | 193 | } |
166 | 194 | } |
167 | 195 | } |