|
Graphviz
2.29.20120524.0446
|
00001 /* $Id$ $Revision$ */ 00002 /* vim:set shiftwidth=4 ts=8: */ 00003 00004 /************************************************************************* 00005 * Copyright (c) 2011 AT&T Intellectual Property 00006 * All rights reserved. This program and the accompanying materials 00007 * are made available under the terms of the Eclipse Public License v1.0 00008 * which accompanies this distribution, and is available at 00009 * http://www.eclipse.org/legal/epl-v10.html 00010 * 00011 * Contributors: See CVS logs. Details at http://www.graphviz.org/ 00012 *************************************************************************/ 00013 00014 #include "mem.h" 00015 #include "geometry.h" 00016 #include "edges.h" 00017 #include "hedges.h" 00018 #include "heap.h" 00019 #include "voronoi.h" 00020 00021 00022 void voronoi(int triangulate, Site * (*nextsite) (void)) 00023 { 00024 Site *newsite, *bot, *top, *temp, *p; 00025 Site *v; 00026 Point newintstar; 00027 char pm; 00028 Halfedge *lbnd, *rbnd, *llbnd, *rrbnd, *bisector; 00029 Edge *e; 00030 00031 edgeinit(); 00032 siteinit(); 00033 PQinitialize(); 00034 bottomsite = (*nextsite) (); 00035 #ifdef STANDALONE 00036 out_site(bottomsite); 00037 #endif 00038 ELinitialize(); 00039 00040 newsite = (*nextsite) (); 00041 while (1) { 00042 if (!PQempty()) 00043 newintstar = PQ_min(); 00044 00045 if (newsite != (struct Site *) NULL && (PQempty() 00046 || newsite->coord.y < 00047 newintstar.y 00048 || (newsite->coord.y == 00049 newintstar.y 00050 && newsite->coord.x < 00051 newintstar.x))) { 00052 /* new site is smallest */ 00053 #ifdef STANDALONE 00054 out_site(newsite); 00055 #endif 00056 lbnd = ELleftbnd(&(newsite->coord)); 00057 rbnd = ELright(lbnd); 00058 bot = rightreg(lbnd); 00059 e = bisect(bot, newsite); 00060 bisector = HEcreate(e, le); 00061 ELinsert(lbnd, bisector); 00062 if ((p = hintersect(lbnd, bisector)) != (struct Site *) NULL) { 00063 PQdelete(lbnd); 00064 PQinsert(lbnd, p, dist(p, newsite)); 00065 } 00066 lbnd = bisector; 00067 bisector = HEcreate(e, re); 00068 ELinsert(lbnd, bisector); 00069 if ((p = hintersect(bisector, rbnd)) != (struct Site *) NULL) 00070 PQinsert(bisector, p, dist(p, newsite)); 00071 newsite = (*nextsite) (); 00072 } else if (!PQempty()) { 00073 /* intersection is smallest */ 00074 lbnd = PQextractmin(); 00075 llbnd = ELleft(lbnd); 00076 rbnd = ELright(lbnd); 00077 rrbnd = ELright(rbnd); 00078 bot = leftreg(lbnd); 00079 top = rightreg(rbnd); 00080 #ifdef STANDALONE 00081 out_triple(bot, top, rightreg(lbnd)); 00082 #endif 00083 v = lbnd->vertex; 00084 makevertex(v); 00085 endpoint(lbnd->ELedge, lbnd->ELpm, v); 00086 endpoint(rbnd->ELedge, rbnd->ELpm, v); 00087 ELdelete(lbnd); 00088 PQdelete(rbnd); 00089 ELdelete(rbnd); 00090 pm = le; 00091 if (bot->coord.y > top->coord.y) { 00092 temp = bot; 00093 bot = top; 00094 top = temp; 00095 pm = re; 00096 } 00097 e = bisect(bot, top); 00098 bisector = HEcreate(e, pm); 00099 ELinsert(llbnd, bisector); 00100 endpoint(e, re - pm, v); 00101 deref(v); 00102 if ((p = hintersect(llbnd, bisector)) != (struct Site *) NULL) { 00103 PQdelete(llbnd); 00104 PQinsert(llbnd, p, dist(p, bot)); 00105 } 00106 if ((p = hintersect(bisector, rrbnd)) != (struct Site *) NULL) { 00107 PQinsert(bisector, p, dist(p, bot)); 00108 } 00109 } else 00110 break; 00111 } 00112 00113 for (lbnd = ELright(ELleftend); lbnd != ELrightend; 00114 lbnd = ELright(lbnd)) { 00115 e = lbnd->ELedge; 00116 clip_line(e); 00117 #ifdef STANDALONE 00118 out_ep(e); 00119 #endif 00120 } 00121 }
1.7.5