/misc/src/release/graphviz-2.18-1/src/graphviz-2.18/lib/neatogen/edges.c

Go to the documentation of this file.
00001 /* $Id: edges.c,v 1.1.1.1 2004/12/23 04:05:11 ellson Exp $ $Revision: 1.1.1.1 $ */
00002 /* vim:set shiftwidth=4 ts=8: */
00003 
00004 /**********************************************************
00005 *      This software is part of the graphviz package      *
00006 *                http://www.graphviz.org/                 *
00007 *                                                         *
00008 *            Copyright (c) 1994-2004 AT&T Corp.           *
00009 *                and is licensed under the                *
00010 *            Common Public License, Version 1.0           *
00011 *                      by AT&T Corp.                      *
00012 *                                                         *
00013 *        Information and Software Systems Research        *
00014 *              AT&T Research, Florham Park NJ             *
00015 **********************************************************/
00016 
00017 #include "neato.h"
00018 #include "mem.h"
00019 #include "info.h"
00020 #include "edges.h"
00021 #include <math.h>
00022 
00023 
00024 double pxmin, pxmax, pymin, pymax;      /* clipping window */
00025 
00026 static int nedges;
00027 static Freelist efl;
00028 
00029 void edgeinit()
00030 {
00031     freeinit(&efl, sizeof(Edge));
00032     nedges = 0;
00033 }
00034 
00035 Edge *bisect(Site * s1, Site * s2)
00036 {
00037     double dx, dy, adx, ady;
00038     Edge *newedge;
00039 
00040     newedge = (Edge *) getfree(&efl);
00041 
00042     newedge->reg[0] = s1;
00043     newedge->reg[1] = s2;
00044     ref(s1);
00045     ref(s2);
00046     newedge->ep[0] = (Site *) NULL;
00047     newedge->ep[1] = (Site *) NULL;
00048 
00049     dx = s2->coord.x - s1->coord.x;
00050     dy = s2->coord.y - s1->coord.y;
00051     adx = dx > 0 ? dx : -dx;
00052     ady = dy > 0 ? dy : -dy;
00053     newedge->c =
00054         s1->coord.x * dx + s1->coord.y * dy + (dx * dx + dy * dy) * 0.5;
00055     if (adx > ady) {
00056         newedge->a = 1.0;
00057         newedge->b = dy / dx;
00058         newedge->c /= dx;
00059     } else {
00060         newedge->b = 1.0;
00061         newedge->a = dx / dy;
00062         newedge->c /= dy;
00063     };
00064 
00065     newedge->edgenbr = nedges;
00066 #ifdef STANDALONE
00067     out_bisector(newedge);
00068 #endif
00069     nedges += 1;
00070     return (newedge);
00071 }
00072 
00073 
00074 static void doSeg(Edge * e, double x1, double y1, double x2, double y2)
00075 {
00076     addVertex(e->reg[0], x1, y1);
00077     addVertex(e->reg[0], x2, y2);
00078     addVertex(e->reg[1], x1, y1);
00079     addVertex(e->reg[1], x2, y2);
00080 }
00081 
00082 void clip_line(Edge * e)
00083 {
00084     Site *s1, *s2;
00085     double x1, x2, y1, y2;
00086 
00087     if (e->a == 1.0 && e->b >= 0.0) {
00088         s1 = e->ep[1];
00089         s2 = e->ep[0];
00090     } else {
00091         s1 = e->ep[0];
00092         s2 = e->ep[1];
00093     }
00094 
00095     if (e->a == 1.0) {
00096         if (s1 != (Site *) NULL) {
00097             y1 = s1->coord.y;
00098             if (y1 > pymax)
00099                 return;
00100             else if (y1 >= pymin)
00101                 x1 = s1->coord.x;
00102             else {
00103                 y1 = pymin;
00104                 x1 = e->c - e->b * y1;
00105             }
00106         } else {
00107             y1 = pymin;
00108             x1 = e->c - e->b * y1;
00109         }
00110 
00111         if (s2 != (Site *) NULL) {
00112             y2 = s2->coord.y;
00113             if (y2 < pymin)
00114                 return;
00115             else if (y2 <= pymax)
00116                 x2 = s2->coord.x;
00117             else {
00118                 y2 = pymax;
00119                 x2 = e->c - e->b * y2;
00120             }
00121         } else {
00122             y2 = pymax;
00123             x2 = e->c - e->b * y2;
00124         }
00125 
00126         if (((x1 > pxmax) & (x2 > pxmax)) | ((x1 < pxmin) & (x2 < pxmin)))
00127             return;
00128         if (x1 > pxmax) {
00129             x1 = pxmax;
00130             y1 = (e->c - x1) / e->b;
00131         };
00132         if (x1 < pxmin) {
00133             x1 = pxmin;
00134             y1 = (e->c - x1) / e->b;
00135         };
00136         if (x2 > pxmax) {
00137             x2 = pxmax;
00138             y2 = (e->c - x2) / e->b;
00139         };
00140         if (x2 < pxmin) {
00141             x2 = pxmin;
00142             y2 = (e->c - x2) / e->b;
00143         };
00144     } else {
00145         if (s1 != (Site *) NULL) {
00146             x1 = s1->coord.x;
00147             if (x1 > pxmax)
00148                 return;
00149             else if (x1 >= pxmin)
00150                 y1 = s1->coord.y;
00151             else {
00152                 x1 = pxmin;
00153                 y1 = e->c - e->a * x1;
00154             }
00155         } else {
00156             x1 = pxmin;
00157             y1 = e->c - e->a * x1;
00158         }
00159 
00160         if (s2 != (Site *) NULL) {
00161             x2 = s2->coord.x;
00162             if (x2 < pxmin)
00163                 return;
00164             else if (x2 <= pxmax)
00165                 y2 = s2->coord.y;
00166             else {
00167                 x2 = pxmax;
00168                 y2 = e->c - e->a * x2;
00169             }
00170         } else {
00171             x2 = pxmax;
00172             y2 = e->c - e->a * x2;
00173         }
00174 
00175         if (((y1 > pymax) & (y2 > pymax)) | ((y1 < pymin) & (y2 < pymin)))
00176             return;
00177         if (y1 > pymax) {
00178             y1 = pymax;
00179             x1 = (e->c - y1) / e->a;
00180         };
00181         if (y1 < pymin) {
00182             y1 = pymin;
00183             x1 = (e->c - y1) / e->a;
00184         };
00185         if (y2 > pymax) {
00186             y2 = pymax;
00187             x2 = (e->c - y2) / e->a;
00188         };
00189         if (y2 < pymin) {
00190             y2 = pymin;
00191             x2 = (e->c - y2) / e->a;
00192         };
00193     }
00194 
00195     doSeg(e, x1, y1, x2, y2);
00196 #ifdef STANDALONE
00197     if (doPS)
00198         line(x1, y1, x2, y2);
00199 #endif
00200 }
00201 
00202 void endpoint(Edge * e, int lr, Site * s)
00203 {
00204     e->ep[lr] = s;
00205     ref(s);
00206     if (e->ep[re - lr] == (Site *) NULL)
00207         return;
00208     clip_line(e);
00209 #ifdef STANDALONE
00210     out_ep(e);
00211 #endif
00212     deref(e->reg[le]);
00213     deref(e->reg[re]);
00214     makefree(e, &efl);
00215 }

Generated on Mon Mar 31 19:03:27 2008 for Graphviz by  doxygen 1.5.1