Graphviz 13.0.0~dev.20241220.2304
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
21
22void edgeinit(void)
23{
24 freeinit(&efl, sizeof(Edge));
25}
26
28{
29 double dx, dy, adx, ady;
31
33
34 newedge->reg[0] = s1;
35 newedge->reg[1] = s2;
36 ref(s1);
37 ref(s2);
38 newedge->ep[0] = NULL;
39 newedge->ep[1] = NULL;
40
41 dx = s2->coord.x - s1->coord.x;
42 dy = s2->coord.y - s1->coord.y;
43 adx = fabs(dx);
44 ady = fabs(dy);
45 newedge->c =
46 s1->coord.x * dx + s1->coord.y * dy + (dx * dx + dy * dy) * 0.5;
47 if (adx > ady) {
48 newedge->a = 1.0;
49 newedge->b = dy / dx;
50 newedge->c /= dx;
51 } else {
52 newedge->b = 1.0;
53 newedge->a = dx / dy;
54 newedge->c /= dy;
55 };
56
57 return (newedge);
58}
59
60
61static void doSeg(Edge * e, double x1, double y1, double x2, double y2)
62{
63 addVertex(e->reg[0], x1, y1);
64 addVertex(e->reg[0], x2, y2);
65 addVertex(e->reg[1], x1, y1);
66 addVertex(e->reg[1], x2, y2);
67}
68
69void clip_line(Edge * e)
70{
71 Site *s1, *s2;
72 double x1, x2, y1, y2;
73
74 if (e->a == 1.0 && e->b >= 0.0) {
75 s1 = e->ep[1];
76 s2 = e->ep[0];
77 } else {
78 s1 = e->ep[0];
79 s2 = e->ep[1];
80 }
81
82 if (e->a == 1.0) {
83 if (s1 != NULL) {
84 y1 = s1->coord.y;
85 if (y1 > pymax)
86 return;
87 else if (y1 >= pymin)
88 x1 = s1->coord.x;
89 else {
90 y1 = pymin;
91 x1 = e->c - e->b * y1;
92 }
93 } else {
94 y1 = pymin;
95 x1 = e->c - e->b * y1;
96 }
97
98 if (s2 != NULL) {
99 y2 = s2->coord.y;
100 if (y2 < pymin)
101 return;
102 else if (y2 <= pymax)
103 x2 = s2->coord.x;
104 else {
105 y2 = pymax;
106 x2 = e->c - e->b * y2;
107 }
108 } else {
109 y2 = pymax;
110 x2 = e->c - e->b * y2;
111 }
112
113 if ((x1 > pxmax && x2 > pxmax) || (x1 < pxmin && x2 < pxmin))
114 return;
115 if (x1 > pxmax) {
116 x1 = pxmax;
117 y1 = (e->c - x1) / e->b;
118 };
119 if (x1 < pxmin) {
120 x1 = pxmin;
121 y1 = (e->c - x1) / e->b;
122 };
123 if (x2 > pxmax) {
124 x2 = pxmax;
125 y2 = (e->c - x2) / e->b;
126 };
127 if (x2 < pxmin) {
128 x2 = pxmin;
129 y2 = (e->c - x2) / e->b;
130 };
131 } else {
132 if (s1 != NULL) {
133 x1 = s1->coord.x;
134 if (x1 > pxmax)
135 return;
136 else if (x1 >= pxmin)
137 y1 = s1->coord.y;
138 else {
139 x1 = pxmin;
140 y1 = e->c - e->a * x1;
141 }
142 } else {
143 x1 = pxmin;
144 y1 = e->c - e->a * x1;
145 }
146
147 if (s2 != NULL) {
148 x2 = s2->coord.x;
149 if (x2 < pxmin)
150 return;
151 else if (x2 <= pxmax)
152 y2 = s2->coord.y;
153 else {
154 x2 = pxmax;
155 y2 = e->c - e->a * x2;
156 }
157 } else {
158 x2 = pxmax;
159 y2 = e->c - e->a * x2;
160 }
161
162 if ((y1 > pymax && y2 > pymax) || (y1 < pymin && y2 < pymin))
163 return;
164 if (y1 > pymax) {
165 y1 = pymax;
166 x1 = (e->c - y1) / e->a;
167 };
168 if (y1 < pymin) {
169 y1 = pymin;
170 x1 = (e->c - y1) / e->a;
171 };
172 if (y2 > pymax) {
173 y2 = pymax;
174 x2 = (e->c - y2) / e->a;
175 };
176 if (y2 < pymin) {
177 y2 = pymin;
178 x2 = (e->c - y2) / e->a;
179 };
180 }
181
182 doSeg(e, x1, y1, x2, y2);
183}
184
185void endpoint(Edge * e, int lr, Site * s)
186{
187 e->ep[lr] = s;
188 ref(s);
189 if (e->ep[re - lr] == NULL)
190 return;
191 clip_line(e);
192 deref(e->reg[le]);
193 deref(e->reg[re]);
194 makefree(e, &efl);
195}
static Agobj_t * deref(Expr_t *pgm, Exnode_t *x, Exref_t *ref, Agobj_t *objp, Gpr_t *state)
Definition compile.c:258
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:195
double pymin
Definition edges.c:18
static void doSeg(Edge *e, double x1, double y1, double x2, double y2)
Definition edges.c:61
Edge * gvbisect(Site *s1, Site *s2)
Definition edges.c:27
void endpoint(Edge *e, int lr, Site *s)
Definition edges.c:185
static Freelist efl
Definition edges.c:20
double pymax
Definition edges.c:18
double pxmin
Definition edges.c:18
void edgeinit(void)
Definition edges.c:22
void clip_line(Edge *e)
Definition edges.c:69
double pxmax
Definition edges.c:18
#define le
Definition edges.h:25
#define re
Definition edges.h:26
node NULL
Definition grammar.y:163
void addVertex(Site *s, double x, double y)
insert vertex into sorted list
Definition info.c:101
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