Graphviz 12.0.1~dev.20240716.0800
Loading...
Searching...
No Matches
hedges.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 <cgraph/alloc.h>
12#include <neatogen/mem.h>
13#include <neatogen/hedges.h>
14#include <common/render.h>
15#include <stdbool.h>
16
17#define DELETED -2
18
20
22static int ELhashsize;
24static int ntry, totalsearch;
25
26void ELcleanup(void)
27{
28 freeinit(&hfl, sizeof(**ELhash));
29 free(ELhash);
30 ELhash = NULL;
31}
32
33void ELinitialize(void)
34{
35 int i;
36
37 freeinit(&hfl, sizeof(**ELhash));
39 if (ELhash == NULL)
40 ELhash = gv_calloc(ELhashsize, sizeof(Halfedge *));
41 for (i = 0; i < ELhashsize; ++i)
42 ELhash[i] = NULL;
49 ELhash[0] = ELleftend;
51}
52
53
55{
56 Edge *e1, *e2, *e;
57 Halfedge *el;
58 double d, xint, yint;
59 bool right_of_site;
60 Site *v;
61
62 e1 = el1->ELedge;
63 e2 = el2->ELedge;
64 if (e1 == NULL || e2 == NULL)
65 return NULL;
66 if (e1->reg[1] == e2->reg[1])
67 return NULL;
68
69 d = e1->a * e2->b - e1->b * e2->a;
70 if (-1.0e-10 < d && d < 1.0e-10)
71 return NULL;
72
73 xint = (e1->c * e2->b - e2->c * e1->b) / d;
74 yint = (e2->c * e1->a - e1->c * e2->a) / d;
75
76 if (e1->reg[1]->coord.y < e2->reg[1]->coord.y ||
77 (e1->reg[1]->coord.y == e2->reg[1]->coord.y &&
78 e1->reg[1]->coord.x < e2->reg[1]->coord.x)) {
79 el = el1;
80 e = e1;
81 } else {
82 el = el2;
83 e = e2;
84 };
85 right_of_site = xint >= e->reg[1]->coord.x;
86 if ((right_of_site && el->ELpm == le) || (!right_of_site && el->ELpm == re))
87 return NULL;
88
89 v = getsite();
90 v->refcnt = 0;
91 v->coord.x = xint;
92 v->coord.y = yint;
93 return v;
94}
95
96/* returns 1 if p is to right of halfedge e */
97int right_of(Halfedge * el, Point * p)
98{
99 Edge *e;
100 Site *topsite;
101 int above, fast;
102 double dxp, dyp, dxs, t1, t2, t3, yl;
103
104 e = el->ELedge;
105 topsite = e->reg[1];
106 bool right_of_site = p->x > topsite->coord.x;
107 if (right_of_site && el->ELpm == le)
108 return 1;
109 if (!right_of_site && el->ELpm == re)
110 return 0;
111
112 if (e->a == 1.0) {
113 dyp = p->y - topsite->coord.y;
114 dxp = p->x - topsite->coord.x;
115 fast = 0;
116 if ((!right_of_site && e->b < 0.0) || (right_of_site && e->b >= 0.0)) {
117 above = dyp >= e->b * dxp;
118 fast = above;
119 } else {
120 above = p->x + p->y * e->b > e->c;
121 if (e->b < 0.0)
122 above = !above;
123 if (!above)
124 fast = 1;
125 };
126 if (!fast) {
127 dxs = topsite->coord.x - (e->reg[0])->coord.x;
128 above = e->b * (dxp * dxp - dyp * dyp) <
129 dxs * dyp * (1.0 + 2.0 * dxp / dxs + e->b * e->b);
130 if (e->b < 0.0)
131 above = !above;
132 };
133 } else { /*e->b==1.0 */
134 yl = e->c - e->a * p->x;
135 t1 = p->y - yl;
136 t2 = p->x - topsite->coord.x;
137 t3 = yl - topsite->coord.y;
138 above = t1 * t1 > t2 * t2 + t3 * t3;
139 };
140 return el->ELpm == le ? above : !above;
141}
142
143Halfedge *HEcreate(Edge * e, char pm)
144{
145 Halfedge *answer;
146 answer = getfree(&hfl);
147 answer->ELedge = e;
148 answer->ELpm = pm;
149 answer->PQnext = NULL;
150 answer->vertex = NULL;
151 answer->ELrefcnt = 0;
152 return answer;
153}
154
155
156void ELinsert(Halfedge * lb, Halfedge * new)
157{
158 new->ELleft = lb;
159 new->ELright = lb->ELright;
160 (lb->ELright)->ELleft = new;
161 lb->ELright = new;
162}
163
164/* Get entry from hash table, pruning any deleted nodes */
165static Halfedge *ELgethash(int b)
166{
167 Halfedge *he;
168
169 if (b < 0 || b >= ELhashsize)
170 return NULL;
171 he = ELhash[b];
172 if (he == NULL || he->ELedge != (Edge *) DELETED)
173 return he;
174
175/* Hash table points to deleted half edge. Patch as necessary. */
176 ELhash[b] = NULL;
177 if (--he->ELrefcnt == 0)
178 makefree(he, &hfl);
179 return NULL;
180}
181
183{
184 int i, bucket;
185 Halfedge *he;
186
187/* Use hash table to get close to desired halfedge */
188 bucket = (p->x - xmin) / deltax * ELhashsize;
189 if (bucket < 0)
190 bucket = 0;
191 if (bucket >= ELhashsize)
192 bucket = ELhashsize - 1;
193 he = ELgethash(bucket);
194 if (he == NULL) {
195 for (i = 1; ; ++i) {
196 if ((he = ELgethash(bucket - i)) != NULL)
197 break;
198 if ((he = ELgethash(bucket + i)) != NULL)
199 break;
200 };
201 totalsearch += i;
202 };
203 ++ntry;
204/* Now search linear list of halfedges for the corect one */
205 if (he == ELleftend || (he != ELrightend && right_of(he, p))) {
206 do {
207 he = he->ELright;
208 } while (he != ELrightend && right_of(he, p));
209 he = he->ELleft;
210 } else
211 do {
212 he = he->ELleft;
213 } while (he != ELleftend && !right_of(he, p));
214
215/* Update hash table and reference counts */
216 if (bucket > 0 && bucket < ELhashsize - 1) {
217 if (ELhash[bucket] != NULL)
218 --ELhash[bucket]->ELrefcnt;
219 ELhash[bucket] = he;
220 ++ELhash[bucket]->ELrefcnt;
221 };
222 return he;
223}
224
225
226/* This delete routine can't reclaim node, since pointers from hash
227 table may be present. */
229{
230 (he->ELleft)->ELright = he->ELright;
231 (he->ELright)->ELleft = he->ELleft;
232 he->ELedge = (Edge *) DELETED;
233}
234
235
237{
238 return he->ELright;
239}
240
242{
243 return he->ELleft;
244}
245
246
248{
249 if (he->ELedge == NULL)
250 return (bottomsite);
251 return he->ELpm == le ? he->ELedge->reg[le] : he->ELedge->reg[re];
252}
253
255{
256 if (he->ELedge == NULL)
257 return (bottomsite);
258 return he->ELpm == le ? he->ELedge->reg[re] : he->ELedge->reg[le];
259}
Memory allocation wrappers that exit on failure.
static void * gv_calloc(size_t nmemb, size_t size)
Definition alloc.h:26
#define le
Definition edges.h:26
#define re
Definition edges.h:27
double deltax
Definition geometry.c:16
double xmin
Definition geometry.c:15
int sqrt_nsites
Definition geometry.c:20
void free(void *)
node NULL
Definition grammar.y:149
static Halfedge ** ELhash
Definition hedges.c:23
Halfedge * ELright(Halfedge *he)
Definition hedges.c:236
static int ELhashsize
Definition hedges.c:22
static int ntry
Definition hedges.c:24
void ELinsert(Halfedge *lb, Halfedge *new)
Definition hedges.c:156
Halfedge * ELrightend
Definition hedges.c:19
Site * hintersect(Halfedge *el1, Halfedge *el2)
Definition hedges.c:54
static int totalsearch
Definition hedges.c:24
Halfedge * ELleftbnd(Point *p)
Definition hedges.c:182
Site * rightreg(Halfedge *he)
Definition hedges.c:254
void ELinitialize(void)
Definition hedges.c:33
Halfedge * ELleft(Halfedge *he)
Definition hedges.c:241
Halfedge * HEcreate(Edge *e, char pm)
Definition hedges.c:143
void ELcleanup(void)
Definition hedges.c:26
Halfedge * ELleftend
Definition hedges.c:19
#define DELETED
Definition hedges.c:17
static Halfedge * ELgethash(int b)
Definition hedges.c:165
int right_of(Halfedge *el, Point *p)
Definition hedges.c:97
void ELdelete(Halfedge *he)
Definition hedges.c:228
Site * leftreg(Halfedge *he)
Definition hedges.c:247
static Freelist hfl
Definition hedges.c:21
void * getfree(Freelist *)
Definition memory.c:60
void makefree(void *, Freelist *)
Definition memory.c:83
void freeinit(Freelist *, int)
Definition memory.c:41
pointf coord(node_t *n)
Definition utils.c:151
Site * getsite(void)
Definition site.c:29
Site * bottomsite
Definition site.c:17
Definition edges.h:19
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
Edge * ELedge
Definition hedges.h:22
struct Halfedge * PQnext
Definition hedges.h:27
char ELpm
Definition hedges.h:24
Site * vertex
Definition hedges.h:25
struct Halfedge * ELleft
Definition hedges.h:21
int ELrefcnt
Definition hedges.h:23
struct Halfedge * ELright
Definition hedges.h:21
double x
Definition geometry.h:23
double y
Definition geometry.h:23
Definition site.h:22
Point coord
Definition site.h:23
unsigned refcnt
Definition site.h:25
Definition mem.h:21
double x
Definition geom.h:29