Graphviz 13.0.0~dev.20250204.0809
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
18void voronoi(Site *(*nextsite)(void *context), void *context) {
19 Site *newsite, *bot, *top, *temp, *p;
20 Site *v;
21 Point newintstar = {0};
22 char pm;
23 Halfedge *lbnd, *rbnd, *llbnd, *rrbnd, *bisector;
24 Edge *e;
25
26 edgeinit();
27 siteinit();
28 pq_t *pq = PQinitialize();
29 bottomsite = nextsite(context);
31
32 newsite = nextsite(context);
33 while (1) {
34 if (!PQempty(pq))
35 newintstar = PQ_min(pq);
36
37 if (newsite != NULL &&
38 (PQempty(pq) || newsite->coord.y < newintstar.y ||
39 (newsite->coord.y ==newintstar.y && newsite->coord.x < newintstar.x))) {
40 /* new site is smallest */
41 lbnd = ELleftbnd(&newsite->coord);
42 rbnd = ELright(lbnd);
43 bot = rightreg(lbnd);
44 e = gvbisect(bot, newsite);
45 bisector = HEcreate(e, le);
46 ELinsert(lbnd, bisector);
47 if ((p = hintersect(lbnd, bisector)) != NULL) {
48 PQdelete(pq, lbnd);
49 PQinsert(pq, lbnd, p, dist(p, newsite));
50 }
51 lbnd = bisector;
52 bisector = HEcreate(e, re);
53 ELinsert(lbnd, bisector);
54 if ((p = hintersect(bisector, rbnd)) != NULL)
55 PQinsert(pq, bisector, p, dist(p, newsite));
56 newsite = nextsite(context);
57 } else if (!PQempty(pq)) {
58 /* intersection is smallest */
59 lbnd = PQextractmin(pq);
60 llbnd = ELleft(lbnd);
61 rbnd = ELright(lbnd);
62 rrbnd = ELright(rbnd);
63 bot = leftreg(lbnd);
64 top = rightreg(rbnd);
65 v = lbnd->vertex;
66 makevertex(v);
67 endpoint(lbnd->ELedge, lbnd->ELpm, v);
68 endpoint(rbnd->ELedge, rbnd->ELpm, v);
69 ELdelete(lbnd);
70 PQdelete(pq, rbnd);
71 ELdelete(rbnd);
72 pm = le;
73 if (bot->coord.y > top->coord.y) {
74 temp = bot;
75 bot = top;
76 top = temp;
77 pm = re;
78 }
79 e = gvbisect(bot, top);
80 bisector = HEcreate(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, dist(p, bot));
87 }
88 if ((p = hintersect(bisector, rrbnd)) != NULL) {
89 PQinsert(pq, bisector, p, dist(p, bot));
90 }
91 } else
92 break;
93 }
94
95 for (lbnd = ELright(ELleftend); lbnd != ELrightend; lbnd = ELright(lbnd)) {
96 e = lbnd->ELedge;
97 clip_line(e);
98 }
99
100 // `PQcleanup` relies on the number of sites, so should be discarded and
101 // at least every time we use `vAdjust`. See note in adjust.c:cleanup().
102 PQcleanup(pq);
103}
static Agobj_t * deref(Expr_t *pgm, Exnode_t *x, Exref_t *ref, Agobj_t *objp, Gpr_t *state)
Definition compile.c:258
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:25
#define re
Definition edges.h:26
static double dist(int dim, double *x, double *y)
node NULL
Definition grammar.y:163
Point PQ_min(pq_t *pq)
Definition heap.c:88
void PQcleanup(pq_t *pq)
Definition heap.c:106
bool PQempty(const pq_t *pq)
Definition heap.c:84
void PQdelete(pq_t *pq, Halfedge *he)
Definition heap.c:70
pq_t * PQinitialize(void)
Definition heap.c:113
Halfedge * PQextractmin(pq_t *pq)
Definition heap.c:99
void PQinsert(pq_t *pq, Halfedge *he, Site *v, double offset)
Definition heap.c:54
Halfedge * ELright(Halfedge *he)
Definition hedges.c:233
void ELinsert(Halfedge *lb, Halfedge *new)
Definition hedges.c:155
Halfedge * ELrightend
Definition hedges.c:19
Site * hintersect(Halfedge *el1, Halfedge *el2)
Definition hedges.c:53
Halfedge * ELleftbnd(Point *p)
Definition hedges.c:181
Site * rightreg(Halfedge *he)
Definition hedges.c:251
void ELinitialize(void)
Definition hedges.c:32
Halfedge * ELleft(Halfedge *he)
Definition hedges.c:238
Halfedge * HEcreate(Edge *e, char pm)
Definition hedges.c:142
Halfedge * ELleftend
Definition hedges.c:19
void ELdelete(Halfedge *he)
Definition hedges.c:225
Site * leftreg(Halfedge *he)
Definition hedges.c:244
static Agedge_t * top(edge_stack_t *sp)
Definition tred.c:73
void siteinit(void)
Definition site.c:22
Site * bottomsite
Definition site.c:17
void makevertex(Site *v)
Definition site.c:46
Definition edges.h:19
Edge * ELedge
Definition hedges.h:22
char ELpm
Definition hedges.h:24
Site * vertex
Definition hedges.h:25
double x
Definition geometry.h:23
double y
Definition geometry.h:23
Definition site.h:22
Point coord
Definition site.h:23
Definition heap.c:19
void voronoi(Site *(*nextsite)(void *context), void *context)
Definition voronoi.c:18