Graphviz 13.1.3~dev.20250813.2319
Loading...
Searching...
No Matches
voronoi.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/mem.h>
12#include <neatogen/geometry.h>
13#include <neatogen/edges.h>
14#include <neatogen/hedges.h>
15#include <neatogen/heap.h>
16#include <neatogen/voronoi.h>
17#include <util/gv_math.h>
18
19void voronoi(Site *(*nextsite)(void *context), void *context) {
20 Site *newsite, *bot, *top, *p;
21 Site *v;
22 Point newintstar = {0};
23 char pm;
24 Halfedge *lbnd, *rbnd, *llbnd, *rrbnd, *bisector;
25 Edge *e;
26
27 edgeinit();
28 siteinit();
29 pq_t *pq = PQinitialize();
30 bottomsite = nextsite(context);
31 el_state_t st = {0};
32 ELinitialize(&st);
33
34 newsite = nextsite(context);
35 while (1) {
36 if (!PQempty(pq))
37 newintstar = PQ_min(pq);
38
39 if (newsite != NULL &&
40 (PQempty(pq) || newsite->coord.y < newintstar.y ||
41 (newsite->coord.y ==newintstar.y && newsite->coord.x < newintstar.x))) {
42 /* new site is smallest */
43 lbnd = ELleftbnd(&st, &newsite->coord);
44 rbnd = ELright(lbnd);
45 bot = rightreg(lbnd);
46 e = gvbisect(bot, newsite);
47 bisector = HEcreate(&st, e, le);
48 ELinsert(lbnd, bisector);
49 if ((p = hintersect(lbnd, bisector)) != NULL) {
50 PQdelete(pq, lbnd);
51 PQinsert(pq, lbnd, p, ngdist(p, newsite));
52 }
53 lbnd = bisector;
54 bisector = HEcreate(&st, e, re);
55 ELinsert(lbnd, bisector);
56 if ((p = hintersect(bisector, rbnd)) != NULL)
57 PQinsert(pq, bisector, p, ngdist(p, newsite));
58 newsite = nextsite(context);
59 } else if (!PQempty(pq)) {
60 /* intersection is smallest */
61 lbnd = PQextractmin(pq);
62 llbnd = ELleft(lbnd);
63 rbnd = ELright(lbnd);
64 rrbnd = ELright(rbnd);
65 bot = leftreg(lbnd);
66 top = rightreg(rbnd);
67 v = lbnd->vertex;
68 makevertex(v);
69 endpoint(lbnd->ELedge, lbnd->ELpm, v);
70 endpoint(rbnd->ELedge, rbnd->ELpm, v);
71 ELdelete(lbnd);
72 PQdelete(pq, rbnd);
73 ELdelete(rbnd);
74 pm = le;
75 if (bot->coord.y > top->coord.y) {
76 SWAP(&bot, &top);
77 pm = re;
78 }
79 e = gvbisect(bot, top);
80 bisector = HEcreate(&st, e, pm);
81 ELinsert(llbnd, bisector);
82 endpoint(e, re - pm, v);
83 deref(v);
84 if ((p = hintersect(llbnd, bisector)) != NULL) {
85 PQdelete(pq, llbnd);
86 PQinsert(pq, llbnd, p, ngdist(p, bot));
87 }
88 if ((p = hintersect(bisector, rrbnd)) != NULL) {
89 PQinsert(pq, bisector, p, ngdist(p, bot));
90 }
91 } else
92 break;
93 }
94
95 for (lbnd = ELright(st.leftend); lbnd != st.rightend;
96 lbnd = ELright(lbnd)) {
97 e = lbnd->ELedge;
98 clip_line(e);
99 }
100
101 ELcleanup(&st);
102
103 // `PQcleanup` relies on the number of sites, so should be discarded and
104 // at least every time we use `vAdjust`. See note in adjust.c:cleanup().
105 PQcleanup(pq);
106}
static Agobj_t * deref(Expr_t *pgm, Exnode_t *x, Exref_t *ref, Agobj_t *objp, Gpr_t *state)
Definition compile.c:202
Edge * gvbisect(Site *s1, Site *s2)
Definition edges.c:27
void endpoint(Edge *e, int lr, Site *s)
Definition edges.c:185
void edgeinit(void)
Definition edges.c:22
void clip_line(Edge *e)
Definition edges.c:69
#define le
Definition edges.h:31
#define re
Definition edges.h:32
node NULL
Definition grammar.y:181
Arithmetic helper functions.
#define SWAP(a, b)
Definition gv_math.h:131
Point PQ_min(pq_t *pq)
Definition heap.c:97
void PQcleanup(pq_t *pq)
Definition heap.c:115
bool PQempty(const pq_t *pq)
Definition heap.c:93
void PQdelete(pq_t *pq, Halfedge *he)
Definition heap.c:79
pq_t * PQinitialize(void)
Definition heap.c:122
Halfedge * PQextractmin(pq_t *pq)
Definition heap.c:108
void PQinsert(pq_t *pq, Halfedge *he, Site *v, double offset)
Definition heap.c:63
Halfedge * ELright(Halfedge *he)
Definition hedges.c:229
void ELcleanup(el_state_t *st)
Definition hedges.c:21
void ELinitialize(el_state_t *st)
Definition hedges.c:26
void ELinsert(Halfedge *lb, Halfedge *new)
Definition hedges.c:142
Site * hintersect(Halfedge *el1, Halfedge *el2)
Definition hedges.c:44
Site * rightreg(Halfedge *he)
Definition hedges.c:247
Halfedge * ELleft(Halfedge *he)
Definition hedges.c:234
Halfedge * ELleftbnd(el_state_t *st, Point *p)
Definition hedges.c:183
void ELdelete(Halfedge *he)
Definition hedges.c:221
Halfedge * HEcreate(el_state_t *st, Edge *e, char pm)
Definition hedges.c:132
Site * leftreg(Halfedge *he)
Definition hedges.c:240
static Agedge_t * top(edge_stack_t *sp)
Definition tred.c:73
double ngdist(Site *s, Site *t)
Definition site.c:34
void siteinit(void)
Definition site.c:22
Site * bottomsite
Definition site.c:17
void makevertex(Site *v)
Definition site.c:46
Definition edges.h:25
Edge * ELedge
Definition hedges.h:30
char ELpm
Definition hedges.h:31
Site * vertex
Definition hedges.h:32
double x
Definition geometry.h:29
double y
Definition geometry.h:29
Definition site.h:28
Point coord
Definition site.h:29
Halfedge * leftend
Definition hedges.h:41
Halfedge * rightend
Definition hedges.h:42
Definition heap.c:19
void voronoi(Site *(*nextsite)(void *context), void *context)
Definition voronoi.c:19