Graphviz 12.0.1~dev.20240715.2254
Loading...
Searching...
No Matches
edges.c
Go to the documentation of this file.
1/*************************************************************************
2 * Copyright (c) 2011 AT&T Intellectual Property
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * https://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors: Details at https://graphviz.org
9 *************************************************************************/
10
11#include <neatogen/neato.h>
12#include <neatogen/mem.h>
13#include <neatogen/info.h>
14#include <neatogen/edges.h>
15#include <math.h>
16
17
18double pxmin, pxmax, pymin, pymax; /* clipping window */
19
20static int nedges;
22
23void edgeinit(void)
24{
25 freeinit(&efl, sizeof(Edge));
26 nedges = 0;
27}
28
30{
31 double dx, dy, adx, ady;
33
35
36 newedge->reg[0] = s1;
37 newedge->reg[1] = s2;
38 ref(s1);
39 ref(s2);
40 newedge->ep[0] = NULL;
41 newedge->ep[1] = NULL;
42
43 dx = s2->coord.x - s1->coord.x;
44 dy = s2->coord.y - s1->coord.y;
45 adx = fabs(dx);
46 ady = fabs(dy);
47 newedge->c =
48 s1->coord.x * dx + s1->coord.y * dy + (dx * dx + dy * dy) * 0.5;
49 if (adx > ady) {
50 newedge->a = 1.0;
51 newedge->b = dy / dx;
52 newedge->c /= dx;
53 } else {
54 newedge->b = 1.0;
55 newedge->a = dx / dy;
56 newedge->c /= dy;
57 };
58
59 newedge->edgenbr = nedges;
60 nedges += 1;
61 return (newedge);
62}
63
64
65static void doSeg(Edge * e, double x1, double y1, double x2, double y2)
66{
67 addVertex(e->reg[0], x1, y1);
68 addVertex(e->reg[0], x2, y2);
69 addVertex(e->reg[1], x1, y1);
70 addVertex(e->reg[1], x2, y2);
71}
72
73void clip_line(Edge * e)
74{
75 Site *s1, *s2;
76 double x1, x2, y1, y2;
77
78 if (e->a == 1.0 && e->b >= 0.0) {
79 s1 = e->ep[1];
80 s2 = e->ep[0];
81 } else {
82 s1 = e->ep[0];
83 s2 = e->ep[1];
84 }
85
86 if (e->a == 1.0) {
87 if (s1 != NULL) {
88 y1 = s1->coord.y;
89 if (y1 > pymax)
90 return;
91 else if (y1 >= pymin)
92 x1 = s1->coord.x;
93 else {
94 y1 = pymin;
95 x1 = e->c - e->b * y1;
96 }
97 } else {
98 y1 = pymin;
99 x1 = e->c - e->b * y1;
100 }
101
102 if (s2 != NULL) {
103 y2 = s2->coord.y;
104 if (y2 < pymin)
105 return;
106 else if (y2 <= pymax)
107 x2 = s2->coord.x;
108 else {
109 y2 = pymax;
110 x2 = e->c - e->b * y2;
111 }
112 } else {
113 y2 = pymax;
114 x2 = e->c - e->b * y2;
115 }
116
117 if ((x1 > pxmax && x2 > pxmax) || (x1 < pxmin && x2 < pxmin))
118 return;
119 if (x1 > pxmax) {
120 x1 = pxmax;
121 y1 = (e->c - x1) / e->b;
122 };
123 if (x1 < pxmin) {
124 x1 = pxmin;
125 y1 = (e->c - x1) / e->b;
126 };
127 if (x2 > pxmax) {
128 x2 = pxmax;
129 y2 = (e->c - x2) / e->b;
130 };
131 if (x2 < pxmin) {
132 x2 = pxmin;
133 y2 = (e->c - x2) / e->b;
134 };
135 } else {
136 if (s1 != NULL) {
137 x1 = s1->coord.x;
138 if (x1 > pxmax)
139 return;
140 else if (x1 >= pxmin)
141 y1 = s1->coord.y;
142 else {
143 x1 = pxmin;
144 y1 = e->c - e->a * x1;
145 }
146 } else {
147 x1 = pxmin;
148 y1 = e->c - e->a * x1;
149 }
150
151 if (s2 != NULL) {
152 x2 = s2->coord.x;
153 if (x2 < pxmin)
154 return;
155 else if (x2 <= pxmax)
156 y2 = s2->coord.y;
157 else {
158 x2 = pxmax;
159 y2 = e->c - e->a * x2;
160 }
161 } else {
162 x2 = pxmax;
163 y2 = e->c - e->a * x2;
164 }
165
166 if ((y1 > pymax && y2 > pymax) || (y1 < pymin && y2 < pymin))
167 return;
168 if (y1 > pymax) {
169 y1 = pymax;
170 x1 = (e->c - y1) / e->a;
171 };
172 if (y1 < pymin) {
173 y1 = pymin;
174 x1 = (e->c - y1) / e->a;
175 };
176 if (y2 > pymax) {
177 y2 = pymax;
178 x2 = (e->c - y2) / e->a;
179 };
180 if (y2 < pymin) {
181 y2 = pymin;
182 x2 = (e->c - y2) / e->a;
183 };
184 }
185
186 doSeg(e, x1, y1, x2, y2);
187}
188
189void endpoint(Edge * e, int lr, Site * s)
190{
191 e->ep[lr] = s;
192 ref(s);
193 if (e->ep[re - lr] == NULL)
194 return;
195 clip_line(e);
196 deref(e->reg[le]);
197 deref(e->reg[re]);
198 makefree(e, &efl);
199}
static Agobj_t * deref(Expr_t *pgm, Exnode_t *x, Exref_t *ref, Agobj_t *objp, Gpr_t *state)
Definition compile.c:278
static float dy
Definition draw.c:38
static float dx
Definition draw.c:37
static Agedge_t * newedge(Agraph_t *g, Agnode_t *t, Agnode_t *h, IDTYPE id)
Definition edge.c:194
double pymin
Definition edges.c:18
static void doSeg(Edge *e, double x1, double y1, double x2, double y2)
Definition edges.c:65
Edge * gvbisect(Site *s1, Site *s2)
Definition edges.c:29
void endpoint(Edge *e, int lr, Site *s)
Definition edges.c:189
static Freelist efl
Definition edges.c:21
double pymax
Definition edges.c:18
static int nedges
Definition edges.c:20
double pxmin
Definition edges.c:18
void edgeinit(void)
Definition edges.c:23
void clip_line(Edge *e)
Definition edges.c:73
double pxmax
Definition edges.c:18
#define le
Definition edges.h:26
#define re
Definition edges.h:27
node NULL
Definition grammar.y:149
void addVertex(Site *s, double x, double y)
Definition info.c:110
void * getfree(Freelist *)
Definition memory.c:60
void makefree(void *, Freelist *)
Definition memory.c:83
void freeinit(Freelist *, int)
Definition memory.c:41
NEATOPROCS_API void s1(graph_t *, node_t *)
Definition stuff.c:671
void ref(Site *v)
Definition site.c:59
Definition edges.h:19
Site * ep[2]
Definition edges.h:21
double b
Definition edges.h:20
double c
Definition edges.h:20
Site * reg[2]
Definition edges.h:22
double a
Definition edges.h:20
double x
Definition geometry.h:23
double y
Definition geometry.h:23
Definition site.h:22
Point coord
Definition site.h:23
Definition mem.h:21
Definition grammar.c:93