par_bubbles.h 46 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343
  1. // BUBBLES :: https://github.com/prideout/par
  2. // Simple C library for packing circles into hierarchical (or flat) diagrams.
  3. //
  4. // Based on "Visualization of Large Hierarchical Data by Circle Packing" by
  5. // Wang et al (2006).
  6. //
  7. // Also implements Emo Welzl's "Smallest enclosing disks" algorithm (1991).
  8. //
  9. // The API is divided into three sections:
  10. //
  11. // - Enclosing. Compute the smallest bounding circle for points or circles.
  12. // - Packing. Pack circles together, or into other circles.
  13. // - Queries. Given a touch point, pick a circle from a hierarchy, etc.
  14. //
  15. // In addition to the comment block above each function declaration, the API
  16. // has informal documentation here:
  17. //
  18. // http://github.prideout.net/bubbles/
  19. //
  20. // The MIT License
  21. // Copyright (c) 2015 Philip Rideout
  22. #ifndef PAR_BUBBLES_H
  23. #define PAR_BUBBLES_H
  24. #ifdef __cplusplus
  25. extern "C" {
  26. #endif
  27. #include <stdbool.h>
  28. #include <stdint.h>
  29. // This can be any signed integer type.
  30. #ifndef PAR_BUBBLES_INT
  31. #define PAR_BUBBLES_INT int32_t
  32. #endif
  33. // This must be "float" or "double" or "long double". Note that you should not
  34. // need high precision if you use the relative coordinate systems API.
  35. #ifndef PAR_BUBBLES_FLT
  36. #define PAR_BUBBLES_FLT double
  37. #endif
  38. // Enclosing / Touching --------------------------------------------------------
  39. // Read an array of (x,y) coordinates, write a single 3-tuple (x,y,radius).
  40. void par_bubbles_enclose_points(PAR_BUBBLES_FLT const* xy, PAR_BUBBLES_INT npts,
  41. PAR_BUBBLES_FLT* result);
  42. // Read an array of 3-tuples (x,y,radius), write a 3-tuple (x,y,radius).
  43. // Internally, this approximates each disk with an enclosing octagon.
  44. void par_bubbles_enclose_disks(PAR_BUBBLES_FLT const* xyr,
  45. PAR_BUBBLES_INT ndisks, PAR_BUBBLES_FLT* result);
  46. // Find the circle (x,y,radius) that is tangent to 3 points (x,y).
  47. void par_bubbles_touch_three_points(PAR_BUBBLES_FLT const* xy,
  48. PAR_BUBBLES_FLT* result);
  49. // Find a position for disk "c" that makes it tangent to "a" and "b".
  50. // Note that the ordering of a and b can affect where c will land.
  51. // All three arguments are pointers to three-tuples (x,y,radius).
  52. void par_bubbles_touch_two_disks(PAR_BUBBLES_FLT* c, PAR_BUBBLES_FLT const* a,
  53. PAR_BUBBLES_FLT const* b);
  54. // Packing ---------------------------------------------------------------------
  55. // Tiny POD structure returned by all packing functions. Private data is
  56. // attached after the public fields, so clients should call the provided
  57. // free function rather than freeing the memory manually.
  58. typedef struct {
  59. PAR_BUBBLES_FLT* xyr; // array of 3-tuples (x y radius) in input order
  60. PAR_BUBBLES_INT count; // number of 3-tuples in "xyr"
  61. PAR_BUBBLES_INT* ids; // populated by par_bubbles_cull
  62. } par_bubbles_t;
  63. void par_bubbles_free_result(par_bubbles_t*);
  64. // Entry point for unbounded non-hierarchical packing. Takes a list of radii.
  65. par_bubbles_t* par_bubbles_pack(PAR_BUBBLES_FLT const* radiuses,
  66. PAR_BUBBLES_INT nradiuses);
  67. // Consume a hierarchy defined by a list of integers. Each integer is an index
  68. // to its parent. The root node is its own parent, and it must be the first node
  69. // in the list. Clients do not have control over individual radiuses, only the
  70. // radius of the outermost enclosing disk.
  71. par_bubbles_t* par_bubbles_hpack_circle(PAR_BUBBLES_INT* nodes,
  72. PAR_BUBBLES_INT nnodes, PAR_BUBBLES_FLT radius);
  73. // Queries ---------------------------------------------------------------------
  74. // Find the node at the given position. Children are on top of their parents.
  75. // If the result is -1, there is no node at the given pick coordinate.
  76. PAR_BUBBLES_INT par_bubbles_pick(par_bubbles_t const*, PAR_BUBBLES_FLT x,
  77. PAR_BUBBLES_FLT y);
  78. // Get bounding box; take a pointer to 4 floats and set them to min xy, max xy.
  79. void par_bubbles_compute_aabb(par_bubbles_t const*, PAR_BUBBLES_FLT* aabb);
  80. // Check if the given circle (3-tuple) intersects the given aabb (4-tuple).
  81. bool par_bubbles_check_aabb(PAR_BUBBLES_FLT const* disk,
  82. PAR_BUBBLES_FLT const* aabb);
  83. // Clip the bubble diagram to the given AABB (4-tuple of left,bottom,right,top)
  84. // and return the result. Circles smaller than the given world-space
  85. // "minradius" are removed. Optionally, an existing diagram (dst) can be passed
  86. // in to receive the culled dataset, which reduces the number of memory allocs
  87. // when calling this function frequently. Pass null to "dst" to create a new
  88. // culled diagram.
  89. par_bubbles_t* par_bubbles_cull(par_bubbles_t const* src,
  90. PAR_BUBBLES_FLT const* aabb, PAR_BUBBLES_FLT minradius, par_bubbles_t* dst);
  91. // Dump out a SVG file for diagnostic purposes.
  92. void par_bubbles_export(par_bubbles_t const* bubbles, char const* filename);
  93. // Returns a pointer to a list of children nodes.
  94. void par_bubbles_get_children(par_bubbles_t const* bubbles, PAR_BUBBLES_INT idx,
  95. PAR_BUBBLES_INT** pchildren, PAR_BUBBLES_INT* nchildren);
  96. // Returns the given node's parent, or 0 if it's the root.
  97. PAR_BUBBLES_INT par_bubbles_get_parent(par_bubbles_t const* bubbles,
  98. PAR_BUBBLES_INT idx);
  99. // Finds the height of the tree and returns one of its deepest leaves.
  100. void par_bubbles_get_maxdepth(par_bubbles_t const* bubbles,
  101. PAR_BUBBLES_INT* maxdepth, PAR_BUBBLES_INT* leaf);
  102. // Finds the height of the tree at a certain node.
  103. PAR_BUBBLES_INT par_bubbles_get_depth(par_bubbles_t const* bubbles,
  104. PAR_BUBBLES_INT node);
  105. // Returns a 4-tuple (min xy, max xy) for the given node.
  106. void par_bubbles_compute_aabb_for_node(par_bubbles_t const* bubbles,
  107. PAR_BUBBLES_INT node, PAR_BUBBLES_FLT* aabb);
  108. // Find the deepest node that is an ancestor of both A and B. Classic!
  109. PAR_BUBBLES_INT par_bubbles_lowest_common_ancestor(par_bubbles_t const* bubbles,
  110. PAR_BUBBLES_INT node_a, PAR_BUBBLES_INT node_b);
  111. // Relative Coordinate Systems -------------------------------------------------
  112. // Similar to hpack, but maintains precision by storing disk positions within
  113. // the local coordinate system of their parent. After calling this function,
  114. // clients can use cull_local to flatten the coordinate systems.
  115. par_bubbles_t* par_bubbles_hpack_local(PAR_BUBBLES_INT* nodes,
  116. PAR_BUBBLES_INT nnodes);
  117. // Similar to par_bubbles_cull, but takes a root node rather than an AABB,
  118. // and returns a result within the local coordinate system of the new root.
  119. // In other words, the new root will have radius 1, centered at (0,0). The
  120. // minradius is also expressed in this coordinate system.
  121. par_bubbles_t* par_bubbles_cull_local(par_bubbles_t const* src,
  122. PAR_BUBBLES_FLT const* aabb, PAR_BUBBLES_FLT minradius,
  123. PAR_BUBBLES_INT root, par_bubbles_t* dst);
  124. // Finds the smallest node in the given bubble diagram that completely encloses
  125. // the given axis-aligned bounding box (min xy, max xy). The AABB coordinates
  126. // are expressed in the local coordinate system of the given root node.
  127. PAR_BUBBLES_INT par_bubbles_find_local(par_bubbles_t const* src,
  128. PAR_BUBBLES_FLT const* aabb, PAR_BUBBLES_INT root);
  129. // Similar to pick, but expects (x,y) to be in the coordinate system of the
  130. // given root node.
  131. PAR_BUBBLES_INT par_bubbles_pick_local(par_bubbles_t const*, PAR_BUBBLES_FLT x,
  132. PAR_BUBBLES_FLT y, PAR_BUBBLES_INT root, PAR_BUBBLES_FLT minradius);
  133. // Obtains the scale and translation (which should be applied in that order)
  134. // that can move a point from the node0 coord system to the node1 coord system.
  135. // The "xform" argument should point to three floats, which will be populated
  136. // with: x translation, y translation, and scale.
  137. bool par_bubbles_transform_local(par_bubbles_t const* bubbles,
  138. PAR_BUBBLES_FLT* xform, PAR_BUBBLES_INT node0, PAR_BUBBLES_INT node1);
  139. // Dump out a SVG file for diagnostic purposes.
  140. void par_bubbles_export_local(par_bubbles_t const* bubbles,
  141. PAR_BUBBLES_INT idx, char const* filename);
  142. typedef enum {
  143. PAR_BUBBLES_FILTER_DEFAULT,
  144. PAR_BUBBLES_FILTER_DISCARD_LAST_CHILD,
  145. PAR_BUBBLES_FILTER_KEEP_ONLY_LAST_CHILD
  146. } par_bubbles_filter;
  147. // Special-case function that affects the behavior of subsequent calls to
  148. // cull_local. Allows clients to filter the children list of each non-leaf
  149. // node, which is especially useful when using placeholder bubbles for labels.
  150. void par_bubbles_set_filter(par_bubbles_t* src, par_bubbles_filter f);
  151. typedef enum {
  152. PAR_BUBBLES_HORIZONTAL,
  153. PAR_BUBBLES_VERTICAL
  154. } par_bubbles_orientation;
  155. // Sets some global state that affect subsequent calls to hpack. The first two
  156. // children can either be placed horizontally (default) or vertically. The
  157. // effect of this is subtle, since overall layout is obviously circular.
  158. void par_bubbles_set_orientation(par_bubbles_orientation );
  159. #ifndef PAR_PI
  160. #define PAR_PI (3.14159265359)
  161. #define PAR_MIN(a, b) (a > b ? b : a)
  162. #define PAR_MAX(a, b) (a > b ? a : b)
  163. #define PAR_CLAMP(v, lo, hi) PAR_MAX(lo, PAR_MIN(hi, v))
  164. #define PAR_SWAP(T, A, B) { T tmp = B; B = A; A = tmp; }
  165. #define PAR_SQR(a) ((a) * (a))
  166. #endif
  167. #ifndef PAR_MALLOC
  168. #define PAR_MALLOC(T, N) ((T*) malloc(N * sizeof(T)))
  169. #define PAR_CALLOC(T, N) ((T*) calloc(N * sizeof(T), 1))
  170. #define PAR_REALLOC(T, BUF, N) ((T*) realloc(BUF, sizeof(T) * (N)))
  171. #define PAR_FREE(BUF) free(BUF)
  172. #endif
  173. #ifdef __cplusplus
  174. }
  175. #endif
  176. // -----------------------------------------------------------------------------
  177. // END PUBLIC API
  178. // -----------------------------------------------------------------------------
  179. #ifdef PAR_BUBBLES_IMPLEMENTATION
  180. #define PARINT PAR_BUBBLES_INT
  181. #define PARFLT PAR_BUBBLES_FLT
  182. #include <math.h>
  183. #include <stdio.h>
  184. #include <stdlib.h>
  185. #include <float.h>
  186. #include <assert.h>
  187. static par_bubbles_orientation par_bubbles__ostate = PAR_BUBBLES_HORIZONTAL;
  188. typedef struct {
  189. PARINT prev;
  190. PARINT next;
  191. } par_bubbles__node;
  192. typedef struct {
  193. PARFLT* xyr; // results array
  194. PARINT count; // client-provided count
  195. PARINT* ids; // populated by par_bubbles_cull
  196. PARFLT const* radiuses; // client-provided radius list
  197. par_bubbles__node* chain; // counterclockwise enveloping chain
  198. PARINT const* graph_parents; // client-provided parent indices
  199. PARINT* graph_children; // flat list of children indices
  200. PARINT* graph_heads; // list of "pointers" to first child
  201. PARINT* graph_tails; // list of "pointers" to one-past-last child
  202. PARINT npacked;
  203. PARINT maxwidth;
  204. PARINT capacity;
  205. par_bubbles_filter filter;
  206. } par_bubbles__t;
  207. static PARFLT par_bubbles__len2(PARFLT const* a)
  208. {
  209. return a[0] * a[0] + a[1] * a[1];
  210. }
  211. static void par_bubbles__initgraph(par_bubbles__t* bubbles)
  212. {
  213. PARINT const* parents = bubbles->graph_parents;
  214. PARINT* nchildren = PAR_CALLOC(PARINT, bubbles->count);
  215. for (PARINT i = 0; i < bubbles->count; i++) {
  216. nchildren[parents[i]]++;
  217. }
  218. PARINT c = 0;
  219. bubbles->graph_heads = PAR_CALLOC(PARINT, bubbles->count * 2);
  220. bubbles->graph_tails = bubbles->graph_heads + bubbles->count;
  221. for (PARINT i = 0; i < bubbles->count; i++) {
  222. bubbles->maxwidth = PAR_MAX(bubbles->maxwidth, nchildren[i]);
  223. bubbles->graph_heads[i] = bubbles->graph_tails[i] = c;
  224. c += nchildren[i];
  225. }
  226. bubbles->graph_heads[0] = bubbles->graph_tails[0] = 1;
  227. bubbles->graph_children = PAR_MALLOC(PARINT, c);
  228. for (PARINT i = 1; i < bubbles->count; i++) {
  229. PARINT parent = parents[i];
  230. bubbles->graph_children[bubbles->graph_tails[parent]++] = i;
  231. }
  232. PAR_FREE(nchildren);
  233. }
  234. static void par_bubbles__initflat(par_bubbles__t* bubbles)
  235. {
  236. PARFLT* xyr = bubbles->xyr;
  237. PARFLT const* radii = bubbles->radiuses;
  238. par_bubbles__node* chain = bubbles->chain;
  239. PARFLT x0, y0, x1, y1;
  240. if (par_bubbles__ostate == PAR_BUBBLES_HORIZONTAL) {
  241. x0 = -radii[0];
  242. y0 = 0;
  243. x1 = radii[1];
  244. y1 = 0;
  245. } else {
  246. x0 = 0;
  247. y0 = -radii[0];
  248. x1 = 0;
  249. y1 = radii[1];
  250. }
  251. *xyr++ = x0;
  252. *xyr++ = y0;
  253. *xyr++ = *radii++;
  254. if (bubbles->count == ++bubbles->npacked) {
  255. return;
  256. }
  257. *xyr++ = x1;
  258. *xyr++ = y1;
  259. *xyr++ = *radii++;
  260. if (bubbles->count == ++bubbles->npacked) {
  261. return;
  262. }
  263. xyr[2] = *radii;
  264. par_bubbles_touch_two_disks(xyr, xyr - 6, xyr - 3);
  265. if (bubbles->count == ++bubbles->npacked) {
  266. return;
  267. }
  268. chain[0].prev = 2;
  269. chain[0].next = 1;
  270. chain[1].prev = 0;
  271. chain[1].next = 2;
  272. chain[2].prev = 1;
  273. chain[2].next = 0;
  274. }
  275. // March forward or backward along the enveloping chain, starting with the
  276. // node at "cn" and testing for collision against the node at "ci".
  277. static PARINT par_bubbles__collide(par_bubbles__t* bubbles, PARINT ci,
  278. PARINT cn, PARINT* cj, PARINT direction)
  279. {
  280. PARFLT const* ci_xyr = bubbles->xyr + ci * 3;
  281. par_bubbles__node* chain = bubbles->chain;
  282. PARINT nsteps = 1;
  283. if (direction > 0) {
  284. for (PARINT i = chain[cn].next; i != cn; i = chain[i].next, ++nsteps) {
  285. PARFLT const* i_xyr = bubbles->xyr + i * 3;
  286. PARFLT dx = i_xyr[0] - ci_xyr[0];
  287. PARFLT dy = i_xyr[1] - ci_xyr[1];
  288. PARFLT dr = i_xyr[2] + ci_xyr[2];
  289. if (0.999 * dr * dr > dx * dx + dy * dy) {
  290. *cj = i;
  291. return nsteps;
  292. }
  293. }
  294. return 0;
  295. }
  296. for (PARINT i = chain[cn].prev; i != cn; i = chain[i].prev, ++nsteps) {
  297. PARFLT const* i_xyr = bubbles->xyr + i * 3;
  298. PARFLT dx = i_xyr[0] - ci_xyr[0];
  299. PARFLT dy = i_xyr[1] - ci_xyr[1];
  300. PARFLT dr = i_xyr[2] + ci_xyr[2];
  301. if (0.999 * dr * dr > dx * dx + dy * dy) {
  302. *cj = i;
  303. return nsteps;
  304. }
  305. }
  306. return 0;
  307. }
  308. static void par_bubbles__packflat(par_bubbles__t* bubbles)
  309. {
  310. PARFLT const* radii = bubbles->radiuses;
  311. PARFLT* xyr = bubbles->xyr;
  312. par_bubbles__node* chain = bubbles->chain;
  313. // Find the circle closest to the origin, known as "Cm" in the paper.
  314. PARINT cm = 0;
  315. PARFLT mindist = par_bubbles__len2(xyr + 0);
  316. PARFLT dist = par_bubbles__len2(xyr + 3);
  317. if (dist > mindist) {
  318. cm = 1;
  319. }
  320. dist = par_bubbles__len2(xyr + 6);
  321. if (dist > mindist) {
  322. cm = 2;
  323. }
  324. // In the paper, "Cn" is always the node that follows "Cm".
  325. PARINT ci, cn = chain[cm].next;
  326. for (ci = bubbles->npacked; ci < bubbles->count; ) {
  327. PARFLT* ci_xyr = xyr + ci * 3;
  328. ci_xyr[2] = radii[ci];
  329. PARFLT* cm_xyr = xyr + cm * 3;
  330. PARFLT* cn_xyr = xyr + cn * 3;
  331. par_bubbles_touch_two_disks(ci_xyr, cn_xyr, cm_xyr);
  332. // Check for a collision. In the paper, "Cj" is the intersecting node.
  333. PARINT cj_f;
  334. PARINT nfsteps = par_bubbles__collide(bubbles, ci, cn, &cj_f, +1);
  335. if (!nfsteps) {
  336. chain[cm].next = ci;
  337. chain[ci].prev = cm;
  338. chain[ci].next = cn;
  339. chain[cn].prev = ci;
  340. cm = ci++;
  341. continue;
  342. }
  343. // Search backwards for a collision, in case it is closer.
  344. PARINT cj_b;
  345. PARINT nbsteps = par_bubbles__collide(bubbles, ci, cm, &cj_b, -1);
  346. // Intersection occurred after Cn.
  347. if (nfsteps <= nbsteps) {
  348. cn = cj_f;
  349. chain[cm].next = cn;
  350. chain[cn].prev = cm;
  351. continue;
  352. }
  353. // Intersection occurred before Cm.
  354. cm = cj_b;
  355. chain[cm].next = cn;
  356. chain[cn].prev = cm;
  357. }
  358. bubbles->npacked = bubbles->count;
  359. }
  360. static void par__disk_from_two(PARFLT const* xy1, PARFLT const* xy2,
  361. PARFLT* result)
  362. {
  363. PARFLT dx = xy1[0] - xy2[0];
  364. PARFLT dy = xy1[1] - xy2[1];
  365. result[0] = 0.5 * (xy1[0] + xy2[0]);
  366. result[1] = 0.5 * (xy1[1] + xy2[1]);
  367. result[2] = sqrt(dx * dx + dy * dy) / 2.0;
  368. }
  369. static PARINT par__disk_contains(PARFLT const* xyr, PARFLT const* xy)
  370. {
  371. PARFLT dx = xyr[0] - xy[0];
  372. PARFLT dy = xyr[1] - xy[1];
  373. return dx * dx + dy * dy <= PAR_SQR(xyr[2]);
  374. }
  375. static void par__easydisk(PARFLT* disk, PARFLT const* edgepts, PARINT nedgepts)
  376. {
  377. if (nedgepts == 0) {
  378. disk[0] = 0;
  379. disk[1] = 0;
  380. disk[2] = 0;
  381. return;
  382. }
  383. if (nedgepts == 1) {
  384. disk[0] = edgepts[0];
  385. disk[1] = edgepts[1];
  386. disk[2] = 0;
  387. return;
  388. }
  389. par__disk_from_two(edgepts, edgepts + 2, disk);
  390. if (nedgepts == 2 || par__disk_contains(disk, edgepts + 4)) {
  391. return;
  392. }
  393. par__disk_from_two(edgepts, edgepts + 4, disk);
  394. if (par__disk_contains(disk, edgepts + 2)) {
  395. return;
  396. }
  397. par__disk_from_two(edgepts + 2, edgepts + 4, disk);
  398. if (par__disk_contains(disk, edgepts)) {
  399. return;
  400. }
  401. par_bubbles_touch_three_points(edgepts, disk);
  402. }
  403. static void par__minidisk(PARFLT* disk, PARFLT const* pts, PARINT npts,
  404. PARFLT const* edgepts, PARINT nedgepts)
  405. {
  406. if (npts == 0 || nedgepts == 3) {
  407. par__easydisk(disk, edgepts, nedgepts);
  408. return;
  409. }
  410. PARFLT const* pt = pts + (--npts) * 2;
  411. par__minidisk(disk, pts, npts, edgepts, nedgepts);
  412. if (!par__disk_contains(disk, pt)) {
  413. PARFLT edgepts1[6];
  414. for (PARINT i = 0; i < nedgepts * 2; i += 2) {
  415. edgepts1[i] = edgepts[i];
  416. edgepts1[i + 1] = edgepts[i + 1];
  417. }
  418. edgepts1[2 * nedgepts] = pt[0];
  419. edgepts1[2 * nedgepts + 1] = pt[1];
  420. par__minidisk(disk, pts, npts, edgepts1, ++nedgepts);
  421. }
  422. }
  423. static void par_bubbles__copy_disk(par_bubbles__t const* src,
  424. par_bubbles__t* dst, PARINT parent)
  425. {
  426. PARINT i = dst->count++;
  427. if (dst->capacity < dst->count) {
  428. dst->capacity = PAR_MAX(16, dst->capacity) * 2;
  429. dst->xyr = PAR_REALLOC(PARFLT, dst->xyr, 3 * dst->capacity);
  430. dst->ids = PAR_REALLOC(PARINT, dst->ids, dst->capacity);
  431. }
  432. PARFLT const* xyr = src->xyr + parent * 3;
  433. dst->xyr[i * 3] = xyr[0];
  434. dst->xyr[i * 3 + 1] = xyr[1];
  435. dst->xyr[i * 3 + 2] = xyr[2];
  436. dst->ids[i] = parent;
  437. }
  438. void par_bubbles_enclose_points(PARFLT const* xy, PARINT npts, PARFLT* result)
  439. {
  440. if (npts == 0) {
  441. return;
  442. }
  443. par__minidisk(result, xy, npts, 0, 0);
  444. }
  445. void par_bubbles_enclose_disks(PARFLT const* xyr, PARINT ndisks, PARFLT* result)
  446. {
  447. PARINT ngon = 8;
  448. PARINT npts = ndisks * ngon;
  449. PARFLT* pts = PAR_MALLOC(PARFLT, npts * 2);
  450. PARFLT* ppts = pts;
  451. float dtheta = PAR_PI * 2.0 / ngon;
  452. for (PARINT i = 0; i < ndisks; i++) {
  453. PARFLT cx = xyr[i * 3];
  454. PARFLT cy = xyr[i * 3 + 1];
  455. PARFLT cr = xyr[i * 3 + 2];
  456. PARFLT a = 2.0 * cr / (1.0 + sqrt(2));
  457. PARFLT r = 0.5 * sqrt(2) * a * sqrt(2 + sqrt(2));
  458. float theta = 0;
  459. for (PARINT j = 0; j < ngon; j++, theta += dtheta) {
  460. *ppts++ = cx + r * cos(theta);
  461. *ppts++ = cy + r * sin(theta);
  462. }
  463. }
  464. par_bubbles_enclose_points(pts, npts, result);
  465. PAR_FREE(pts);
  466. }
  467. void par_bubbles_touch_three_points(PARFLT const* xy, PARFLT* xyr)
  468. {
  469. // Many thanks to Stephen Schmitts:
  470. // http://www.abecedarical.com/zenosamples/zs_circle3pts.html
  471. PARFLT p1x = xy[0], p1y = xy[1];
  472. PARFLT p2x = xy[2], p2y = xy[3];
  473. PARFLT p3x = xy[4], p3y = xy[5];
  474. PARFLT a = p2x - p1x, b = p2y - p1y;
  475. PARFLT c = p3x - p1x, d = p3y - p1y;
  476. PARFLT e = a * (p2x + p1x) * 0.5 + b * (p2y + p1y) * 0.5;
  477. PARFLT f = c * (p3x + p1x) * 0.5 + d * (p3y + p1y) * 0.5;
  478. PARFLT det = a*d - b*c;
  479. PARFLT cx = xyr[0] = (d*e - b*f) / det;
  480. PARFLT cy = xyr[1] = (-c*e + a*f) / det;
  481. xyr[2] = sqrt((p1x - cx)*(p1x - cx) + (p1y - cy)*(p1y - cy));
  482. }
  483. void par_bubbles_touch_two_disks(PARFLT* c, PARFLT const* a, PARFLT const* b)
  484. {
  485. PARFLT db = a[2] + c[2], dx = b[0] - a[0], dy = b[1] - a[1];
  486. if (db && (dx || dy)) {
  487. PARFLT da = b[2] + c[2], dc = dx * dx + dy * dy;
  488. da *= da;
  489. db *= db;
  490. PARFLT x = 0.5 + (db - da) / (2 * dc);
  491. PARFLT db1 = db - dc;
  492. PARFLT y0 = PAR_MAX(0, 2 * da * (db + dc) - db1 * db1 - da * da);
  493. PARFLT y = sqrt(y0) / (2 * dc);
  494. c[0] = a[0] + x * dx + y * dy;
  495. c[1] = a[1] + x * dy - y * dx;
  496. } else {
  497. c[0] = a[0] + db;
  498. c[1] = a[1];
  499. }
  500. }
  501. void par_bubbles_free_result(par_bubbles_t* pubbub)
  502. {
  503. par_bubbles__t* bubbles = (par_bubbles__t*) pubbub;
  504. PAR_FREE(bubbles->graph_children);
  505. PAR_FREE(bubbles->graph_heads);
  506. PAR_FREE(bubbles->chain);
  507. PAR_FREE(bubbles->xyr);
  508. PAR_FREE(bubbles->ids);
  509. PAR_FREE(bubbles);
  510. }
  511. par_bubbles_t* par_bubbles_pack(PARFLT const* radiuses, PARINT nradiuses)
  512. {
  513. par_bubbles__t* bubbles = PAR_CALLOC(par_bubbles__t, 1);
  514. if (nradiuses > 0) {
  515. bubbles->radiuses = radiuses;
  516. bubbles->count = nradiuses;
  517. bubbles->chain = PAR_MALLOC(par_bubbles__node, nradiuses);
  518. bubbles->xyr = PAR_MALLOC(PARFLT, 3 * nradiuses);
  519. par_bubbles__initflat(bubbles);
  520. par_bubbles__packflat(bubbles);
  521. }
  522. return (par_bubbles_t*) bubbles;
  523. }
  524. // Assigns a radius to every node according to its number of descendants.
  525. void par_bubbles__generate_radii(par_bubbles__t* bubbles,
  526. par_bubbles__t* worker, PARINT parent)
  527. {
  528. PARINT head = bubbles->graph_heads[parent];
  529. PARINT tail = bubbles->graph_tails[parent];
  530. PARINT nchildren = tail - head;
  531. PARINT pr = parent * 3 + 2;
  532. bubbles->xyr[pr] = 1;
  533. if (nchildren == 0) {
  534. return;
  535. }
  536. for (PARINT cindex = head; cindex != tail; cindex++) {
  537. PARINT child = bubbles->graph_children[cindex];
  538. par_bubbles__generate_radii(bubbles, worker, child);
  539. bubbles->xyr[pr] += bubbles->xyr[child * 3 + 2];
  540. }
  541. // The following square root seems to produce a nicer, more space-filling,
  542. // distribution of radiuses in randomly-generated trees.
  543. bubbles->xyr[pr] = sqrtf(bubbles->xyr[pr]);
  544. }
  545. void par_bubbles__hpack(par_bubbles__t* bubbles, par_bubbles__t* worker,
  546. PARINT parent, bool local)
  547. {
  548. PARINT head = bubbles->graph_heads[parent];
  549. PARINT tail = bubbles->graph_tails[parent];
  550. PARINT nchildren = tail - head;
  551. if (nchildren == 0) {
  552. return;
  553. }
  554. // Cast away const because we're using the worker as a cache to avoid
  555. // a kazillion malloc / free calls.
  556. PARFLT* radiuses = (PARFLT*) worker->radiuses;
  557. // We perform flat layout twice: once without padding (to determine scale)
  558. // and then again with scaled padding.
  559. PARFLT enclosure[3];
  560. PARFLT px = bubbles->xyr[parent * 3 + 0];
  561. PARFLT py = bubbles->xyr[parent * 3 + 1];
  562. PARFLT pr = bubbles->xyr[parent * 3 + 2];
  563. const PARFLT PAR_HPACK_PADDING1 = 0.15;
  564. const PARFLT PAR_HPACK_PADDING2 = 0.025;
  565. PARFLT scaled_padding = 0.0;
  566. while (1) {
  567. worker->npacked = 0;
  568. worker->count = nchildren;
  569. PARINT c = 0;
  570. for (PARINT cindex = head; cindex != tail; cindex++) {
  571. PARINT child = bubbles->graph_children[cindex];
  572. radiuses[c++] = bubbles->xyr[child * 3 + 2] + scaled_padding;
  573. }
  574. par_bubbles__initflat(worker);
  575. par_bubbles__packflat(worker);
  576. // Using Welzl's algorithm instead of a simple AABB enclosure is
  577. // slightly slower and doesn't yield much aesthetic improvement.
  578. #if PAR_BUBBLES_HPACK_WELZL
  579. par_bubbles_enclose_disks(worker->xyr, nchildren, enclosure);
  580. #else
  581. PARFLT aabb[6];
  582. par_bubbles_compute_aabb((par_bubbles_t const*) worker, aabb);
  583. enclosure[0] = 0.5 * (aabb[0] + aabb[2]);
  584. enclosure[1] = 0.5 * (aabb[1] + aabb[3]);
  585. enclosure[2] = 0;
  586. for (PARINT c = 0; c < nchildren; c++) {
  587. PARFLT x = worker->xyr[c * 3 + 0] - enclosure[0];
  588. PARFLT y = worker->xyr[c * 3 + 1] - enclosure[1];
  589. PARFLT r = worker->xyr[c * 3 + 2];
  590. enclosure[2] = PAR_MAX(enclosure[2], r + sqrtf(x * x + y * y));
  591. }
  592. #endif
  593. if (scaled_padding || !PAR_HPACK_PADDING1) {
  594. break;
  595. } else {
  596. scaled_padding = PAR_HPACK_PADDING1 / enclosure[2];
  597. }
  598. }
  599. PARFLT cx = enclosure[0], cy = enclosure[1], cr = enclosure[2];
  600. scaled_padding *= cr;
  601. cr += PAR_HPACK_PADDING2 * cr;
  602. // Transform the children to fit nicely into either (a) the unit circle,
  603. // or (b) their parent. The former is used if "local" is true.
  604. PARFLT scale, tx, ty;
  605. if (local) {
  606. scale = 1.0 / cr;
  607. tx = 0;
  608. ty = 0;
  609. } else {
  610. scale = pr / cr;
  611. tx = px;
  612. ty = py;
  613. }
  614. PARFLT const* src = worker->xyr;
  615. for (PARINT cindex = head; cindex != tail; cindex++, src += 3) {
  616. PARFLT* dst = bubbles->xyr + 3 * bubbles->graph_children[cindex];
  617. dst[0] = tx + scale * (src[0] - cx);
  618. dst[1] = ty + scale * (src[1] - cy);
  619. dst[2] = scale * (src[2] - scaled_padding);
  620. }
  621. // Recursion. TODO: It might be better to use our own stack here.
  622. for (PARINT cindex = head; cindex != tail; cindex++) {
  623. par_bubbles__hpack(bubbles, worker, bubbles->graph_children[cindex],
  624. local);
  625. }
  626. }
  627. par_bubbles_t* par_bubbles_hpack_circle(PARINT* nodes, PARINT nnodes,
  628. PARFLT radius)
  629. {
  630. par_bubbles__t* bubbles = PAR_CALLOC(par_bubbles__t, 1);
  631. if (nnodes > 0) {
  632. bubbles->graph_parents = nodes;
  633. bubbles->count = nnodes;
  634. bubbles->chain = PAR_MALLOC(par_bubbles__node, nnodes);
  635. bubbles->xyr = PAR_MALLOC(PARFLT, 3 * nnodes);
  636. par_bubbles__initgraph(bubbles);
  637. par_bubbles__t* worker = PAR_CALLOC(par_bubbles__t, 1);
  638. worker->radiuses = PAR_MALLOC(PARFLT, bubbles->maxwidth);
  639. worker->chain = PAR_MALLOC(par_bubbles__node, bubbles->maxwidth);
  640. worker->xyr = PAR_MALLOC(PARFLT, 3 * bubbles->maxwidth);
  641. par_bubbles__generate_radii(bubbles, worker, 0);
  642. bubbles->xyr[0] = 0;
  643. bubbles->xyr[1] = 0;
  644. bubbles->xyr[2] = radius;
  645. par_bubbles__hpack(bubbles, worker, 0, false);
  646. par_bubbles_free_result((par_bubbles_t*) worker);
  647. }
  648. return (par_bubbles_t*) bubbles;
  649. }
  650. // TODO: use a stack instead of recursion
  651. static PARINT par_bubbles__pick(par_bubbles__t const* bubbles, PARINT parent,
  652. PARFLT x, PARFLT y)
  653. {
  654. PARFLT const* xyr = bubbles->xyr + parent * 3;
  655. PARFLT d2 = PAR_SQR(x - xyr[0]) + PAR_SQR(y - xyr[1]);
  656. if (d2 > PAR_SQR(xyr[2])) {
  657. return -1;
  658. }
  659. PARINT head = bubbles->graph_heads[parent];
  660. PARINT tail = bubbles->graph_tails[parent];
  661. for (PARINT cindex = head; cindex != tail; cindex++) {
  662. PARINT child = bubbles->graph_children[cindex];
  663. PARINT result = par_bubbles__pick(bubbles, child, x, y);
  664. if (result > -1) {
  665. return result;
  666. }
  667. }
  668. return parent;
  669. }
  670. PARINT par_bubbles_pick(par_bubbles_t const* cbubbles, PARFLT x, PARFLT y)
  671. {
  672. par_bubbles__t const* bubbles = (par_bubbles__t const*) cbubbles;
  673. if (bubbles->count == 0) {
  674. return -1;
  675. }
  676. return par_bubbles__pick(bubbles, 0, x, y);
  677. }
  678. void par_bubbles_compute_aabb(par_bubbles_t const* bubbles, PARFLT* aabb)
  679. {
  680. if (bubbles->count == 0) {
  681. return;
  682. }
  683. PARFLT const* xyr = bubbles->xyr;
  684. aabb[0] = aabb[2] = xyr[0];
  685. aabb[1] = aabb[3] = xyr[1];
  686. for (PARINT i = 0; i < bubbles->count; i++, xyr += 3) {
  687. aabb[0] = PAR_MIN(xyr[0] - xyr[2], aabb[0]);
  688. aabb[1] = PAR_MIN(xyr[1] - xyr[2], aabb[1]);
  689. aabb[2] = PAR_MAX(xyr[0] + xyr[2], aabb[2]);
  690. aabb[3] = PAR_MAX(xyr[1] + xyr[2], aabb[3]);
  691. }
  692. }
  693. bool par_bubbles_check_aabb(PARFLT const* disk, PARFLT const* aabb)
  694. {
  695. PARFLT cx = PAR_CLAMP(disk[0], aabb[0], aabb[2]);
  696. PARFLT cy = PAR_CLAMP(disk[1], aabb[1], aabb[3]);
  697. PARFLT dx = disk[0] - cx;
  698. PARFLT dy = disk[1] - cy;
  699. PARFLT d2 = dx * dx + dy * dy;
  700. return d2 < (disk[2] * disk[2]);
  701. }
  702. static void par_bubbles__cull(par_bubbles__t const* src, PARFLT const* aabb,
  703. PARFLT minradius, par_bubbles__t* dst, PARINT parent)
  704. {
  705. PARFLT const* xyr = src->xyr + parent * 3;
  706. if (xyr[2] < minradius || !par_bubbles_check_aabb(xyr, aabb)) {
  707. return;
  708. }
  709. par_bubbles__copy_disk(src, dst, parent);
  710. PARINT head = src->graph_heads[parent];
  711. PARINT tail = src->graph_tails[parent];
  712. for (PARINT cindex = head; cindex != tail; cindex++) {
  713. PARINT child = src->graph_children[cindex];
  714. par_bubbles__cull(src, aabb, minradius, dst, child);
  715. }
  716. }
  717. par_bubbles_t* par_bubbles_cull(par_bubbles_t const* psrc,
  718. PARFLT const* aabb, PARFLT minradius, par_bubbles_t* pdst)
  719. {
  720. par_bubbles__t const* src = (par_bubbles__t const*) psrc;
  721. par_bubbles__t* dst = (par_bubbles__t*) pdst;
  722. if (!dst) {
  723. dst = PAR_CALLOC(par_bubbles__t, 1);
  724. pdst = (par_bubbles_t*) dst;
  725. } else {
  726. dst->count = 0;
  727. }
  728. if (src->count == 0) {
  729. return pdst;
  730. }
  731. par_bubbles__cull(src, aabb, minradius, dst, 0);
  732. return pdst;
  733. }
  734. void par_bubbles_export(par_bubbles_t const* bubbles, char const* filename)
  735. {
  736. PARFLT aabb[4];
  737. par_bubbles_compute_aabb(bubbles, aabb);
  738. PARFLT maxextent = PAR_MAX(aabb[2] - aabb[0], aabb[3] - aabb[1]);
  739. PARFLT padding = 0.05 * maxextent;
  740. FILE* svgfile = fopen(filename, "wt");
  741. fprintf(svgfile,
  742. "<svg viewBox='%f %f %f %f' width='640px' height='640px' "
  743. "version='1.1' "
  744. "xmlns='http://www.w3.org/2000/svg'>\n"
  745. "<g stroke-width='0.5' stroke-opacity='0.5' stroke='black' "
  746. "fill-opacity='0.2' fill='#2A8BB6'>\n"
  747. "<rect fill-opacity='0.1' stroke='none' fill='#2A8BB6' x='%f' y='%f' "
  748. "width='100%%' height='100%%'/>\n",
  749. aabb[0] - padding, aabb[1] - padding,
  750. aabb[2] - aabb[0] + 2 * padding, aabb[3] - aabb[1] + 2 * padding,
  751. aabb[0] - padding, aabb[1] - padding);
  752. PARFLT const* xyr = bubbles->xyr;
  753. for (PARINT i = 0; i < bubbles->count; i++, xyr += 3) {
  754. fprintf(svgfile, "<circle stroke-width='%f' cx='%f' cy='%f' r='%f'/>\n",
  755. xyr[2] * 0.01, xyr[0], xyr[1], xyr[2]);
  756. fprintf(svgfile, "<text text-anchor='middle' stroke='none' "
  757. "x='%f' y='%f' font-size='%f'>%d</text>\n",
  758. xyr[0], xyr[1] + xyr[2] * 0.125, xyr[2] * 0.5, (int) i);
  759. }
  760. fputs("</g>\n</svg>", svgfile);
  761. fclose(svgfile);
  762. }
  763. void par_bubbles_get_children(par_bubbles_t const* pbubbles, PARINT node,
  764. PARINT** pchildren, PARINT* nchildren)
  765. {
  766. par_bubbles__t const* bubbles = (par_bubbles__t const*) pbubbles;
  767. *pchildren = bubbles->graph_children + bubbles->graph_heads[node];
  768. *nchildren = bubbles->graph_tails[node] - bubbles->graph_heads[node];
  769. }
  770. PARINT par_bubbles_get_parent(par_bubbles_t const* pbubbles, PARINT node)
  771. {
  772. par_bubbles__t const* bubbles = (par_bubbles__t const*) pbubbles;
  773. return bubbles->graph_parents[node];
  774. }
  775. void par_bubbles__get_maxdepth(par_bubbles__t const* bubbles, PARINT* maxdepth,
  776. PARINT* leaf, PARINT parent, PARINT depth)
  777. {
  778. if (depth > *maxdepth) {
  779. *leaf = parent;
  780. *maxdepth = depth;
  781. }
  782. PARINT* children;
  783. PARINT nchildren;
  784. par_bubbles_t const* pbubbles = (par_bubbles_t const*) bubbles;
  785. par_bubbles_get_children(pbubbles, parent, &children, &nchildren);
  786. for (PARINT c = 0; c < nchildren; c++) {
  787. par_bubbles__get_maxdepth(bubbles, maxdepth, leaf, children[c],
  788. depth + 1);
  789. }
  790. }
  791. void par_bubbles_get_maxdepth(par_bubbles_t const* pbubbles, PARINT* maxdepth,
  792. PARINT* leaf)
  793. {
  794. par_bubbles__t const* bubbles = (par_bubbles__t const*) pbubbles;
  795. *maxdepth = -1;
  796. *leaf = -1;
  797. return par_bubbles__get_maxdepth(bubbles, maxdepth, leaf, 0, 0);
  798. }
  799. PARINT par_bubbles_get_depth(par_bubbles_t const* pbubbles, PARINT node)
  800. {
  801. par_bubbles__t const* bubbles = (par_bubbles__t const*) pbubbles;
  802. PARINT const* parents = bubbles->graph_parents;
  803. PARINT depth = 0;
  804. while (node) {
  805. node = parents[node];
  806. depth++;
  807. }
  808. return depth;
  809. }
  810. void par_bubbles_compute_aabb_for_node(par_bubbles_t const* bubbles,
  811. PAR_BUBBLES_INT node, PAR_BUBBLES_FLT* aabb)
  812. {
  813. PARFLT const* xyr = bubbles->xyr + 3 * node;
  814. aabb[0] = aabb[2] = xyr[0];
  815. aabb[1] = aabb[3] = xyr[1];
  816. aabb[0] = PAR_MIN(xyr[0] - xyr[2], aabb[0]);
  817. aabb[1] = PAR_MIN(xyr[1] - xyr[2], aabb[1]);
  818. aabb[2] = PAR_MAX(xyr[0] + xyr[2], aabb[2]);
  819. aabb[3] = PAR_MAX(xyr[1] + xyr[2], aabb[3]);
  820. }
  821. PARINT par_bubbles_lowest_common_ancestor(par_bubbles_t const* bubbles,
  822. PARINT node_a, PARINT node_b)
  823. {
  824. if (node_a == node_b) {
  825. return node_a;
  826. }
  827. par_bubbles__t const* src = (par_bubbles__t const*) bubbles;
  828. PARINT depth_a = par_bubbles_get_depth(bubbles, node_a);
  829. PARINT* chain_a = PAR_MALLOC(PARINT, depth_a);
  830. for (PARINT i = depth_a - 1; i >= 0; i--) {
  831. chain_a[i] = node_a;
  832. node_a = src->graph_parents[node_a];
  833. }
  834. PARINT depth_b = par_bubbles_get_depth(bubbles, node_b);
  835. PARINT* chain_b = PAR_MALLOC(PARINT, depth_b);
  836. for (PARINT i = depth_b - 1; i >= 0; i--) {
  837. chain_b[i] = node_b;
  838. node_b = src->graph_parents[node_b];
  839. }
  840. PARINT lca = 0;
  841. for (PARINT i = 1; i < PAR_MIN(depth_a, depth_b); i++) {
  842. if (chain_a[i] != chain_b[i]) {
  843. break;
  844. }
  845. lca = chain_a[i];
  846. }
  847. PAR_FREE(chain_a);
  848. PAR_FREE(chain_b);
  849. return lca;
  850. }
  851. void par_bubbles_export_local(par_bubbles_t const* bubbles,
  852. PAR_BUBBLES_INT root, char const* filename)
  853. {
  854. par_bubbles_t* clone = par_bubbles_cull_local(bubbles, 0, 0, root, 0);
  855. FILE* svgfile = fopen(filename, "wt");
  856. fprintf(svgfile,
  857. "<svg viewBox='%f %f %f %f' width='640px' height='640px' "
  858. "version='1.1' "
  859. "xmlns='http://www.w3.org/2000/svg'>\n"
  860. "<g stroke-width='0.5' stroke-opacity='0.5' stroke='black' "
  861. "fill-opacity='0.2' fill='#2A8BB6'>\n"
  862. "<rect fill-opacity='0.1' stroke='none' fill='#2AB68B' x='%f' y='%f' "
  863. "width='100%%' height='100%%'/>\n",
  864. -1.0, -1.0, 2.0, 2.0, -1.0, -1.0);
  865. PARFLT const* xyr = clone->xyr;
  866. for (PARINT i = 0; i < clone->count; i++, xyr += 3) {
  867. fprintf(svgfile, "<circle stroke-width='%f' cx='%f' cy='%f' r='%f'/>\n",
  868. xyr[2] * 0.01, xyr[0], xyr[1], xyr[2]);
  869. }
  870. fputs("</g>\n</svg>", svgfile);
  871. fclose(svgfile);
  872. par_bubbles_free_result(clone);
  873. }
  874. void par_bubbles_set_filter(par_bubbles_t* bubbles, par_bubbles_filter f)
  875. {
  876. par_bubbles__t* src = (par_bubbles__t*) bubbles;
  877. src->filter = f;
  878. }
  879. static void par_bubbles__copy_disk_local(par_bubbles__t const* src,
  880. par_bubbles__t* dst, PARINT parent, PARFLT const* xform)
  881. {
  882. PARINT i = dst->count++;
  883. if (dst->capacity < dst->count) {
  884. dst->capacity = PAR_MAX(16, dst->capacity) * 2;
  885. dst->xyr = PAR_REALLOC(PARFLT, dst->xyr, 3 * dst->capacity);
  886. dst->ids = PAR_REALLOC(PARINT, dst->ids, dst->capacity);
  887. }
  888. PARFLT const* xyr = src->xyr + parent * 3;
  889. dst->xyr[i * 3] = xyr[0] * xform[2] + xform[0];
  890. dst->xyr[i * 3 + 1] = xyr[1] * xform[2] + xform[1];
  891. dst->xyr[i * 3 + 2] = xyr[2] * xform[2];
  892. dst->ids[i] = parent;
  893. }
  894. static void par_bubbles__cull_local(par_bubbles__t const* src,
  895. PARFLT const* aabb, PARFLT const* xform, PARFLT minradius,
  896. par_bubbles__t* dst, PARINT parent)
  897. {
  898. PARFLT const* xyr = src->xyr + parent * 3;
  899. PARFLT child_xform[3] = {
  900. xform[0] + xform[2] * xyr[0],
  901. xform[1] + xform[2] * xyr[1],
  902. xform[2] * xyr[2]
  903. };
  904. if (aabb && !par_bubbles_check_aabb(child_xform, aabb)) {
  905. return;
  906. }
  907. if (child_xform[2] < minradius) {
  908. return;
  909. }
  910. par_bubbles__copy_disk_local(src, dst, parent, xform);
  911. xform = child_xform;
  912. PARINT head = src->graph_heads[parent];
  913. PARINT tail = src->graph_tails[parent];
  914. if (src->filter == PAR_BUBBLES_FILTER_DISCARD_LAST_CHILD) {
  915. tail--;
  916. } else if (src->filter == PAR_BUBBLES_FILTER_KEEP_ONLY_LAST_CHILD) {
  917. head = PAR_MAX(head, tail - 1);
  918. }
  919. for (PARINT cindex = head; cindex < tail; cindex++) {
  920. PARINT child = src->graph_children[cindex];
  921. par_bubbles__cull_local(src, aabb, xform, minradius, dst, child);
  922. }
  923. }
  924. par_bubbles_t* par_bubbles_cull_local(par_bubbles_t const* psrc,
  925. PAR_BUBBLES_FLT const* aabb, PAR_BUBBLES_FLT minradius,
  926. PAR_BUBBLES_INT root, par_bubbles_t* pdst)
  927. {
  928. par_bubbles__t const* src = (par_bubbles__t const*) psrc;
  929. par_bubbles__t* dst = (par_bubbles__t*) pdst;
  930. if (!dst) {
  931. dst = PAR_CALLOC(par_bubbles__t, 1);
  932. pdst = (par_bubbles_t*) dst;
  933. } else {
  934. dst->count = 0;
  935. }
  936. if (src->count == 0) {
  937. return pdst;
  938. }
  939. PARFLT xform[3] = {0, 0, 1};
  940. par_bubbles__copy_disk_local(src, dst, root, xform);
  941. dst->xyr[0] = dst->xyr[1] = 0;
  942. dst->xyr[2] = 1;
  943. PARINT head = src->graph_heads[root];
  944. PARINT tail = src->graph_tails[root];
  945. if (src->filter == PAR_BUBBLES_FILTER_DISCARD_LAST_CHILD) {
  946. tail--;
  947. } else if (src->filter == PAR_BUBBLES_FILTER_KEEP_ONLY_LAST_CHILD) {
  948. head = PAR_MAX(head, tail - 1);
  949. }
  950. for (PARINT cindex = head; cindex < tail; cindex++) {
  951. PARINT child = src->graph_children[cindex];
  952. par_bubbles__cull_local(src, aabb, xform, minradius, dst, child);
  953. }
  954. return pdst;
  955. }
  956. par_bubbles_t* par_bubbles_hpack_local(PARINT* nodes, PARINT nnodes)
  957. {
  958. par_bubbles__t* bubbles = PAR_CALLOC(par_bubbles__t, 1);
  959. if (nnodes > 0) {
  960. bubbles->graph_parents = nodes;
  961. bubbles->count = nnodes;
  962. bubbles->chain = PAR_MALLOC(par_bubbles__node, nnodes);
  963. bubbles->xyr = PAR_MALLOC(PARFLT, 3 * nnodes);
  964. par_bubbles__initgraph(bubbles);
  965. par_bubbles__t* worker = PAR_CALLOC(par_bubbles__t, 1);
  966. worker->radiuses = PAR_MALLOC(PARFLT, bubbles->maxwidth);
  967. worker->chain = PAR_MALLOC(par_bubbles__node, bubbles->maxwidth);
  968. worker->xyr = PAR_MALLOC(PARFLT, 3 * bubbles->maxwidth);
  969. par_bubbles__generate_radii(bubbles, worker, 0);
  970. bubbles->xyr[0] = 0;
  971. bubbles->xyr[1] = 0;
  972. bubbles->xyr[2] = 1;
  973. par_bubbles__hpack(bubbles, worker, 0, true);
  974. par_bubbles_free_result((par_bubbles_t*) worker);
  975. }
  976. return (par_bubbles_t*) bubbles;
  977. }
  978. static bool par_bubbles__disk_encloses_aabb(PAR_BUBBLES_FLT cx,
  979. PAR_BUBBLES_FLT cy, PAR_BUBBLES_FLT r, PAR_BUBBLES_FLT const* aabb)
  980. {
  981. PAR_BUBBLES_FLT x, y;
  982. PAR_BUBBLES_FLT r2 = r * r;
  983. x = aabb[0]; y = aabb[1];
  984. if (PAR_SQR(x - cx) + PAR_SQR(y - cy) > r2) {
  985. return false;
  986. }
  987. x = aabb[2]; y = aabb[1];
  988. if (PAR_SQR(x - cx) + PAR_SQR(y - cy) > r2) {
  989. return false;
  990. }
  991. x = aabb[0]; y = aabb[3];
  992. if (PAR_SQR(x - cx) + PAR_SQR(y - cy) > r2) {
  993. return false;
  994. }
  995. x = aabb[2]; y = aabb[3];
  996. return PAR_SQR(x - cx) + PAR_SQR(y - cy) <= r2;
  997. }
  998. static bool par_bubbles__get_local(par_bubbles__t const* src, PARFLT* xform,
  999. PARINT parent, PARINT node);
  1000. static bool par_bubbles_transform_parent(par_bubbles__t const* src,
  1001. PARFLT* xform, PARINT node0)
  1002. {
  1003. PARINT node1 = src->graph_parents[node0];
  1004. xform[0] = 0;
  1005. xform[1] = 0;
  1006. xform[2] = 1;
  1007. PARINT head = src->graph_heads[node1];
  1008. PARINT tail = src->graph_tails[node1];
  1009. for (PARINT cindex = head; cindex != tail; cindex++) {
  1010. PARINT child = src->graph_children[cindex];
  1011. if (par_bubbles__get_local(src, xform, child, node0)) {
  1012. return true;
  1013. }
  1014. }
  1015. return false;
  1016. }
  1017. PARINT par_bubbles__find_local(par_bubbles__t const* src,
  1018. PARFLT const* xform, PARFLT const* aabb, PARINT parent)
  1019. {
  1020. PARFLT const* xyr = src->xyr + parent * 3;
  1021. PARFLT child_xform[3] = {
  1022. xform[2] * xyr[0] + xform[0],
  1023. xform[2] * xyr[1] + xform[1],
  1024. xform[2] * xyr[2]
  1025. };
  1026. xform = child_xform;
  1027. if (!par_bubbles__disk_encloses_aabb(xform[0], xform[1], xform[2], aabb)) {
  1028. return -1;
  1029. }
  1030. PARFLT maxrad = 0;
  1031. PARINT head = src->graph_heads[parent];
  1032. PARINT tail = src->graph_tails[parent];
  1033. for (PARINT cindex = head; cindex != tail; cindex++) {
  1034. PARINT child = src->graph_children[cindex];
  1035. PARFLT const* xyr = src->xyr + child * 3;
  1036. maxrad = PAR_MAX(maxrad, xyr[2]);
  1037. }
  1038. PARFLT maxext = PAR_MAX(aabb[2] - aabb[0], aabb[3] - aabb[1]);
  1039. if (2 * maxrad < maxext) {
  1040. return parent;
  1041. }
  1042. for (PARINT cindex = head; cindex != tail; cindex++) {
  1043. PARINT child = src->graph_children[cindex];
  1044. PARINT cresult = par_bubbles__find_local(src, xform, aabb, child);
  1045. if (cresult > -1) {
  1046. return cresult;
  1047. }
  1048. }
  1049. return parent;
  1050. }
  1051. // This finds the deepest node that completely encloses the box.
  1052. PARINT par_bubbles_find_local(par_bubbles_t const* bubbles, PARFLT const* aabb,
  1053. PARINT root)
  1054. {
  1055. par_bubbles__t const* src = (par_bubbles__t const*) bubbles;
  1056. // Since the aabb is expressed in the coordinate system of the given root,
  1057. // we can do a trivial rejection right away, using the unit circle.
  1058. if (!par_bubbles__disk_encloses_aabb(0, 0, 1, aabb)) {
  1059. if (root == 0) {
  1060. return -1;
  1061. }
  1062. PARFLT xform[3];
  1063. par_bubbles_transform_parent(src, xform, root);
  1064. PARFLT width = aabb[2] - aabb[0];
  1065. PARFLT height = aabb[3] - aabb[1];
  1066. PARFLT cx = 0.5 * (aabb[0] + aabb[2]);
  1067. PARFLT cy = 0.5 * (aabb[1] + aabb[3]);
  1068. width *= xform[2];
  1069. height *= xform[2];
  1070. cx = cx * xform[2] + xform[0];
  1071. cy = cy * xform[2] + xform[1];
  1072. PARFLT new_aabb[4] = {
  1073. cx - width * 0.5,
  1074. cy - height * 0.5,
  1075. cx + width * 0.5,
  1076. cy + height * 0.5
  1077. };
  1078. PARINT parent = src->graph_parents[root];
  1079. return par_bubbles_find_local(bubbles, new_aabb, parent);
  1080. }
  1081. PARFLT maxrad = 0;
  1082. PARINT head = src->graph_heads[root];
  1083. PARINT tail = src->graph_tails[root];
  1084. for (PARINT cindex = head; cindex != tail; cindex++) {
  1085. PARINT child = src->graph_children[cindex];
  1086. PARFLT const* xyr = src->xyr + child * 3;
  1087. maxrad = PAR_MAX(maxrad, xyr[2]);
  1088. }
  1089. PARFLT maxext = PAR_MAX(aabb[2] - aabb[0], aabb[3] - aabb[1]);
  1090. if (2 * maxrad < maxext) {
  1091. return root;
  1092. }
  1093. PARFLT xform[3] = {0, 0, 1};
  1094. for (PARINT cindex = head; cindex != tail; cindex++) {
  1095. PARINT child = src->graph_children[cindex];
  1096. PARINT cresult = par_bubbles__find_local(src, xform, aabb, child);
  1097. if (cresult > -1) {
  1098. return cresult;
  1099. }
  1100. }
  1101. return root;
  1102. }
  1103. // This could be implemented much more efficiently, but for now it simply
  1104. // calls find_local with a zero-size AABB, then ensures that the result
  1105. // has a radius that is greater than or equal to minradius.
  1106. PARINT par_bubbles_pick_local(par_bubbles_t const* bubbles, PARFLT x, PARFLT y,
  1107. PARINT root, PARFLT minradius)
  1108. {
  1109. par_bubbles__t const* src = (par_bubbles__t const*) bubbles;
  1110. PARFLT aabb[] = { x, y, x, y };
  1111. PARINT result = par_bubbles_find_local(bubbles, aabb, root);
  1112. if (result == -1) {
  1113. return result;
  1114. }
  1115. PARINT depth = par_bubbles_get_depth(bubbles, result);
  1116. PARINT* chain = PAR_MALLOC(PARINT, depth);
  1117. PARINT node = result;
  1118. for (PARINT i = depth - 1; i >= 0; i--) {
  1119. chain[i] = node;
  1120. node = src->graph_parents[node];
  1121. }
  1122. PARFLT radius = 1;
  1123. for (PARINT i = 1; i < depth; i++) {
  1124. PARINT node = chain[i];
  1125. radius *= src->xyr[node * 3 + 2];
  1126. if (radius < minradius) {
  1127. result = chain[i - 1];
  1128. break;
  1129. }
  1130. }
  1131. PAR_FREE(chain);
  1132. return result;
  1133. }
  1134. static bool par_bubbles__get_local(par_bubbles__t const* src, PARFLT* xform,
  1135. PARINT parent, PARINT node)
  1136. {
  1137. PARFLT const* xyr = src->xyr + parent * 3;
  1138. PARFLT child_xform[3] = {
  1139. xform[2] * xyr[0] + xform[0],
  1140. xform[2] * xyr[1] + xform[1],
  1141. xform[2] * xyr[2]
  1142. };
  1143. if (parent == node) {
  1144. xform[0] = child_xform[0];
  1145. xform[1] = child_xform[1];
  1146. xform[2] = child_xform[2];
  1147. return true;
  1148. }
  1149. PARINT head = src->graph_heads[parent];
  1150. PARINT tail = src->graph_tails[parent];
  1151. for (PARINT cindex = head; cindex != tail; cindex++) {
  1152. PARINT child = src->graph_children[cindex];
  1153. if (par_bubbles__get_local(src, child_xform, child, node)) {
  1154. xform[0] = child_xform[0];
  1155. xform[1] = child_xform[1];
  1156. xform[2] = child_xform[2];
  1157. return true;
  1158. }
  1159. }
  1160. return false;
  1161. }
  1162. // Obtains the scale and translation (which should be applied in that order)
  1163. // that can move a point from the node0 coord system to the node1 coord system.
  1164. // The "xform" argument should point to three floats, which will be populated
  1165. // with: x translation, y translation, and scale.
  1166. bool par_bubbles_transform_local(par_bubbles_t const* bubbles, PARFLT* xform,
  1167. PARINT node0, PARINT node1)
  1168. {
  1169. par_bubbles__t const* src = (par_bubbles__t const*) bubbles;
  1170. xform[0] = 0;
  1171. xform[1] = 0;
  1172. xform[2] = 1;
  1173. if (node0 == node1) {
  1174. return true;
  1175. }
  1176. if (node1 == src->graph_parents[node0]) {
  1177. return par_bubbles_transform_parent(src, xform, node0);
  1178. }
  1179. // First try the case where node1 is a descendant of node0
  1180. PARINT head = src->graph_heads[node0];
  1181. PARINT tail = src->graph_tails[node0];
  1182. for (PARINT cindex = head; cindex != tail; cindex++) {
  1183. PARINT child = src->graph_children[cindex];
  1184. if (par_bubbles__get_local(src, xform, child, node1)) {
  1185. float tx = xform[0];
  1186. float ty = xform[1];
  1187. float s = xform[2];
  1188. xform[0] = -tx / s;
  1189. xform[1] = -ty / s;
  1190. xform[2] = 1.0 / s;
  1191. return true;
  1192. }
  1193. }
  1194. // Next, try the case where node0 is a descendant of node1
  1195. head = src->graph_heads[node1];
  1196. tail = src->graph_tails[node1];
  1197. for (PARINT cindex = head; cindex != tail; cindex++) {
  1198. PARINT child = src->graph_children[cindex];
  1199. if (par_bubbles__get_local(src, xform, child, node0)) {
  1200. return true;
  1201. }
  1202. }
  1203. // If we reach here, then node0 is neither an ancestor nor a descendant, so
  1204. // do something hacky and return false. It would be best to find the lowest
  1205. // common ancestor, but let's just assume the lowest common ancestor is 0.
  1206. PARFLT xform2[3] = {0, 0, 1};
  1207. par_bubbles_transform_local(bubbles, xform, node0, 0);
  1208. par_bubbles_transform_local(bubbles, xform2, 0, node1);
  1209. xform[0] *= xform2[2];
  1210. xform[1] *= xform2[2];
  1211. xform[2] *= xform2[2];
  1212. xform[0] += xform2[0];
  1213. xform[1] += xform2[1];
  1214. return false;
  1215. }
  1216. void par_bubbles_set_orientation(par_bubbles_orientation ostate)
  1217. {
  1218. par_bubbles__ostate = ostate;
  1219. }
  1220. #undef PARINT
  1221. #undef PARFLT
  1222. #endif // PAR_BUBBLES_IMPLEMENTATION
  1223. #endif // PAR_BUBBLES_H