source: node_modules/d3-hierarchy/src/pack/enclose.js@ e4c61dd

Last change on this file since e4c61dd was e4c61dd, checked in by istevanoska <ilinastevanoska@…>, 6 months ago

Prototype 1.1

  • Property mode set to 100644
File size: 3.1 KB
Line 
1import {shuffle} from "../array.js";
2import lcg from "../lcg.js";
3
4export default function(circles) {
5 return packEncloseRandom(circles, lcg());
6}
7
8export function packEncloseRandom(circles, random) {
9 var i = 0, n = (circles = shuffle(Array.from(circles), random)).length, B = [], p, e;
10
11 while (i < n) {
12 p = circles[i];
13 if (e && enclosesWeak(e, p)) ++i;
14 else e = encloseBasis(B = extendBasis(B, p)), i = 0;
15 }
16
17 return e;
18}
19
20function extendBasis(B, p) {
21 var i, j;
22
23 if (enclosesWeakAll(p, B)) return [p];
24
25 // If we get here then B must have at least one element.
26 for (i = 0; i < B.length; ++i) {
27 if (enclosesNot(p, B[i])
28 && enclosesWeakAll(encloseBasis2(B[i], p), B)) {
29 return [B[i], p];
30 }
31 }
32
33 // If we get here then B must have at least two elements.
34 for (i = 0; i < B.length - 1; ++i) {
35 for (j = i + 1; j < B.length; ++j) {
36 if (enclosesNot(encloseBasis2(B[i], B[j]), p)
37 && enclosesNot(encloseBasis2(B[i], p), B[j])
38 && enclosesNot(encloseBasis2(B[j], p), B[i])
39 && enclosesWeakAll(encloseBasis3(B[i], B[j], p), B)) {
40 return [B[i], B[j], p];
41 }
42 }
43 }
44
45 // If we get here then something is very wrong.
46 throw new Error;
47}
48
49function enclosesNot(a, b) {
50 var dr = a.r - b.r, dx = b.x - a.x, dy = b.y - a.y;
51 return dr < 0 || dr * dr < dx * dx + dy * dy;
52}
53
54function enclosesWeak(a, b) {
55 var dr = a.r - b.r + Math.max(a.r, b.r, 1) * 1e-9, dx = b.x - a.x, dy = b.y - a.y;
56 return dr > 0 && dr * dr > dx * dx + dy * dy;
57}
58
59function enclosesWeakAll(a, B) {
60 for (var i = 0; i < B.length; ++i) {
61 if (!enclosesWeak(a, B[i])) {
62 return false;
63 }
64 }
65 return true;
66}
67
68function encloseBasis(B) {
69 switch (B.length) {
70 case 1: return encloseBasis1(B[0]);
71 case 2: return encloseBasis2(B[0], B[1]);
72 case 3: return encloseBasis3(B[0], B[1], B[2]);
73 }
74}
75
76function encloseBasis1(a) {
77 return {
78 x: a.x,
79 y: a.y,
80 r: a.r
81 };
82}
83
84function encloseBasis2(a, b) {
85 var x1 = a.x, y1 = a.y, r1 = a.r,
86 x2 = b.x, y2 = b.y, r2 = b.r,
87 x21 = x2 - x1, y21 = y2 - y1, r21 = r2 - r1,
88 l = Math.sqrt(x21 * x21 + y21 * y21);
89 return {
90 x: (x1 + x2 + x21 / l * r21) / 2,
91 y: (y1 + y2 + y21 / l * r21) / 2,
92 r: (l + r1 + r2) / 2
93 };
94}
95
96function encloseBasis3(a, b, c) {
97 var x1 = a.x, y1 = a.y, r1 = a.r,
98 x2 = b.x, y2 = b.y, r2 = b.r,
99 x3 = c.x, y3 = c.y, r3 = c.r,
100 a2 = x1 - x2,
101 a3 = x1 - x3,
102 b2 = y1 - y2,
103 b3 = y1 - y3,
104 c2 = r2 - r1,
105 c3 = r3 - r1,
106 d1 = x1 * x1 + y1 * y1 - r1 * r1,
107 d2 = d1 - x2 * x2 - y2 * y2 + r2 * r2,
108 d3 = d1 - x3 * x3 - y3 * y3 + r3 * r3,
109 ab = a3 * b2 - a2 * b3,
110 xa = (b2 * d3 - b3 * d2) / (ab * 2) - x1,
111 xb = (b3 * c2 - b2 * c3) / ab,
112 ya = (a3 * d2 - a2 * d3) / (ab * 2) - y1,
113 yb = (a2 * c3 - a3 * c2) / ab,
114 A = xb * xb + yb * yb - 1,
115 B = 2 * (r1 + xa * xb + ya * yb),
116 C = xa * xa + ya * ya - r1 * r1,
117 r = -(Math.abs(A) > 1e-6 ? (B + Math.sqrt(B * B - 4 * A * C)) / (2 * A) : C / B);
118 return {
119 x: x1 + xa + xb * r,
120 y: y1 + ya + yb * r,
121 r: r
122 };
123}
Note: See TracBrowser for help on using the repository browser.