(circles)
| 121448 | } |
| 121449 | |
| 121450 | function packEnclose(circles) { |
| 121451 | if (!(n = circles.length)) return 0; |
| 121452 | var a, b, c, n, aa, ca, i, j, k, sj, sk; // Place the first circle. |
| 121453 | |
| 121454 | a = circles[0], a.x = 0, a.y = 0; |
| 121455 | if (!(n > 1)) return a.r; // Place the second circle. |
| 121456 | |
| 121457 | b = circles[1], a.x = -b.r, b.x = a.r, b.y = 0; |
| 121458 | if (!(n > 2)) return a.r + b.r; // Place the third circle. |
| 121459 | |
| 121460 | place(b, a, c = circles[2]); // Initialize the front-chain using the first three circles a, b and c. |
| 121461 | |
| 121462 | a = new Node(a), b = new Node(b), c = new Node(c); |
| 121463 | a.next = c.previous = b; |
| 121464 | b.next = a.previous = c; |
| 121465 | c.next = b.previous = a; // Attempt to place each remaining circle… |
| 121466 | |
| 121467 | pack: for (i = 3; i < n; ++i) { |
| 121468 | place(a._, b._, c = circles[i]), c = new Node(c); // Find the closest intersecting circle on the front-chain, if any. |
| 121469 | // “Closeness” is determined by linear distance along the front-chain. |
| 121470 | // “Ahead” or “behind” is likewise determined by linear distance. |
| 121471 | |
| 121472 | j = b.next, k = a.previous, sj = b._.r, sk = a._.r; |
| 121473 | |
| 121474 | do { |
| 121475 | if (sj <= sk) { |
| 121476 | if (intersects(j._, c._)) { |
| 121477 | b = j, a.next = b, b.previous = a, --i; |
| 121478 | continue pack; |
| 121479 | } |
| 121480 | |
| 121481 | sj += j._.r, j = j.next; |
| 121482 | } else { |
| 121483 | if (intersects(k._, c._)) { |
| 121484 | a = k, a.next = b, b.previous = a, --i; |
| 121485 | continue pack; |
| 121486 | } |
| 121487 | |
| 121488 | sk += k._.r, k = k.previous; |
| 121489 | } |
| 121490 | } while (j !== k.next); // Success! Insert the new circle c between a and b. |
| 121491 | |
| 121492 | |
| 121493 | c.previous = a, c.next = b, a.next = b.previous = b = c; // Compute the new closest circle pair to the centroid. |
| 121494 | |
| 121495 | aa = score(a); |
| 121496 | |
| 121497 | while ((c = c.next) !== b) { |
| 121498 | if ((ca = score(c)) < aa) { |
| 121499 | a = c, aa = ca; |
| 121500 | } |
| 121501 | } |
| 121502 | |
| 121503 | b = a.next; |
| 121504 | } // Compute the enclosing circle of the front chain. |
| 121505 | |
| 121506 | |
| 121507 | a = [b._], c = b; |
no test coverage detected