[Date Prev ][Date Next ] [Thread Prev ][Thread Next ]
[Thread Index ]
[Date Index ]
[Author Index ]
Patch: Connection optimization
From : tino schwarze informatik tu-chemnitz de (Tino Schwarze)
To : dia-list gnome org
Subject : Patch: Connection optimization
Date : Tue, 21 May 2002 22:50:00 +0200
Hi there,
today I worked a bit with Dia. 0.88.1 had severe problems with finding
fonts (although they should are there). So I tried the CVS version.
Later on, I noticed what would be a great feature. Take the following
situation:
+------+ +-------+
| *----------* | (two rectangles connected by a line)
+------+ +-------+
If I move the left one to the right, I get:
+------+ +-------+
*-------------------------*
+------+ +-------+
Which I find rather annoying.
Therefore, I hacked around a bit (getting the concept of
ConnectionPoints, Connections and Handles right isn't that easy) and
produced the patch attached. It is more a proof-of-concept than a final
patch. An UI addition to enable/disable this behaviour (or maybe add
this as a property to the connection) is neccessary.
The patch only modifies the Connection object (and a small part of
connectionpoint_ops.c) - I think it should be factored out to be used by
other connection types as well (e.g. bezier, zig-zag). As I'm not
familiar with the Dia architecture, I could not find a suitable place.
Comments welcome!
Bye, Tino.
--
* LINUX - Where do you want to be tomorrow? *
http://www.tu-chemnitz.de/linux/tag/
Index: app/connectionpoint_ops.c
===================================================================
RCS file: /cvs/gnome/dia/app/connectionpoint_ops.c,v
retrieving revision 1.9
diff -u -r1.9 connectionpoint_ops.c
--- app/connectionpoint_ops.c 23 Mar 2001 14:29:48 -0000 1.9
+++ app/connectionpoint_ops.c 21 May 2002 20:29:22 -0000
@@ -107,7 +107,13 @@
if (connected_obj->handles[j]->connected_to == cp)
handle = connected_obj->handles[j];
}
- assert(handle!=NULL);
+ if (handle == NULL)
+ {
+ /* the connection point might have been altered by calling
+ move_handle below */
+ list = g_list_next(list);
+ continue;
+ }
object_add_updates(connected_obj, dia);
connected_obj->ops->move_handle(connected_obj, handle ,
Index: lib/connection.c
===================================================================
RCS file: /cvs/gnome/dia/lib/connection.c,v
retrieving revision 1.9
diff -u -r1.9 connection.c
--- lib/connection.c 26 May 2001 01:11:48 -0000 1.9
+++ lib/connection.c 21 May 2002 20:29:23 -0000
@@ -24,6 +24,95 @@
#include "connection.h"
#include "message.h"
+static coord
+square_distance_point_point (Point p1, Point p2)
+{
+ const coord dx = p2.x - p1.x;
+ const coord dy = p2.y - p1.y;
+ return dx*dx+dy*dy;
+}
+
+
+static void
+optimize_connection (Connection* conn)
+{
+ ConnectionPoint* first_connpoint = conn->endpoint_handles[0].connected_to;
+ ConnectionPoint* second_connpoint = conn->endpoint_handles[1].connected_to;
+ ConnectionPoint* new_first_connpoint = first_connpoint;
+ ConnectionPoint* new_second_connpoint = second_connpoint;
+
+ Object* first_object;
+ Object* second_object;
+
+ ConnectionPoint** first_connections;
+ ConnectionPoint** second_connections;
+
+ coord min_distance;
+
+ int first_connection_num;
+
+ /* for now we only handle full connections */
+ if ( (first_connpoint == 0L)
+ || (second_connpoint == 0L))
+ return;
+
+ min_distance = square_distance_point_point (
+ first_connpoint->pos, second_connpoint->pos);
+
+ first_object = first_connpoint->object;
+ second_object = second_connpoint->object;
+
+ first_connections = first_object->connections;
+ second_connections = second_object->connections;
+
+ /* Now figure out the connections with the smallest distance.
+ This is O(n*m) - not optimal but we're only proofing a concept */
+ for (first_connection_num = 0; first_connection_num < first_object->num_connections; first_connection_num++)
+ {
+ int second_connection_num;
+
+ for (second_connection_num = 0; second_connection_num < second_object->num_connections; second_connection_num++)
+ {
+ const coord distance = square_distance_point_point (
+ first_connections[first_connection_num]->pos,
+ second_connections[second_connection_num]->pos);
+
+ if (distance < min_distance)
+ {
+ min_distance = distance;
+ new_first_connpoint = first_connections[first_connection_num];
+ new_second_connpoint = second_connections[second_connection_num];
+ }
+
+ }
+
+ }
+
+ if (new_first_connpoint != first_connpoint)
+ {
+ conn->endpoint_handles[0].connected_to = new_first_connpoint;
+
+ first_connpoint->connected = g_list_remove (first_connpoint->connected, conn);
+
+ new_first_connpoint->connected = g_list_prepend (new_first_connpoint->connected, conn);
+
+ conn->endpoints[0] = new_first_connpoint->pos;
+ }
+
+ if (new_second_connpoint != second_connpoint)
+ {
+ conn->endpoint_handles[1].connected_to = new_second_connpoint;
+
+ second_connpoint->connected = g_list_remove (second_connpoint->connected, conn);
+
+ new_second_connpoint->connected = g_list_prepend (new_second_connpoint->connected, conn);
+
+ conn->endpoints[1] = new_second_connpoint->pos;
+ }
+
+}
+
+
void
connection_move_handle(Connection *conn, HandleId id,
Point *to, HandleMoveReason reason)
@@ -39,11 +128,15 @@
message_error("Internal error in connection_move_handle.\n");
break;
}
+
+ optimize_connection (conn);
}
void
connection_update_handles(Connection *conn)
{
+ assert(conn != NULL);
+
conn->endpoint_handles[0].id = HANDLE_MOVE_STARTPOINT;
conn->endpoint_handles[0].pos = conn->endpoints[0];
[Date Prev ][Date Next ] [Thread Prev ][Thread Next ]
[Thread Index ]
[Date Index ]
[Author Index ]
Mail converted by Mofo Magic and the Flying D
All trademarks and copyrights are the property of
their respective owners.
Other Directory Sites:
SeekWonder |
Directory Owners Forum
GuideSMACK