mirror of
https://kevinblog.sytes.net/Code/Jibo-Revival-Group/RoboCommander.git
synced 2026-06-16 08:36:04 +00:00
Initial commit
This commit is contained in:
115
node_modules/d3-hierarchy/src/pack/siblings.js
generated
vendored
Normal file
115
node_modules/d3-hierarchy/src/pack/siblings.js
generated
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
import enclose from "./enclose";
|
||||
|
||||
function place(a, b, c) {
|
||||
var ax = a.x,
|
||||
ay = a.y,
|
||||
da = b.r + c.r,
|
||||
db = a.r + c.r,
|
||||
dx = b.x - ax,
|
||||
dy = b.y - ay,
|
||||
dc = dx * dx + dy * dy;
|
||||
if (dc) {
|
||||
var x = 0.5 + ((db *= db) - (da *= da)) / (2 * dc),
|
||||
y = Math.sqrt(Math.max(0, 2 * da * (db + dc) - (db -= dc) * db - da * da)) / (2 * dc);
|
||||
c.x = ax + x * dx + y * dy;
|
||||
c.y = ay + x * dy - y * dx;
|
||||
} else {
|
||||
c.x = ax + db;
|
||||
c.y = ay;
|
||||
}
|
||||
}
|
||||
|
||||
function intersects(a, b) {
|
||||
var dx = b.x - a.x,
|
||||
dy = b.y - a.y,
|
||||
dr = a.r + b.r;
|
||||
return dr * dr - 1e-6 > dx * dx + dy * dy;
|
||||
}
|
||||
|
||||
function score(node) {
|
||||
var a = node._,
|
||||
b = node.next._,
|
||||
ab = a.r + b.r,
|
||||
dx = (a.x * b.r + b.x * a.r) / ab,
|
||||
dy = (a.y * b.r + b.y * a.r) / ab;
|
||||
return dx * dx + dy * dy;
|
||||
}
|
||||
|
||||
function Node(circle) {
|
||||
this._ = circle;
|
||||
this.next = null;
|
||||
this.previous = null;
|
||||
}
|
||||
|
||||
export function packEnclose(circles) {
|
||||
if (!(n = circles.length)) return 0;
|
||||
|
||||
var a, b, c, n, aa, ca, i, j, k, sj, sk;
|
||||
|
||||
// Place the first circle.
|
||||
a = circles[0], a.x = 0, a.y = 0;
|
||||
if (!(n > 1)) return a.r;
|
||||
|
||||
// Place the second circle.
|
||||
b = circles[1], a.x = -b.r, b.x = a.r, b.y = 0;
|
||||
if (!(n > 2)) return a.r + b.r;
|
||||
|
||||
// Place the third circle.
|
||||
place(b, a, c = circles[2]);
|
||||
|
||||
// Initialize the front-chain using the first three circles a, b and c.
|
||||
a = new Node(a), b = new Node(b), c = new Node(c);
|
||||
a.next = c.previous = b;
|
||||
b.next = a.previous = c;
|
||||
c.next = b.previous = a;
|
||||
|
||||
// Attempt to place each remaining circle…
|
||||
pack: for (i = 3; i < n; ++i) {
|
||||
place(a._, b._, c = circles[i]), c = new Node(c);
|
||||
|
||||
// Find the closest intersecting circle on the front-chain, if any.
|
||||
// “Closeness” is determined by linear distance along the front-chain.
|
||||
// “Ahead” or “behind” is likewise determined by linear distance.
|
||||
j = b.next, k = a.previous, sj = b._.r, sk = a._.r;
|
||||
do {
|
||||
if (sj <= sk) {
|
||||
if (intersects(j._, c._)) {
|
||||
b = j, a.next = b, b.previous = a, --i;
|
||||
continue pack;
|
||||
}
|
||||
sj += j._.r, j = j.next;
|
||||
} else {
|
||||
if (intersects(k._, c._)) {
|
||||
a = k, a.next = b, b.previous = a, --i;
|
||||
continue pack;
|
||||
}
|
||||
sk += k._.r, k = k.previous;
|
||||
}
|
||||
} while (j !== k.next);
|
||||
|
||||
// Success! Insert the new circle c between a and b.
|
||||
c.previous = a, c.next = b, a.next = b.previous = b = c;
|
||||
|
||||
// Compute the new closest circle pair to the centroid.
|
||||
aa = score(a);
|
||||
while ((c = c.next) !== b) {
|
||||
if ((ca = score(c)) < aa) {
|
||||
a = c, aa = ca;
|
||||
}
|
||||
}
|
||||
b = a.next;
|
||||
}
|
||||
|
||||
// Compute the enclosing circle of the front chain.
|
||||
a = [b._], c = b; while ((c = c.next) !== b) a.push(c._); c = enclose(a);
|
||||
|
||||
// Translate the circles to put the enclosing circle around the origin.
|
||||
for (i = 0; i < n; ++i) a = circles[i], a.x -= c.x, a.y -= c.y;
|
||||
|
||||
return c.r;
|
||||
}
|
||||
|
||||
export default function(circles) {
|
||||
packEnclose(circles);
|
||||
return circles;
|
||||
}
|
||||
Reference in New Issue
Block a user