]> granicus.if.org Git - graphviz/commitdiff
Fix bugs in repositioning code;
authorerg <devnull@localhost>
Sat, 19 Apr 2008 05:09:44 +0000 (05:09 +0000)
committererg <devnull@localhost>
Sat, 19 Apr 2008 05:09:44 +0000 (05:09 +0000)
make topfish parameters available to the GUI

cmd/smyrna/gltemplate.c
cmd/smyrna/hier.c
cmd/smyrna/hier.h
cmd/smyrna/smyrnadefs.h
cmd/smyrna/topfisheyeview.c
cmd/smyrna/topfisheyeview.h
cmd/smyrna/topview.h
cmd/smyrna/viewport.c
lib/topfish/hierarchy.c
lib/topfish/hierarchy.h
lib/topfish/rescale_layout.c

index 5fc850bdde5504839ce5c774f2001b0eaff8186b..859202b8c7cbb1bf4f115c4794419fe68f4ebc4c 100755 (executable)
@@ -19,6 +19,7 @@
 #include "gui.h"
 #include "viewport.h"
 #include "topview.h"
+#include "topfisheyeview.h"
 #include "gltemplate.h"
 #include "glutils.h"
 #include "glexpose.h"
@@ -128,7 +129,7 @@ static void realize(GtkWidget * widget, gpointer data)
     GLfloat lmodel_ambient[] = { 0.2f, 0.2f, 0.2f, 1.0f };
     GLfloat local_view[] = { 0.0 };
 
-    charsmyrna_font;
+    char *smyrna_font;
 
 #ifdef WIN32
 #define SMYRNA_FONT "c:/arial.tga"
@@ -136,11 +137,11 @@ static void realize(GtkWidget * widget, gpointer data)
 // using -DSMYRNA_FONT from Makefile.am and configure.ac
 #endif
 
-    if ((smyrna_font = smyrnaPath ("gui/arial.tga"))) {
+    if ((smyrna_font = smyrnaPath("gui/arial.tga"))) {
        g_print("loading font....%i\n", fontLoad(smyrna_font));
-       free (smyrna_font);
-    }
-    else g_print("loading font....%i\n", fontLoad(SMYRNA_FONT));
+       free(smyrna_font);
+    } else
+       g_print("loading font....%i\n", fontLoad(SMYRNA_FONT));
 
   /*** OpenGL BEGIN ***/
     if (!gdk_gl_drawable_gl_begin(gldrawable, glcontext))
@@ -196,10 +197,13 @@ static gboolean configure_event(GtkWidget * widget,
     glLoadIdentity();
     if (view->w > view->h) {
        aspect = (float) view->w / (float) view->h;
-       glOrtho(-aspect * GL_VIEWPORT_FACTOR, aspect * GL_VIEWPORT_FACTOR, GL_VIEWPORT_FACTOR*-1, GL_VIEWPORT_FACTOR, -1500, 1500);
+       glOrtho(-aspect * GL_VIEWPORT_FACTOR, aspect * GL_VIEWPORT_FACTOR,
+               GL_VIEWPORT_FACTOR * -1, GL_VIEWPORT_FACTOR, -1500, 1500);
     } else {
        aspect = (float) view->h / (float) view->w;
-       glOrtho(GL_VIEWPORT_FACTOR*-1, GL_VIEWPORT_FACTOR, -aspect * GL_VIEWPORT_FACTOR, aspect * GL_VIEWPORT_FACTOR, -1500, 1500);
+       glOrtho(GL_VIEWPORT_FACTOR * -1, GL_VIEWPORT_FACTOR,
+               -aspect * GL_VIEWPORT_FACTOR, aspect * GL_VIEWPORT_FACTOR,
+               -1500, 1500);
     }
 
     glMatrixMode(GL_MODELVIEW);
@@ -253,15 +257,15 @@ static gboolean button_press_event(GtkWidget * widget,
     begin_y = (float) event->y;
 
     if (event->button == 3)    //right click
-               view->mouse.button = rightmousebutton;
+       view->mouse.button = rightmousebutton;
 
 
     if (event->button == 1)    //left click
     {
-               view->prevpanx = view->panx;
-               view->prevpany = view->pany;
-               view->mouse.mouse_down = 1;
-               view->mouse.button = leftmousebutton;
+       view->prevpanx = view->panx;
+       view->prevpany = view->pany;
+       view->mouse.mouse_down = 1;
+       view->mouse.button = leftmousebutton;
        if (GetOGLPosRef
            ((int) begin_x, (int) begin_y, &(view->GLx), &(view->GLy),
             &(view->GLz))) {
@@ -290,62 +294,60 @@ static gboolean button_release_event(GtkWidget * widget,
                                     GdkEventButton * event, gpointer data)
 {
     if (event->button == 1)    //left click release
+    {
+       if (glCompSetRelease
+           (view->Topview->topviewmenu, (int) event->x_root,
+            (int) event->y_root)) {
+           expose_event(view->drawing_area, NULL, NULL);
+       }
+       view->mouse.mouse_down = 0;
+       if ((view->mouse.mouse_mode == MM_RECTANGULAR_SELECT)
+           || (view->mouse.mouse_mode == MM_RECTANGULAR_X_SELECT)) {
+           if (view->GLx <= view->GLx2)
+               view->Selection.X = view->GLx;
+           else
+               view->Selection.X = view->GLx2;
+           if (view->GLy <= view->GLy2)
+               view->Selection.Y = view->GLy;
+           else
+               view->Selection.Y = view->GLy2;
+           view->Selection.W = view->GLx2 - view->GLx;
+           if (view->Selection.W < 0)
+               view->Selection.W = view->Selection.W * -1;
+           view->Selection.H = view->GLy2 - view->GLy;
+           if (view->Selection.H < 0)
+               view->Selection.H = view->Selection.H * -1;
+           if (view->mouse.mouse_mode == 4)
+               view->Selection.Type = 1;
+           else
+               view->Selection.Type = 2;
+           view->Selection.Active = 1;
+           expose_event(view->drawing_area, NULL, NULL);
+       }
+       if (view->mouse.mouse_mode == MM_MOVE) {
+           if (GD_TopView(view->g[view->activeGraph]) == 0)
+               move_nodes(view->g[view->activeGraph]);
+           else
+               move_TVnodes();
+       }
+
+       if ((view->mouse.mouse_mode == MM_FISHEYE_MAGNIFIER) || (view->mouse.mouse_mode == MM_MAGNIFIER))       //fisheye mag mouse release, stop distortion
        {
-               if (glCompSetRelease
-                       (view->Topview->topviewmenu, (int) event->x_root,
-                               (int) event->y_root))
-               {
-                       expose_event(view->drawing_area, NULL, NULL);
-               }
-               view->mouse.mouse_down = 0;
-               if ((view->mouse.mouse_mode == MM_RECTANGULAR_SELECT)
-                   || (view->mouse.mouse_mode == MM_RECTANGULAR_X_SELECT))
-               {
-                       if (view->GLx <= view->GLx2)
-                               view->Selection.X = view->GLx;
-                       else
-                               view->Selection.X = view->GLx2;
-                       if (view->GLy <= view->GLy2)
-                               view->Selection.Y = view->GLy;
-                       else
-                               view->Selection.Y = view->GLy2;
-                   view->Selection.W = view->GLx2 - view->GLx;
-                   if (view->Selection.W < 0)
-                               view->Selection.W = view->Selection.W * -1;
-                       view->Selection.H = view->GLy2 - view->GLy;
-                       if (view->Selection.H < 0)
-                               view->Selection.H = view->Selection.H * -1;
-                       if (view->mouse.mouse_mode == 4)
-                               view->Selection.Type = 1;
-                       else
-                               view->Selection.Type = 2;
-                       view->Selection.Active = 1;
-                       expose_event(view->drawing_area, NULL, NULL);
-               }
-               if (view->mouse.mouse_mode == MM_MOVE)
-               {
-                       if (GD_TopView(view->g[view->activeGraph]) == 0)
-                               move_nodes(view->g[view->activeGraph]);
-                       else
-                               move_TVnodes();
-               }
-
-               if ((view->mouse.mouse_mode == MM_FISHEYE_MAGNIFIER) || (view->mouse.mouse_mode == MM_MAGNIFIER))       //fisheye mag mouse release, stop distortion
-               {
-                       originate_distorded_coordinates(view->Topview);
-                       expose_event(view->drawing_area, NULL, NULL);
-               }
+           originate_distorded_coordinates(view->Topview);
+           expose_event(view->drawing_area, NULL, NULL);
        }
+    }
     if (event->button == 3)    //right click
-       {
-               if (view->Topview->is_top_fisheye)
-               {
-                       GetFixedOGLPoslocal((int) event->x, (int) event->y, view->GLDepth, &(view->GLx2),
-                      &(view->GLy2), &(view->GLz2));
-                       changetopologicalfisheyefocus(view->Topview,&view->GLx2,&view->GLy2,0,1);
-                       expose_event(view->drawing_area, NULL, NULL);
-               }
+    {
+       if (view->Topview->is_top_fisheye) {
+           GetFixedOGLPoslocal((int) event->x, (int) event->y,
+                               view->GLDepth, &(view->GLx2),
+                               &(view->GLy2), &(view->GLz2));
+           changetopfishfocus(view->Topview, &view->GLx2, &view->GLy2, 0,
+                              1);
+           expose_event(view->drawing_area, NULL, NULL);
        }
+    }
 
     dx = 0.0;
     dy = 0.0;
@@ -367,57 +369,56 @@ static gboolean motion_notify_event(GtkWidget * widget,
     char buf[50];
 
 
-       float gldx,gldy;
-       gboolean redraw = FALSE;
+    float gldx, gldy;
+    gboolean redraw = FALSE;
     dx = x - begin_x;
     dy = y - begin_y;
 
-       view->mouse.dx=dx;
-       view->mouse.dy=dy;
+    view->mouse.dx = dx;
+    view->mouse.dy = dy;
 
-       /*panning */
+    /*panning */
     if ((event->state & GDK_BUTTON1_MASK)
-       && (view->mouse.mouse_mode == MM_PAN))
-       {
-               if(glmotion_main(view,event,widget))
-                               redraw = TRUE;
-       }
-       /*rotating, only in 3d view */
-    if ((view->active_camera >=0)&&(view->mouse.mouse_mode==MM_ROTATE)&& (event->state & GDK_BUTTON1_MASK) )
-       {
-               if(glmotion_main(view,event,widget))
-                               redraw = TRUE;
-       }
+       && (view->mouse.mouse_mode == MM_PAN)) {
+       if (glmotion_main(view, event, widget))
+           redraw = TRUE;
+    }
+    /*rotating, only in 3d view */
+    if ((view->active_camera >= 0) && (view->mouse.mouse_mode == MM_ROTATE)
+       && (event->state & GDK_BUTTON1_MASK)) {
+       if (glmotion_main(view, event, widget))
+           redraw = TRUE;
+    }
     /*zooming */
     if ((event->state & GDK_BUTTON1_MASK)
        && (view->mouse.mouse_mode == MM_ZOOM)) {
        float x;
-       float real_zoom,old_zoom;
-       if(view->active_camera==-1)
-       {
-               old_zoom=view->zoom;
-               real_zoom=view->zoom + dx / 10 * (view->zoom * -1 / 20);
-       }
-       else
-       {
-               old_zoom=view->cameras[view->active_camera]->r;
-               real_zoom=(view->cameras[view->active_camera]->r + dx / 10 * (view->cameras[view->active_camera]->r  / 20))*-1;
+       float real_zoom, old_zoom;
+       if (view->active_camera == -1) {
+           old_zoom = view->zoom;
+           real_zoom = view->zoom + dx / 10 * (view->zoom * -1 / 20);
+       } else {
+           old_zoom = view->cameras[view->active_camera]->r;
+           real_zoom =
+               (view->cameras[view->active_camera]->r +
+                dx / 10 * (view->cameras[view->active_camera]->r / 20)) *
+               -1;
        }
 
        if (real_zoom > MAX_ZOOM)
-               real_zoom = (float) MAX_ZOOM;
+           real_zoom = (float) MAX_ZOOM;
        if (real_zoom < MIN_ZOOM)
            real_zoom = (float) MIN_ZOOM;
 
-       if(view->active_camera==-1)
-               view->zoom = real_zoom;
-       else{
-               view->cameras[view->active_camera]->r=real_zoom*-1;
+       if (view->active_camera == -1)
+           view->zoom = real_zoom;
+       else {
+           view->cameras[view->active_camera]->r = real_zoom * -1;
 
-       //pan adjsutment
+           //pan adjsutment
        }
-       view->panx=old_zoom*view->panx/real_zoom;
-       view->pany=old_zoom*view->pany/real_zoom;
+       view->panx = old_zoom * view->panx / real_zoom;
+       view->pany = old_zoom * view->pany / real_zoom;
 
        /*set label to new zoom value */
        x = ((float) 100.0 - (float) 1.0) * (view->zoom -
@@ -569,11 +570,11 @@ void create_window(GdkGLConfig * glconfig, GtkWidget * vbox)
                                 glconfig, NULL, TRUE, GDK_GL_RGBA_TYPE);
 
     gtk_widget_add_events(view->drawing_area,
-//  GDK_BUTTON_MOTION_MASK     = 1 << 4,
-                       GDK_BUTTON_MOTION_MASK |
-                       GDK_BUTTON1_MOTION_MASK |
+//  GDK_BUTTON_MOTION_MASK      = 1 << 4,
+                         GDK_BUTTON_MOTION_MASK |
+                         GDK_BUTTON1_MOTION_MASK |
                          GDK_BUTTON2_MOTION_MASK |
-                               GDK_BUTTON3_MOTION_MASK |
+                         GDK_BUTTON3_MOTION_MASK |
                          GDK_BUTTON_PRESS_MASK |
                          GDK_BUTTON_RELEASE_MASK |
                          GDK_VISIBILITY_NOTIFY_MASK);
@@ -599,12 +600,14 @@ void create_window(GdkGLConfig * glconfig, GtkWidget * vbox)
 
     /* Popup menu. */
 
- /*   menu = create_popup_menu(view->drawing_area);
+#if 0
+    menu = create_popup_menu(view->drawing_area);
 
     /* Signal handler */
-  /*  g_signal_connect_swapped(G_OBJECT(view->drawing_area),
+    g_signal_connect_swapped(G_OBJECT(view->drawing_area),
                             "button_press_event",
                             G_CALLBACK(button_press_event_popup_menu),
-                            menu);*/
+                            menu);
+#endif
 
 }
index 8dab2589a39b5ea544112d668a3089736c1320df..ffb3bcc49c71827c3f6ed007e542178f2aa953a6 100644 (file)
 *              AT&T Research, Florham Park NJ             *
 **********************************************************/
 
-
-#include <assert.h>
+#include "smyrnadefs.h"
 #include "hier.h"
 #include "memory.h"
 
-/* To use:
-  double* x_coords; // initial x coordinates
-  double* y_coords; // initial y coordinates
-  focus_t* fs;
-  int ne;
-  vtx_data* graph = makeGraph (topview*, &ne);
-  hierarchy = makeHier(topview->NodeCount, ne, graph, x_coords, y_coords);
-  freeGraph (graph);
-  fs = initFocus (topview->Nodecount); // create focus set
-
-  In loop, 
-    update fs.
-      For example, if user clicks mouse at (p.x,p.y) to pick a single new focus,
-        int closest_fine_node;
-        find_closest_active_node(hierarchy, p.x, p.y, &closest_fine_node);
-        fs->num_foci = 1;
-        fs->foci_nodes[0] = closest_fine_node;
-        fs->x_foci[0] = hierarchy->geom_graphs[cur_level][closest_fine_node].x_coord; 
-        fs->y_foci[0] = hierarchy->geom_graphs[cur_level][closest_fine_node].y_coord;
-      
-    set_active_levels(hierarchy, fs->foci_nodes, fs->num_foci);
-    positionAllItems(hierarchy, fs, parms)
-
-  When done:
-    release (hierarchy);
-*/
-
 /* scale_coords:
  */
 static void
@@ -93,7 +65,7 @@ scale_coords(double *x_coords, double *y_coords, int n,
     }
 }
 
-void positionAllItems(Hierarchy * hp, focus_t * fs, hierparms_t * parms)
+void positionAllItems(Hierarchy * hp, focus_t * fs, reposition_t* parms)
 {
     int i;
     int interval = 20;
@@ -104,6 +76,7 @@ void positionAllItems(Hierarchy * hp, focus_t * fs, hierparms_t * parms)
     double width = parms->width;
     double height = parms->height;
     double margin = parms->margin;
+    double distortion = parms->distortion;
 
     /* get all logical coordinates of active nodes */
     for (i = 0; i < hp->nvtxs[max_level]; i++) {
@@ -125,11 +98,11 @@ void positionAllItems(Hierarchy * hp, focus_t * fs, hierparms_t * parms)
        case Polar:
            rescale_layout_polar(x_coords, y_coords, fs->x_foci,
                                 fs->y_foci, fs->num_foci, counter,
-                                interval, width, height, margin);
+                                interval, width, height, margin, distortion);
            break;
        case Rectilinear:
            rescale_layout(x_coords, y_coords, counter, interval,
-                          width, height, margin);
+                          width, height, margin, distortion);
            break;
        case Scale:
            scale_coords(x_coords, y_coords, counter, width, height, margin);
@@ -149,53 +122,6 @@ void positionAllItems(Hierarchy * hp, focus_t * fs, hierparms_t * parms)
     free(y_coords);
 }
 
-vtx_data *makeGraph(topview * tv, int *nedges)
-{
-    int i;
-    int ne = tv->Edgecount;    /* upper bound */
-    int nv = tv->Nodecount;
-    vtx_data *graph = N_NEW(nv, vtx_data);
-    int *edges = N_NEW(2 * ne + nv, int);  /* reserve space for self loops */
-    float *ewgts = N_NEW(2 * ne + nv, float);
-    Agnode_t *np;
-    Agedge_t *ep;
-    Agraph_t *g = NULL;
-    int i_nedges;
-
-    ne = 0;
-    for (i = 0; i < nv; i++) {
-       graph[i].edges = edges++;       /* reserve space for the self loop */
-       graph[i].ewgts = ewgts++;
-#ifdef STYLES
-       graph[i].styles = NULL;
-#endif
-       i_nedges = 1;           /* one for the self */
-
-       np = tv->Nodes[i].Node;
-       if (!g)
-           g = agraphof(np);
-       for (ep = agfstedge(g, np); ep; ep = agnxtedge(g, ep, np)) {
-           Agnode_t *vp;
-           Agnode_t *tp = agtail(ep);
-           Agnode_t *hp = aghead(ep);
-           assert(hp != tp);
-           /* FIX: handle multiedges */
-           vp = (tp == np ? hp : tp);
-           ne++;
-           i_nedges++;
-           *edges++ = OD_TVRef(vp);
-           *ewgts++ = 1;
-       }
-
-       graph[i].nedges = i_nedges;
-       graph[i].edges[0] = i;
-       graph[i].ewgts[0] = 1 - i_nedges;
-    }
-    ne /= 2;                   /* each edge counted twice */
-    *nedges = ne;
-    return graph;
-}
-
 #ifdef DEBUG
 static void
 dumpG (int nn, vtx_data * graph)
@@ -241,7 +167,7 @@ dumpHier (Hierarchy* hier)
 #endif
 
 Hierarchy *makeHier(int nn, int ne, vtx_data * graph, double *x_coords,
-                   double *y_coords)
+                   double *y_coords, hierparms_t* parms)
 {
     vtx_data *delaunay;
     ex_vtx_data *geom_graph;
@@ -257,7 +183,7 @@ Hierarchy *makeHier(int nn, int ne, vtx_data * graph, double *x_coords,
     free(delaunay[0].edges);
     free(delaunay);
 
-    hp = create_hierarchy(graph, nn, ne, geom_graph, ngeom_edges, 20);
+    hp = create_hierarchy(graph, nn, ne, geom_graph, ngeom_edges, parms);
     free(geom_graph[0].edges);
     free(geom_graph);
 
@@ -281,3 +207,11 @@ focus_t *initFocus(int ncnt)
     fs->y_foci = N_NEW(ncnt, double);
     return fs;
 }
+
+void freeFocus(focus_t* fs)
+{
+    free (fs->foci_nodes);
+    free (fs->x_foci);
+    free (fs->y_foci);
+    free (fs);
+}
index 7fa407f956c32e002703ddc4beaf55ae3e1b9683..4b7735d755e099b4510baa136efa8f8e1da8025f 100644 (file)
@@ -17,7 +17,7 @@
 #define HIER_H
 
 #include "hierarchy.h"
-#include "topview.h"
+
 typedef struct {
     int num_foci;
     int *foci_nodes;  /* Nodes in real graph */ 
@@ -39,17 +39,20 @@ typedef struct {
 typedef enum {NoRescale, Scale, Polar, Rectilinear} RescaleType;
 
 typedef struct {
+/* First 5 must be set i rescale = Polar or Rectilinear */
     int width;      /* viewport width */
     int height;     /* viewport height */
     int margin;     /* viewport margin */
-    int graphSize;  /* viewport scale : 0 -- 100 */
+    int graphSize;  /* 0 -- 100: percent to shrink w x h */
+    double distortion;  /* default of 1.0 */  
     RescaleType rescale;
-} hierparms_t;
+} reposition_t;
 
-void positionAllItems(Hierarchy * hp, focus_t * fs, hierparms_t * parms);
-vtx_data *makeGraph(topview * tv, int *nedges);
+void positionAllItems(Hierarchy * hp, focus_t * fs, reposition_t* parms);
 Hierarchy *makeHier(int nnodes, int nedges, vtx_data *, double *,
-                   double *);
+                   double*, hierparms_t *);
+
 focus_t *initFocus(int ncnt);
+void freeFocus(focus_t* fs);
 
 #endif
index fddf4d59e4b42f83d1ff78826c7aba4225e1fd69..0c1e6c6e2692a166c378bdd00b2d8e0d472c7e68 100644 (file)
@@ -41,7 +41,7 @@
 #include <GL/glu.h>
 #include <gtk/gtkgl.h>
 #include "glcompset.h"
-#include "hierarchy.h"
+#include "hier.h"
 
 #define IS_TEST_MODE_ON                                                        0
 #define        DEFAULT_MAGNIFIER_WIDTH                                 300
@@ -79,7 +79,6 @@ typedef enum { nodshapedot,nodeshapecircle} node_shape;
 typedef enum { leftmousebutton,rightmousebutton,thirdmousebutton} clicked_mouse_button;
 typedef enum { MOUSE_ROTATE_X,MOUSE_ROTATE_Y,MOUSE_ROTATE_XY,MOUSE_ROTATE_Z} mouse_rotate_axis;
 
-
 typedef struct {
     float R;
     float G;
@@ -161,8 +160,6 @@ typedef struct _viewport_camera{
        cam_t type; //
 } viewport_camera;
 
-
-
 typedef struct {
     topview_node *Nodes;
     topview_edge *Edges;
@@ -173,7 +170,13 @@ typedef struct {
     topviewdata *TopviewData;
     void *customptr;
     Hierarchy *h;
-       int is_top_fisheye;     //1 draw hierarchy 0 draw regular topview
+    int is_top_fisheye;        //1 draw hierarchy 0 draw regular topview
+    focus_t* fs;
+    struct {
+       reposition_t repos;
+       levelparms_t level;
+       hierparms_t hier;
+    } parms;
 } topview;
 
 enum {
index a94c4058fbb01b5b8df211e7240d676250daa948..b824781c698b638e82fc068058bd198a112e8a98 100644 (file)
@@ -1,3 +1,17 @@
+/* vim:set shiftwidth=4 ts=8: */
+
+/**********************************************************
+*      This software is part of the graphviz package      *
+*                http://www.graphviz.org/                 *
+*                                                         *
+*            Copyright (c) 1994-2004 AT&T Corp.           *
+*                and is licensed under the                *
+*            Common Public License, Version 1.0           *
+*                      by AT&T Corp.                      *
+*                                                         *
+*        Information and Software Systems Research        *
+*              AT&T Research, Florham Park NJ             *
+**********************************************************/
 #include "topfisheyeview.h"
 
 #include "glTexFont.h"
 #include "viewportcamera.h"
 #include "draw.h"
 #include "selection.h"
+#include "assert.h"
 #include "hier.h"
 
 static double dist(double x1, double y1, double x2, double y2)
 {
     return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
 }
-static double dist3d(double x1, double y1,double z1, double x2, double y2,double z2)
+static double dist3d(double x1, double y1, double z1, double x2, double y2,
+                    double z2)
 {
-    return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)+(z1 - z2) * (z1 - z2));
+    return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) +
+               (z1 - z2) * (z1 - z2));
 }
 
 
@@ -73,33 +90,37 @@ void fisheye_polar(double x_focus, double y_focus, topview * t)
        }
     }
 }
-void fisheye_spherical(double x_focus, double y_focus,double z_focus, topview * t)
+void fisheye_spherical(double x_focus, double y_focus, double z_focus,
+                      topview * t)
 {
     int i;
     double distance, distorted_distance, ratio, range;
 
     range = 0;
     for (i = 1; i < t->Nodecount; i++) {
-       if (    point_within_sphere_with_coords((float) x_focus, (float) y_focus, (float)z_focus, (float) view->fmg.R
-                                                               ,t->Nodes[i].x, t->Nodes[i].y,t->Nodes[i].z))
-       {
-               
-               
+       if (point_within_sphere_with_coords
+           ((float) x_focus, (float) y_focus, (float) z_focus,
+            (float) view->fmg.R, t->Nodes[i].x, t->Nodes[i].y,
+            t->Nodes[i].z)) {
+
+
            range =
                MAX(range,
-                   dist3d(t->Nodes[i].x, t->Nodes[i].y,t->Nodes[i].z, x_focus, y_focus,z_focus));
+                   dist3d(t->Nodes[i].x, t->Nodes[i].y, t->Nodes[i].z,
+                          x_focus, y_focus, z_focus));
        }
     }
 
     for (i = 1; i < t->Nodecount; i++) {
 
 
-       if (
-                       point_within_sphere_with_coords((float) x_focus, (float) y_focus, (float)z_focus, (float) view->fmg.R
-                                                               ,t->Nodes[i].x, t->Nodes[i].y,t->Nodes[i].z))
-       {
+       if (point_within_sphere_with_coords
+           ((float) x_focus, (float) y_focus, (float) z_focus,
+            (float) view->fmg.R, t->Nodes[i].x, t->Nodes[i].y,
+            t->Nodes[i].z)) {
            distance =
-               dist3d(t->Nodes[i].x, t->Nodes[i].y,t->Nodes[i].z, x_focus, y_focus,z_focus);
+               dist3d(t->Nodes[i].x, t->Nodes[i].y, t->Nodes[i].z,
+                      x_focus, y_focus, z_focus);
            distorted_distance = G(distance / range) * range;
            if (distance != 0) {
                ratio = distorted_distance / distance;
@@ -126,134 +147,164 @@ void fisheye_spherical(double x_focus, double y_focus,double z_focus, topview *
     }
 }
 
+static vtx_data *makeGraph(topview * tv, int *nedges)
+{
+    int i;
+    int ne = tv->Edgecount;    /* upper bound */
+    int nv = tv->Nodecount;
+    vtx_data *graph = N_NEW(nv, vtx_data);
+    int *edges = N_NEW(2 * ne + nv, int);  /* reserve space for self loops */
+    float *ewgts = N_NEW(2 * ne + nv, float);
+    Agnode_t *np;
+    Agedge_t *ep;
+    Agraph_t *g = NULL;
+    int i_nedges;
+
+    ne = 0;
+    for (i = 0; i < nv; i++) {
+       graph[i].edges = edges++;       /* reserve space for the self loop */
+       graph[i].ewgts = ewgts++;
+#ifdef STYLES
+       graph[i].styles = NULL;
+#endif
+       i_nedges = 1;           /* one for the self */
+
+       np = tv->Nodes[i].Node;
+       if (!g)
+           g = agraphof(np);
+       for (ep = agfstedge(g, np); ep; ep = agnxtedge(g, ep, np)) {
+           Agnode_t *vp;
+           Agnode_t *tp = agtail(ep);
+           Agnode_t *hp = aghead(ep);
+           assert(hp != tp);
+           /* FIX: handle multiedges */
+           vp = (tp == np ? hp : tp);
+           ne++;
+           i_nedges++;
+           *edges++ = OD_TVRef(vp);
+           *ewgts++ = 1;
+       }
 
+       graph[i].nedges = i_nedges;
+       graph[i].edges[0] = i;
+       graph[i].ewgts[0] = 1 - i_nedges;
+    }
+    ne /= 2;                   /* each edge counted twice */
+    *nedges = ne;
+    return graph;
+}
 
 
-void prepare_topological_fisheye(topview * t)
-{
 /* To use:
-  double* x_coords; // initial x coordinates
-  double* y_coords; // initial y coordinates
-  focus_t* fs;
-  int ne;
-  vtx_data* graph = makeGraph (topview*, &ne);
-  hierarchy = makeHier(topview->NodeCount, ne, graph, x_coords, y_coords);
-  freeGraph (graph);
-  fs = initFocus (topview->Nodecount); // create focus set
-
-  In loop, 
-    update fs.
-      For example, if user clicks mouse at (p.x,p.y) to pick a single new focus,
-        int closest_fine_node;
-        find_closest_active_node(hierarchy, p.x, p.y, &closest_fine_node);
-        fs->num_foci = 1;
-        fs->foci_nodes[0] = closest_fine_node;
-        fs->x_foci[0] = hierarchy->geom_graphs[cur_level][closest_fine_node].x_coord; 
-        fs->y_foci[0] = hierarchy->geom_graphs[cur_level][closest_fine_node].y_coord;
-      
-    set_active_levels(hierarchy, fs->foci_nodes, fs->num_foci);
-    positionAllItems(hierarchy, fs, parms)
-
-  When done:
-    release (hierarchy);
-*/
-    double *x_coords = N_NEW(t->Nodecount,double);  // initial x coordinates
-    double *y_coords = N_NEW(t->Nodecount,double);  // initial y coordinates
+ * double* x_coords; // initial x coordinates
+ * double* y_coords; // initial y coordinates
+ * focus_t* fs;
+ * int ne;
+ * vtx_data* graph = makeGraph (topview*, &ne);
+ * hierarchy = makeHier(topview->NodeCount, ne, graph, x_coords, y_coords);
+ * freeGraph (graph);
+ * fs = initFocus (topview->Nodecount); // create focus set
+ */
+void prepare_topological_fisheye(topview* t)
+{
+    double *x_coords = N_NEW(t->Nodecount, double);    // initial x coordinates
+    double *y_coords = N_NEW(t->Nodecount, double);    // initial y coordinates
     focus_t *fs;
     int ne;
     int i;
     int closest_fine_node;
-    int   cur_level = 0;
-    hierparms_t parms;
-    Hierarchy* hp;
-    ex_vtx_data* gg;
+    int cur_level = 0;
+    Hierarchy *hp;
+    ex_vtx_data *gg;
+    topview_node *np;
+    reposition_t parms;
 
-    topview_node* np;
     vtx_data *graph = makeGraph(t, &ne);
 
     for (i = 0, np = t->Nodes; i < t->Nodecount; i++, np++) {
-       x_coords[i] = np->x; 
-       y_coords[i] = np->y; 
-       }
-    hp = t->h = makeHier(t->Nodecount, ne, graph, x_coords, y_coords);
+       x_coords[i] = np->x;
+       y_coords[i] = np->y;
+    }
+    hp = t->h = 
+       makeHier(t->Nodecount, ne, graph, x_coords, y_coords, &(t->parms.hier));
     freeGraph(graph);
-    free (x_coords);
-    free (y_coords);
-    fs = initFocus(t->Nodecount);      // create focus set
+    free(x_coords);
+    free(y_coords);
+
+    fs = t->fs = initFocus(t->Nodecount);      // create focus set
     gg = hp->geom_graphs[0];
 
-/*
-    find_closest_active_node(hp, 465.966318,438.649967, &closest_fine_node);
-*/
-    closest_fine_node = 0;
-/* fprintf (stderr, "Closest node [%d] %s\n", closest_fine_node, agnameof(t->Nodes[closest_fine_node].Node)); */
+    closest_fine_node = 0; /* first node */
     fs->num_foci = 1;
     fs->foci_nodes[0] = closest_fine_node;
-    fs->x_foci[0] =
-       hp->geom_graphs[cur_level][closest_fine_node].x_coord;
-    fs->y_foci[0] =
-       hp->geom_graphs[cur_level][closest_fine_node].y_coord;
-
-    set_active_levels(hp, fs->foci_nodes, fs->num_foci);
-
-    parms.rescale = NoRescale;
-/*     parms.width=view->bdxRight-view->bdxLeft;
-       parms.height=view->bdyTop-view->bdyBottom;
-       parms.margin=0;
-       parms.graphSize=100;*/
+    fs->x_foci[0] = hp->geom_graphs[cur_level][closest_fine_node].x_coord;
+    fs->y_foci[0] = hp->geom_graphs[cur_level][closest_fine_node].y_coord;
+
+    set_active_levels(hp, fs->foci_nodes, fs->num_foci, &(t->parms.level));
+
+    parms.rescale = Polar;
+    parms.width=view->bdxRight-view->bdxLeft;
+    parms.height=view->bdyTop-view->bdyBottom;
+    parms.margin=0;
+    parms.graphSize=100;
+    parms.distortion=1.0;
     positionAllItems(hp, fs, &parms);
+    /* positionAllItems(hp, fs, &(t->parms.repos)); */
 /* fprintf (stderr, "No. of active nodes = %d\n", count_active_nodes(hp)); */
+
 }
 
-void drawtopologicalfisheye(topview* t)
+void drawtopologicalfisheye(topview * t)
 {
     int level, v, i, n;
-    Hierarchy* hp = t->h;
-
-       glPointSize(3);
-       glBegin(GL_POINTS);
-    for (level=0;level < hp->nlevels;level++) {
-       for (v=0;v < hp->nvtxs[level]; v++) {
-           ex_vtx_data* gg = hp->geom_graphs[level];
-           vtx_data* g = hp->graphs[level];
-           if(gg[v].active_level==level) {
+    Hierarchy *hp = t->h;
+
+    glPointSize(3);
+    glBegin(GL_POINTS);
+    for (level = 0; level < hp->nlevels; level++) {
+       for (v = 0; v < hp->nvtxs[level]; v++) {
+           ex_vtx_data *gg = hp->geom_graphs[level];
+           if (gg[v].active_level == level) {
                double x0 = gg[v].physical_x_coord;
                double y0 = gg[v].physical_y_coord;
-               glColor3f((GLfloat)(hp->nlevels-level)/(GLfloat)hp->nlevels,(GLfloat)level/(GLfloat)hp->nlevels,0);
-               glVertex3f((GLfloat)x0,(GLfloat)y0,(GLfloat)0);
+               glColor3f((GLfloat) (hp->nlevels - level) /
+                         (GLfloat) hp->nlevels,
+                         (GLfloat) level / (GLfloat) hp->nlevels, 0);
+               glVertex3f((GLfloat) x0, (GLfloat) y0, (GLfloat) 0);
            }
        }
     }
     glEnd();
 
-       
-       
-       
-       glBegin(GL_LINES);
-    for (level=0;level < hp->nlevels;level++) {
-       for (v=0;v < hp->nvtxs[level]; v++) {
-           ex_vtx_data* gg = hp->geom_graphs[level];
-           vtx_data* g = hp->graphs[level];
-           if(gg[v].active_level==level) {
+    glBegin(GL_LINES);
+    for (level = 0; level < hp->nlevels; level++) {
+       for (v = 0; v < hp->nvtxs[level]; v++) {
+           ex_vtx_data *gg = hp->geom_graphs[level];
+           vtx_data *g = hp->graphs[level];
+           if (gg[v].active_level == level) {
                double x0 = gg[v].physical_x_coord;
                double y0 = gg[v].physical_y_coord;
 
-               for (i=1;i < g[v].nedges;i++) {
-                   double x,y;
-                       n = g[v].edges[i];
-                       glColor3f((GLfloat)(hp->nlevels-level)/(GLfloat)hp->nlevels,(GLfloat)level/(GLfloat)hp->nlevels,0);
-                       if (gg[n].active_level == level) {
+               for (i = 1; i < g[v].nedges; i++) {
+                   double x, y;
+                   n = g[v].edges[i];
+                   glColor3f((GLfloat) (hp->nlevels - level) /
+                             (GLfloat) hp->nlevels,
+                             (GLfloat) level / (GLfloat) hp->nlevels, 0);
+                   if (gg[n].active_level == level) {
                        if (v < n) {
                            x = gg[n].physical_x_coord;
                            y = gg[n].physical_y_coord;
-                           glVertex3f((GLfloat)x0,(GLfloat)y0,(GLfloat)0);
-                           glVertex3f((GLfloat)x,(GLfloat)y,(GLfloat)0);
+                           glVertex3f((GLfloat) x0, (GLfloat) y0,
+                                      (GLfloat) 0);
+                           glVertex3f((GLfloat) x, (GLfloat) y,
+                                      (GLfloat) 0);
                        }
-                       }
-                   else if (gg[n].active_level > level) {
+                   } else if (gg[n].active_level > level) {
                        find_physical_coords(hp, level, n, &x, &y);
-                       glVertex3f((GLfloat)x0,(GLfloat)y0,(GLfloat)0);
-                       glVertex3f((GLfloat)x,(GLfloat)y,(GLfloat)0);
+                       glVertex3f((GLfloat) x0, (GLfloat) y0,
+                                  (GLfloat) 0);
+                       glVertex3f((GLfloat) x, (GLfloat) y, (GLfloat) 0);
                    }
                }
            }
@@ -261,55 +312,39 @@ void drawtopologicalfisheye(topview* t)
     }
     glEnd();
 }
-void changetopologicalfisheyefocus(topview* t,float* x,float* y,float* z,int num_foci)
-{
+
 /*  In loop,
-    update fs.
-      For example, if user clicks mouse at (p.x,p.y) to pick a single new focus,
-        int closest_fine_node;
-        find_closest_active_node(hierarchy, p.x, p.y, &closest_fine_node);
-        fs->num_foci = 1;
-        fs->foci_nodes[0] = closest_fine_node;
-        fs->x_foci[0] = 
-hierarchy->geom_graphs[cur_level][closest_fine_node].x_coord;
-        fs->y_foci[0] = 
-hierarchy->geom_graphs[cur_level][closest_fine_node].y_coord;
-
-    set_active_levels(hierarchy, fs->foci_nodes, fs->num_foci);
-    positionAllItems(hierarchy, fs, parms)*/
-
-       focus_t *fs;
-    int ne;
+ *  update fs.
+ *    For example, if user clicks mouse at (p.x,p.y) to pick a single new focus,
+ *      int closest_fine_node;
+ *      find_closest_active_node(hierarchy, p.x, p.y, &closest_fine_node);
+ *      fs->num_foci = 1;
+ *      fs->foci_nodes[0] = closest_fine_node;
+ *      fs->x_foci[0] = hierarchy->geom_graphs[cur_level][closest_fine_node].x_coord;
+ *      fs->y_foci[0] = hierarchy->geom_graphs[cur_level][closest_fine_node].y_coord;
+ *  set_active_levels(hierarchy, fs->foci_nodes, fs->num_foci);
+ *  positionAllItems(hierarchy, fs, parms)
+ */
+void changetopfishfocus(topview * t, float *x, float *y,
+                                  float *z, int num_foci)
+{
+    focus_t *fs = t->fs;
     int i;
     int closest_fine_node;
-    int   cur_level = 0;
-    hierparms_t parms;
-    Hierarchy* hp;
-
-//    ex_vtx_data* gg;
-
-    topview_node* np;
-       printf ("c(%f,%f)  z:%f\n",x[0],y[0],view->zoom);
-
-       hp = t->h;
-    fs = initFocus(t->Nodecount);      // create focus set
-//    gg = hp->geom_graphs[0];
-
-
-       fs->num_foci = num_foci;
-       for (i=0;i < num_foci;i++)
-       {
-           find_closest_active_node(hp, x[i],y[i], &closest_fine_node);
-               fs->foci_nodes[i] = closest_fine_node;
-               fs->x_foci[i] =
-               hp->geom_graphs[cur_level][closest_fine_node].x_coord;
-               fs->y_foci[i] =
-               hp->geom_graphs[cur_level][closest_fine_node].y_coord;
-       }
-
+    int cur_level = 0;
+    Hierarchy *hp = t->h;
+
+    fs->num_foci = num_foci;
+    for (i = 0; i < num_foci; i++) {
+       find_closest_active_node(hp, x[i], y[i], &closest_fine_node);
+       fs->foci_nodes[i] = closest_fine_node;
+       fs->x_foci[i] =
+           hp->geom_graphs[cur_level][closest_fine_node].x_coord;
+       fs->y_foci[i] =
+           hp->geom_graphs[cur_level][closest_fine_node].y_coord;
+    }
 
-       
-       set_active_levels(hp, fs->foci_nodes, fs->num_foci);
-    parms.rescale = NoRescale;
-    positionAllItems(hp, fs, &parms);
+    set_active_levels(hp, fs->foci_nodes, fs->num_foci, &(t->parms.level));
+    positionAllItems(hp, fs, &(t->parms.repos));
 }
+
index 2a0a786c47f39e53cac6c51d0657bfe24d39c816..a33808633599140aa32dd34babf296f4c713a3d2 100644 (file)
@@ -1,10 +1,28 @@
+/* vim:set shiftwidth=4 ts=8: */
+
+/**********************************************************
+*      This software is part of the graphviz package      *
+*                http://www.graphviz.org/                 *
+*                                                         *
+*            Copyright (c) 1994-2004 AT&T Corp.           *
+*                and is licensed under the                *
+*            Common Public License, Version 1.0           *
+*                      by AT&T Corp.                      *
+*                                                         *
+*        Information and Software Systems Research        *
+*              AT&T Research, Florham Park NJ             *
+**********************************************************/
 #ifndef TOPFISHEYEVIEW_H
 #define TOPFISHEYEVIEW_H
+
 #include "smyrnadefs.h"
+#include "hier.h"
 
 void fisheye_polar(double x_focus, double y_focus, topview * t);
-void fisheye_spherical(double x_focus, double y_focus,double z_focus, topview * t);
-void prepare_topological_fisheye(topview * t);
+void fisheye_spherical(double x_focus, double y_focus, double z_focus,
+                      topview * t);
+void prepare_topological_fisheye(topview*);
 void drawtopologicalfisheye(topview * t);
-void changetopologicalfisheyefocus(topview* t,float* x,float* y,float* z,int num_foci);
-#endif 
+void changetopfishfocus(topview * t, float *x, float *y,
+                                  float *z, int num_foci);
+#endif
index aa18e52d21c44b39c06eaa273591693f3a1dc2a8..4aa1482d57c17c11587f9f0b64a809f05e117369 100755 (executable)
@@ -17,7 +17,6 @@
 #ifndef TOPVIEW_H
 #define TOPVIEW_H
 
-
 #include "smyrnadefs.h"
 #ifdef WIN32                   //this is needed on WIN32 to get libglade see the callback
 #define _BB  __declspec(dllexport)
index 99cc3fe7979ac3c971c6f61d5a5cd83c7e69b879..27afac81a40aed9d813b7cdcd4054fe0c1f1aa1e 100755 (executable)
@@ -337,6 +337,15 @@ void init_viewport(ViewInfo * view)
     view->Selection.SelectionColor.A = 1;
     view->Selection.Anti = 0;
     view->Topview = GNEW(topview);
+    view->Topview->fs = 0;
+
+    /* init topfish parameters */
+    view->Topview->parms.level.num_fine_nodes = 50;
+    view->Topview->parms.level.coarsening_rate = 2.5;
+    view->Topview->parms.hier.dist2_limit = 1;
+    view->Topview->parms.hier.min_nvtxs = 20;
+    view->Topview->parms.repos.rescale = NoRescale;
+
     view->Topview->topviewmenu = '\0';
        view->cameras='\0';;
        view->camera_count=0;
index 9978eaa324b7a7f82fed9b401c502b0e84606946..f4fafb971d895a654163a1b079aa0681d4b51a84 100644 (file)
 #include "hierarchy.h"
 
 static int cur_level = 0;
-static int num_fine_nodes = 50;
-static double coarsening_rate = 2.5;
-static int dist2_limit = 1;    // don't contract nodes of distance larger than 2
-                           // if 'false' then also distance 3 is possible
 
 /////////////////////////
 // Some utilities for  //
@@ -147,7 +143,8 @@ static int
 maxmatch(vtx_data * graph,     /* array of vtx data for graph */
        ex_vtx_data * geom_graph,       /* array of vtx data for graph */
        int nvtxs,      /* number of vertices in graph */
-       int *mflag      /* flag indicating vtx selected or not */
+       int *mflag,     /* flag indicating vtx selected or not */
+       int dist2_limit
     )
 /* 
     Compute a matching of the nodes set. 
@@ -682,7 +679,8 @@ coarsen_match (
     int *cnedges,      /* number of edges in coarsened graph */
     int *cgeom_nedges, /* number of edges in coarsened geom_graph */
     int **v2cvp,       /* reference from vertices to coarse vertices */
-    int **cv2vp        /* reference from vertices to coarse vertices */
+    int **cv2vp,       /* reference from vertices to coarse vertices */
+    int dist2_limit
 )
 
 /*
@@ -701,7 +699,7 @@ coarsen_match (
     mflag = N_NEW(nvtxs, int);
 
     /* Find a maximal matching in the graphs */
-    nmerged = maxmatch(graph, geom_graph, nvtxs, mflag);
+    nmerged = maxmatch(graph, geom_graph, nvtxs, mflag, dist2_limit);
 
     /* Now construct coarser graph by contracting along matching edges. */
     /* Pairs of values in mflag array indicate matched vertices. */
@@ -836,7 +834,7 @@ static ex_vtx_data *cpExGraph(ex_vtx_data * graph, int n, int nedges)
 
 Hierarchy *create_hierarchy(vtx_data * graph, int nvtxs, int nedges,
                            ex_vtx_data * geom_graph, int ngeom_edges,
-                           int min_nvtxs)
+                           hierparms_t* parms)
 {
     int cur_level;
     Hierarchy *hierarchy = NEW(Hierarchy);
@@ -844,6 +842,7 @@ Hierarchy *create_hierarchy(vtx_data * graph, int nvtxs, int nedges,
     ex_vtx_data *geom_graph_level;
     int nodeIndex = 0;
     int i, j;
+    int min_nvtxs = parms->min_nvtxs;
     int nlevels = MAX(5, 10 * (int) log((float) (nvtxs / min_nvtxs))); // just an estimate
 
     hierarchy->graphs = N_NEW(nlevels, vtx_data *);
@@ -882,7 +881,8 @@ Hierarchy *create_hierarchy(vtx_data * graph, int nvtxs, int nedges,
             &hierarchy->geom_graphs[cur_level + 1],
             &hierarchy->nvtxs[cur_level + 1],
             &hierarchy->nedges[cur_level + 1], &cngeom_edges,
-            &hierarchy->v2cv[cur_level], &hierarchy->cv2v[cur_level + 1]);
+            &hierarchy->v2cv[cur_level], &hierarchy->cv2v[cur_level + 1],
+             parms->dist2_limit);
     }
 
     hierarchy->nlevels = cur_level + 1;
@@ -920,7 +920,8 @@ dist_from_foci(ex_vtx_data * graph, int node, int *foci, int num_foci)
  * If the active level equals the node's level then the node is currently shown
  */
 void
-set_active_levels(Hierarchy * hierarchy, int *foci_nodes, int num_foci)
+set_active_levels(Hierarchy * hierarchy, int *foci_nodes, int num_foci,
+    levelparms_t* parms)
 {
     int n, i;
     int *nodes;
@@ -954,13 +955,13 @@ set_active_levels(Hierarchy * hierarchy, int *foci_nodes, int num_foci)
      * factor: 'coarsening_rate'
      */
     level = min_level;
-    group_size = num_fine_nodes * num_foci;
+    group_size = parms->num_fine_nodes * num_foci;
     thresh = group_size;
     for (i = 0; i < n; i++) {
        vtx = nodes[i];
        if (i > thresh && level < hierarchy->nlevels - 1) {
            level++;
-           group_size = (int) (group_size * coarsening_rate);
+           group_size = (int) (group_size * parms->coarsening_rate);
            thresh += group_size;
        }
        graph[vtx].active_level = level;
index 88e4b12995ba90af8d6f1eddebc5284811028a04..acdfa558b98f0954b994f5a726acd239e733a1a4 100644 (file)
@@ -34,7 +34,6 @@ typedef struct {
     float physical_y_coord;    
 } ex_vtx_data;
 
-
 typedef struct {
     int nlevels;
     vtx_data ** graphs;
@@ -52,11 +51,24 @@ typedef struct {
     int maxNodeIndex;
 } Hierarchy;
 
+typedef struct {
+    int num_fine_nodes; /* 50 */
+    double coarsening_rate; /* 2.5 */
+} levelparms_t;
+
+typedef struct {
+    // if dist2_limit true, don't contract nodes of distance larger than 2
+    // if false then also distance 3 is possible
+    int dist2_limit; /* TRUE */
+    int min_nvtxs;   /* 20 */
+} hierparms_t;
+
 void release(Hierarchy*);
+
 Hierarchy* create_hierarchy(vtx_data * graph, int nvtxs, int nedges, 
-    ex_vtx_data* geom_graph, int ngeom_edges, int min_nvtxs);
+    ex_vtx_data* geom_graph, int ngeom_edges, hierparms_t*);
        
-void set_active_levels(Hierarchy*, int*, int);
+void set_active_levels(Hierarchy*, int*, int, levelparms_t*);
 double find_closest_active_node(Hierarchy*, double x, double y, int*);
 
 int extract_active_logical_coords(Hierarchy * hierarchy, int node, int level, 
@@ -78,10 +90,10 @@ vtx_data *UG_graph(double *x, double *y, int n, int accurate_computation);
 // layout distortion:
 void rescale_layout(double *x_coords, double *y_coords,
     int n, int interval, double width, double height,
-    double margin);
+    double margin, double distortion);
 void rescale_layout_polar(double * x_coords, double * y_coords, 
-    double * x_foci, double * y_foci, int num_foci,
-    int n, int interval, double width, double height, double margin);
+    double * x_foci, double * y_foci, int num_foci, int n, int interval, 
+    double width, double height, double margin, double distortion);
 
 void find_physical_coords(Hierarchy*, int, int, double *x, double *y);
 int find_active_ancestor(Hierarchy*, int, int);
index c619f13533c4e4a6ea8a4f4851939e11721a2a5a..b5bfbebd44854207e7df74d4d39bd1d827893670 100644 (file)
@@ -37,8 +37,6 @@
 #include "memory.h"
 #include "arith.h"
 
-static double distortion_factor = 1.0;
-
 static double *compute_densities(vtx_data * graph, int n, double *x,
                                 double *y)
 {
@@ -196,7 +194,7 @@ void quicksort_place(double *place, int *ordering, int first, int last)
 
 static void
 rescaleLayout(vtx_data * graph, int n, double *x_coords, double *y_coords,
-             int interval)
+             int interval, double distortion)
 {
     // Rectlinear distortion - auxilliary function
     int i;
@@ -212,15 +210,15 @@ rescaleLayout(vtx_data * graph, int n, double *x_coords, double *y_coords,
     }
 
     // just to make milder behavior:
-    if (distortion_factor >= 0) {
-       factor = sqrt(distortion_factor);
+    if (distortion >= 0) {
+       factor = sqrt(distortion);
     } else {
-       factor = -sqrt(-distortion_factor);
+       factor = -sqrt(-distortion);
     }
 
     quicksort_place(x_coords, ordering, 0, n - 1);
     densities = recompute_densities(graph, n, x_coords, densities);
-    smooth_vec(densities, ordering, n, interval, smoothed_densities);
+    smoothed_densities = smooth_vec(densities, ordering, n, interval, smoothed_densities);
     cpvec(copy_coords, 0, n - 1, x_coords);
     for (i = 1; i < n; i++) {
        x_coords[ordering[i]] =
@@ -231,7 +229,7 @@ rescaleLayout(vtx_data * graph, int n, double *x_coords, double *y_coords,
 
     quicksort_place(y_coords, ordering, 0, n - 1);
     densities = recompute_densities(graph, n, y_coords, densities);
-    smooth_vec(densities, ordering, n, interval, smoothed_densities);
+    smoothed_densities = smooth_vec(densities, ordering, n, interval, smoothed_densities);
     cpvec(copy_coords, 0, n - 1, y_coords);
     for (i = 1; i < n; i++) {
        y_coords[ordering[i]] =
@@ -249,7 +247,7 @@ rescaleLayout(vtx_data * graph, int n, double *x_coords, double *y_coords,
 void
 rescale_layout(double *x_coords, double *y_coords,
               int n, int interval, double width, double height,
-              double margin)
+              double margin, double distortion)
 {
     // Rectlinear distortion - main function
     int i;
@@ -279,7 +277,7 @@ rescale_layout(double *x_coords, double *y_coords,
 
     // construct mutual neighborhood graph
     graph = UG_graph(x_coords, y_coords, n, 0);
-    rescaleLayout(graph, n, x_coords, y_coords, interval);
+    rescaleLayout(graph, n, x_coords, y_coords, interval, distortion);
     free(graph[0].edges);
     free(graph);
 
@@ -328,8 +326,8 @@ rescale_layout(double *x_coords, double *y_coords,
 
 static void
 rescale_layout_polarFocus(vtx_data * graph, int n,
-                         double *x_coords, double *y_coords,
-                         double x_focus, double y_focus, int interval)
+         double *x_coords, double *y_coords,
+         double x_focus, double y_focus, int interval, double distortion)
 {
     // Polar distortion - auxilliary function
     int i;
@@ -351,25 +349,24 @@ rescale_layout_polarFocus(vtx_data * graph, int n,
     quicksort_place(distances, ordering, 0, n - 1);
 
     densities = compute_densities(graph, n, x_coords, y_coords);
-    smooth_vec(densities, ordering, n, interval, smoothed_densities);
+    smoothed_densities = smooth_vec(densities, ordering, n, interval, smoothed_densities);
 
     // rescale distances
-    if (distortion_factor < 1.01 && distortion_factor > 0.99) {
+    if (distortion < 1.01 && distortion > 0.99) {
        for (i = 1; i < n; i++) {
            distances[ordering[i]] =
                distances[ordering[i - 1]] + (orig_distances[ordering[i]] -
                                              orig_distances[ordering
                                                             [i -
-                                                             1]]) /
-               smoothed_densities[ordering[i]];
+                                                             1]]) / smoothed_densities[ordering[i]];
        }
     } else {
        double factor;
        // just to make milder behavior:
-       if (distortion_factor >= 0) {
-           factor = sqrt(distortion_factor);
+       if (distortion >= 0) {
+           factor = sqrt(distortion);
        } else {
-           factor = -sqrt(-distortion_factor);
+           factor = -sqrt(-distortion);
        }
        for (i = 1; i < n; i++) {
            distances[ordering[i]] =
@@ -403,7 +400,7 @@ void
 rescale_layout_polar(double *x_coords, double *y_coords,
                     double *x_foci, double *y_foci, int num_foci,
                     int n, int interval, double width,
-                    double height, double margin)
+                    double height, double margin, double distortion)
 {
     // Polar distortion - main function
     int i;
@@ -436,7 +433,7 @@ rescale_layout_polar(double *x_coords, double *y_coords,
 
     if (num_foci == 1) {       // accelerate execution of most common case
        rescale_layout_polarFocus(graph, n, x_coords, y_coords, x_foci[0],
-                                 y_foci[0], interval);
+                                 y_foci[0], interval, distortion);
     } else {
        // average-based rescale
        double *final_x_coords = N_NEW(n, double);
@@ -450,7 +447,7 @@ rescale_layout_polar(double *x_coords, double *y_coords,
            cpvec(cp_x_coords, 0, n - 1, x_coords);
            cpvec(cp_y_coords, 0, n - 1, y_coords);
            rescale_layout_polarFocus(graph, n, cp_x_coords, cp_y_coords,
-                                     x_foci[i], y_foci[i], interval);
+                                     x_foci[i], y_foci[i], interval, distortion);
            scadd(final_x_coords, 0, n - 1, 1.0 / num_foci, cp_x_coords);
            scadd(final_y_coords, 0, n - 1, 1.0 / num_foci, cp_y_coords);
        }